Patchworkβ notmuch-new: Respect maildir flags when importing a new message

login
register
about
Submitter Sebastian Spaeth
Date 2010-03-01 13:28:56
Message ID <1267450136-31749-1-git-send-email-Sebastian@SSpaeth.de>
Download mbox | patch
Permalink /patch/399/
State New
Headers show

Comments

Sebastian Spaeth - 2010-03-01 13:28:56
When importing a new mail do check for maildir tags and assign corresponding notmuch tags.

Based on a patch by Michiel Buddingh <michiel@michielbuddingh.net> and subsequently modified by Tim Stoakes, Stewart Smith, and Sebastian Spaeth (see mail thread around mail id:20100210031339.GH16686@mail.rocksoft.com)

Do note that this will only add tags when importing a really new message, and will not do anything when detecting a file rename (although someone should really make it honor file renames as well). Deleteing an existing message in another IMAP client will therefore not trigger tagging (as it counts as a file rename).

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
---
I cleaned up the patch by Stewart Smith a bit more, but it's basically his last version of the patch. The biggest caveat is really that file renames won't cause any change. So this approach is really only part of the solution to sync with e.g. thunderbird usage.
 notmuch-new.c |   64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 63 insertions(+), 1 deletions(-)
Carl Worth - 2010-04-07 21:16:34
On Mon,  1 Mar 2010 14:28:56 +0100, Sebastian Spaeth <Sebastian@SSpaeth.de> wrote:
> When importing a new mail do check for maildir tags and assign
> corresponding notmuch tags.

I think this is a useful thing to support, as obviously new users have
*some* state that's interesting to import (which messages have been
"seen" for example), and simply importing their entire email archive
with both the "inbox" and "unread" tags is not helpful. So I'd like to
figure out how to support this.

> Do note that this will only add tags when importing a really new
> message, and will not do anything when detecting a file rename
> (although someone should really make it honor file renames as
> well). Deleteing an existing message in another IMAP client will
> therefore not trigger tagging (as it counts as a file rename).

But I think we really need to fix that if we're going to claim that
notmuch "supports maildir flags" in any sense.

It's a fairly tricky issue though since we can have multiple files that
have the same message ID, but then have different maildir flags. And
it's the matter of arbitrary ordering which one of these files appears
as "new" and which one appears as a "rename".

It's not obvious to me what we can do here unless we make some
assumptions, (such as "mails always start without the seen flag, and
once it appears it can't be removed" or so). But I'd love some input
From someone who's thought harder about this than I have.

-Carl
Michal Sojka - 2010-04-08 12:57:31
On Wed, 07 Apr 2010, Carl Worth wrote:
> On Mon,  1 Mar 2010 14:28:56 +0100, Sebastian Spaeth <Sebastian@SSpaeth.de> wrote:
> > When importing a new mail do check for maildir tags and assign
> > corresponding notmuch tags.
> 
> I think this is a useful thing to support, as obviously new users have
> *some* state that's interesting to import (which messages have been
> "seen" for example), and simply importing their entire email archive
> with both the "inbox" and "unread" tags is not helpful. So I'd like to
> figure out how to support this.

I'm solving this in my mailstore abstraction patches. I'll send the next
version in a while.

> > Do note that this will only add tags when importing a really new
> > message, and will not do anything when detecting a file rename
> > (although someone should really make it honor file renames as
> > well). Deleteing an existing message in another IMAP client will
> > therefore not trigger tagging (as it counts as a file rename).
> 
> But I think we really need to fix that if we're going to claim that
> notmuch "supports maildir flags" in any sense.
> 
> It's a fairly tricky issue though since we can have multiple files that
> have the same message ID, but then have different maildir flags. And
> it's the matter of arbitrary ordering which one of these files appears
> as "new" and which one appears as a "rename".

Yes, that's a problem. It is not currently solved in my pacthes, but I
have one solution in my mind. Let's discuss this with my patch.

> It's not obvious to me what we can do here unless we make some
> assumptions, (such as "mails always start without the seen flag, and
> once it appears it can't be removed" or so). But I'd love some input
> From someone who's thought harder about this than I have.

-Michal

Patch

diff --git a/notmuch-new.c b/notmuch-new.c
index f25c71f..5a75950 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -39,6 +39,7 @@  typedef struct {
     int total_files;
     int processed_files;
     int added_messages;
+    notmuch_bool_t tag_maildir;
     struct timeval tv_start;
 
     _filename_list_t *removed_files;
@@ -169,6 +170,60 @@  _entries_resemble_maildir (struct dirent **entries, int count)
     return 0;
 }
 
+/* Tag new mail according to its Maildir attribute flags.
+ *
+ * Test if the mail file's filename contains any of the
+ * standard Maildir attributes, and translate these to
+ * the corresponding standard notmuch tags.
+ *
+ * If the message is not marked as 'seen', or if no
+ * flags are present, tag as 'inbox, unread'.
+ */
+static void
+derive_tags_from_maildir_flags (notmuch_message_t *message,
+                           const char * path)
+{
+    int seen = FALSE;
+    int end_of_flags = FALSE;
+    size_t l = strlen(path);
+
+    /* Non-experimental message flags start with this */
+    char * i = strstr(path, ":2,");
+    i = (i) ? i : strstr(path, "!2,"); /* This format is used on VFAT */
+    if (i != NULL) {
+   i += 3;
+   for (; i < (path + l) && !end_of_flags; i++) {
+       switch (*i) {
+       case 'F' :
+           notmuch_message_add_tag (message, "maildir::flagged");
+           break;
+       case 'R': /* replied */
+           notmuch_message_add_tag (message, "maildir::replied");
+           break;
+       case 'D':
+           notmuch_message_add_tag (message, "maildir::draft");
+           break;
+       case 'S': /* seen */
+           seen = TRUE;
+           break;
+       case 'T': /* trashed */
+           notmuch_message_add_tag (message, "maildir::trashed");
+           break;
+       case 'P': /* passed */
+           notmuch_message_add_tag (message, "maildir::forwarded");
+           break;
+       default:
+           end_of_flags = TRUE;
+           break;
+       }
+   }
+    }
+
+    if (i == NULL || !seen) {
+   tag_inbox_and_unread (message);
+    }
+}
+
 /* Examine 'path' recursively as follows:
  *
  *   o Ask the filesystem for the mtime of 'path' (fs_mtime)
@@ -299,6 +354,8 @@  add_files_recursive (notmuch_database_t *notmuch,
 	    strcmp (entry->d_name, ".notmuch") ==0)
 	{
 	    continue;
+	} else {
+	    state->tag_maildir = TRUE;
 	}
 
 	next = talloc_asprintf (notmuch, "%s/%s", path, entry->d_name);
@@ -412,7 +469,12 @@  add_files_recursive (notmuch_database_t *notmuch,
 	/* success */
 	case NOTMUCH_STATUS_SUCCESS:
 	    state->added_messages++;
-	    tag_inbox_and_unread (message);
+	    if (state->tag_maildir) {
+	      derive_tags_from_maildir_flags (message,
+					      entry->d_name);
+	    } else {
+	        tag_inbox_and_unread (message);
+	    }
 	    break;
 	/* Non-fatal issues (go on to next file) */
 	case NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID: