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

Stewart Smith stewart at flamingspork.com
Mon Feb 15 17:58:56 PST 2010


New patch that does it. Pretty much same as the old one, just with
that one bug I mentioned fixed. This is what I've currently used to
import my Maildir. I'm now happy :)

diff --git a/notmuch-new.c b/notmuch-new.c
index f25c71f..43371a3 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, "flagged");
+		break;
+	    case 'R': /* replied */
+		notmuch_message_add_tag (message, "answered");
+		break;
+	    case 'D':
+		notmuch_message_add_tag (message, "draft");
+		break;
+	    case 'S': /* seen */
+		seen = TRUE;
+		break;
+	    case 'T': /* trashed */
+		notmuch_message_add_tag (message, "deleted");
+		break;
+	    case 'P': /* passed */
+		notmuch_message_add_tag (message, "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


More information about the notmuch mailing list