[notmuch] [PATCH] notmuch: Respect maildir message flags

Stewart Smith stewart at flamingspork.com
Mon Feb 15 18:21:28 PST 2010


On Tue, Feb 16, 2010 at 03:12:50PM +1300, martin f krafft wrote:
> also sprach Stewart Smith <stewart at flamingspork.com> [2010.02.16.1458 +1300]:
> > +	    case 'R': /* replied */
> > +		notmuch_message_add_tag (message, "answered");
> > +		break;
> 
> 'r' means replied, not 'answered'.

fixed.

(i have to admit... i didn't look too closely at this... it just
worked enough for me)

> 
> > +	    case 'T': /* trashed */
> > +		notmuch_message_add_tag (message, "deleted");
> > +		break;
> 
> Same. trashed and deleted are not the same thing.

changed to 'trashed'.

> I don't want to get into an argument over this, because I think this
> already exposes a problem: you are putting into global namespace
> something not everyone might want, or agree with.
> 
> Why not use 'maildirflags::replied' instead? People can always map
> that to something in the global namespace.

What about putting them all in there except for the seen tag, with the
seen tag dictating if it gets marked 'unread' or not? I cannot imagine
where somebody would want this not to be the case... it was bad enough
discovering 100,000 unread messages :)

What about this patch (just with those few things fixed)?

diff --git a/notmuch-new.c b/notmuch-new.c
index f25c71f..8303047 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -39,6 +39,7 @@ typedef struct {
     int total_files;
     int processed_files;
     int added_messages;
+    int 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)
@@ -222,6 +277,7 @@ add_files_recursive (notmuch_database_t *notmuch,
     notmuch_filenames_t *db_subdirs = NULL;
     struct stat st;
     notmuch_bool_t is_maildir, new_directory;
+    int maildir_detected = -1;
 
     if (stat (path, &st)) {
 	fprintf (stderr, "Error reading directory %s: %s\n",
@@ -301,6 +357,28 @@ add_files_recursive (notmuch_database_t *notmuch,
 	    continue;
 	}
 
+	/* If this directory is a Maildir folder, we need to
+	 * ignore any subdirectories marked tmp/, and scan for
+	 * Maildir attributes on messages contained in the sub-
+	 * directories 'new' and 'cur'. */
+	if (maildir_detected != 0 &&
+	    (entry->d_type == DT_DIR || entry->d_type == DT_UNKNOWN) &&
+	    ((strcmp (entry->d_name, "tmp") == 0) ||
+	     (strcmp (entry->d_name, "new") == 0) ||
+	     (strcmp (entry->d_name, "cur") == 0))) {
+
+    if (maildir_detected == -1) {
+      maildir_detected = _entries_resemble_maildir(fs_entries, num_fs_entries);
+    }
+    if (maildir_detected == 1) {
+      if (strcmp (entry->d_name, "tmp") == 0) {
+        continue;
+      } else {
+        state->tag_maildir = TRUE;
+      }
+    }
+  }
+
 	next = talloc_asprintf (notmuch, "%s/%s", path, entry->d_name);
 	status = add_files_recursive (notmuch, next, state);
 	if (status && ret == NOTMUCH_STATUS_SUCCESS)
@@ -412,7 +490,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:

-- 
Stewart Smith
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: Digital signature
URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20100216/5323bb1c/attachment.pgp>


More information about the notmuch mailing list