summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2016-03-25 20:33:33 +0200
committerLars Wirzenius <liw@liw.fi>2016-03-25 20:33:33 +0200
commit99aa0893ad5cb5f798f889a09f6f6521a4432ba1 (patch)
tree5aee82b400aea95d4a4df4f86aefdf984de06442
parent36656efe16604153743d4140570498fffa3bcc45 (diff)
downloaddistix-99aa0893ad5cb5f798f889a09f6f6521a4432ba1.tar.gz
Set key/value pair on tickets when importing mail
-rw-r--r--NEWS3
-rw-r--r--distixlib/plugins/import_mail_plugin.py54
-rw-r--r--yarns/080-import-mail.yarn23
-rw-r--r--yarns/900-implements.yarn15
4 files changed, 83 insertions, 12 deletions
diff --git a/NEWS b/NEWS
index d6825bc..70cdae8 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,9 @@ Version 0.5+git, not yet released
duplicate imported mails whenever there's another mail that's
belongs in an existing ticket.
+* Importing mails can now set a key/value pair on any new or modified
+ tickets. This can be used, for example, to unset a closed status.
+
Version 0.5, released 2016-03-08
---------------------------------
diff --git a/distixlib/plugins/import_mail_plugin.py b/distixlib/plugins/import_mail_plugin.py
index 8f3e311..080e663 100644
--- a/distixlib/plugins/import_mail_plugin.py
+++ b/distixlib/plugins/import_mail_plugin.py
@@ -29,7 +29,12 @@ import distixlib
class WrongArguments(distixlib.StructuredError):
- msg = 'Wrong number of arguments: got {count}, wanted 2'
+ msg = 'Wrong number of arguments: got {count}, wanted 2 or 3'
+
+
+class NotKeywordArgument(distixlib.StructuredError):
+
+ msg = '{arg} is not a keyword argumnent (KEY=VALUE)'
class ImportMailPlugin(cliapp.Plugin):
@@ -38,16 +43,20 @@ class ImportMailPlugin(cliapp.Plugin):
def enable(self):
self.app.add_subcommand(
- 'import-mail', self.import_mail, arg_synopsis='REPO FILE')
+ 'import-mail', self.import_mail,
+ arg_synopsis='REPO FILE [KEY=VALUE]')
self.app.add_subcommand(
- 'import-mbox', self.import_mbox, arg_synopsis='REPO FILE')
+ 'import-mbox', self.import_mbox,
+ arg_synopsis='REPO FILE [KEY=VALUE]')
self.app.add_subcommand(
- 'import-maildir', self.import_maildir, arg_synopsis='REPO MAILDIR')
+ 'import-maildir', self.import_maildir,
+ arg_synopsis='REPO MAILDIR')
def import_mail(self, args):
- repo_dirname, mail_filename = self._parse_command_line(args)
+ repo_dirname, mail_filename, keyvalue = self._parse_command_line(args)
+ key, value = self._parse_keyvalue(keyvalue)
msg = self._read_mail_message(mail_filename)
repo = distixlib.Repository(repo_dirname)
repo.require_clean_working_tree()
@@ -55,21 +64,31 @@ class ImportMailPlugin(cliapp.Plugin):
all_tickets = ticket_store.get_tickets()
cache = _MessageIdCache()
filenames = self._import_msg_to_ticket_store(
- repo, ticket_store, all_tickets, msg, cache)
+ repo, ticket_store, all_tickets, msg, cache, key, value)
if filenames:
repo.commit_changes(filenames, self.commit_msg)
def _parse_command_line(self, args):
- if len(args) != 2:
+ if len(args) == 2:
+ return args[0], args[1], None
+ elif len(args) == 3:
+ if '=' not in args[2]:
+ raise NotKeywordArgument(arg=args[2])
+ return args[0], args[1], args[2]
+ else:
raise WrongArguments(count=len(args))
- return args
+
+ def _parse_keyvalue(self, keyvalue):
+ if keyvalue is None:
+ return None, None
+ return keyvalue.split('=', 1)
def _read_mail_message(self, mail_filename):
with open(mail_filename) as f:
return email.message_from_file(f)
def _import_msg_to_ticket_store(
- self, repo, ticket_store, all_tickets, msg, cache):
+ self, repo, ticket_store, all_tickets, msg, cache, key, value):
referenced_tickets = self._find_tickets_with_mails_referenced_by_msg(
all_tickets, msg, cache)
@@ -80,12 +99,13 @@ class ImportMailPlugin(cliapp.Plugin):
for ticket in referenced_tickets:
if not self._contains_message(ticket, msg):
ticket.add_message(msg)
+ self._set_key_value(ticket, key, value)
cache.add_msg_ids_for_ticket_id(
ticket.get_ticket_id(), msg_ids)
else:
if not self._is_already_imported(msg, all_tickets):
- print 'new ticket'
new_ticket = self._create_ticket_from_msg(repo, msg)
+ self._set_key_value(new_ticket, key, value)
cache.add_msg_ids_for_ticket_id(
new_ticket.get_ticket_id(), msg_ids)
all_tickets.append(new_ticket)
@@ -94,6 +114,14 @@ class ImportMailPlugin(cliapp.Plugin):
filenames += ticket_store.save_changes()
return filenames
+ def _set_key_value(self, ticket, key, value):
+ if key is not None and value is not None:
+ metadata = ticket.get_ticket_metadata()
+ if key in metadata:
+ metadata.remove_all_values(key)
+ metadata.add(key, value)
+ ticket.set_ticket_metadata(metadata)
+
def _contains_message(self, ticket, msg):
return any(
self._equal_messages(existing, msg)
@@ -174,7 +202,9 @@ class ImportMailPlugin(cliapp.Plugin):
self._import_folder(args, maildir_factory)
def _import_folder(self, args, folder_factory):
- repo_dirname, folder_filename = self._parse_command_line(args)
+ repo_dirname, folder_filename, keyvalue = self._parse_command_line(
+ args)
+ key, value = self._parse_keyvalue(keyvalue)
folder = folder_factory(folder_filename)
repo = distixlib.Repository(repo_dirname)
repo.require_clean_working_tree()
@@ -190,7 +220,7 @@ class ImportMailPlugin(cliapp.Plugin):
for msg in folder:
progress.next_msg()
filenames += self._import_msg_to_ticket_store(
- repo, ticket_store, all_tickets, msg, cache)
+ repo, ticket_store, all_tickets, msg, cache, key, value)
filenames += ticket_store.save_changes()
if filenames:
repo.commit_changes(filenames, self.commit_msg)
diff --git a/yarns/080-import-mail.yarn b/yarns/080-import-mail.yarn
index 7d7a1b8..ada7182 100644
--- a/yarns/080-import-mail.yarn
+++ b/yarns/080-import-mail.yarn
@@ -125,3 +125,26 @@ Ditto, but for mailboxes.
THEN attempt succeeded
AND output matches "^[0-9a-f]{32} .* bar$"
AND output doesn't match "^[0-9a-f]{32} .* blerf$"
+
+When users send new mails to tickets that are already closed, the
+"status" key needs to get updated. In other words, a ticket that has
+the metadata "status=closed" should lose that.
+
+ SCENARIO ticket gets re-opened upon importing new mail
+
+ WHEN user attempts to run distix init REPO
+ THEN attempt succeeded
+
+ GIVEN file MBOX1 containing "From foo@example.com Mon Mar 19 09:46:32 2012\nFrom: foo@example.com\nSubject: bar\nMessage-Id: one@example.com\n\nyo\n"
+ WHEN user attempts to run distix import-mbox REPO MBOX1
+ THEN attempt succeeded
+
+ GIVEN file MBOX2 containing "From foo@example.com Mon Mar 19 09:46:32 2012\nFrom: foo2@example.com\nSubject: blerf\nMessage-Id: <two@example.com>\nReferences: <one@example.com>\n\nyo\n"
+ WHEN user sets all tickets in REPO to status=closed
+ AND user attempts to run distix import-mbox REPO MBOX2 status=
+ THEN attempt succeeded
+
+ WHEN user changes working directory to REPO
+ AND user attempts to run distix list status!=closed
+ THEN attempt succeeded
+ AND output matches "."
diff --git a/yarns/900-implements.yarn b/yarns/900-implements.yarn
index d5ca4bf..cbf8ea4 100644
--- a/yarns/900-implements.yarn
+++ b/yarns/900-implements.yarn
@@ -42,6 +42,21 @@ be, and changing there when running various commands.
echo "$?" > "$DATADIR/attempt.exit"
fi
+ IMPLEMENTS WHEN user sets all tickets in (\S+) to (\S+)
+ cd "$DATADIR/$MATCH_1"
+
+ "$SRCDIR/distix" --no-default-config --quiet \
+ --log "$DATADIR/distix.log" list |
+ awk '{ print $1 }' > "$DATADIR/tickets.list"
+
+ cat "$DATADIR/tickets.list" |
+ while read ticket
+ do
+ "$SRCDIR/distix" --no-default-config --quiet \
+ --log "$DATADIR/distix.log" \
+ set "$ticket" "$MATCH_2"
+ done
+
We also need steps for inspecting the results of attempting to run
distix.