[PATCH/RFC 2/3] notmuch new: tag messages based on maildir custom flags

Igor Almeida igor.contato at gmail.com
Wed Nov 25 18:16:30 PST 2015


Iterate through the flags in the message's filename, creating tags and
tagging the message as they appear.
This uses Bremner/Dovecot's convention of maildir_keyword_xxx, where xxx a char
between 'a' and 'z'.

Since more than one file may point to the same message in the database
(think renames), the tags related to maildir custom flags are always
removed and later re-added to maintain consistency.

Signed-off-by: Igor Almeida <igor.contato at gmail.com>
---
 lib/message.cc | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 88 insertions(+)

diff --git a/lib/message.cc b/lib/message.cc
index 26b5e76..8a89dee 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -1301,6 +1301,13 @@ notmuch_message_maildir_flags_to_tags (notmuch_message_t *message)
     unsigned i;
     int seen_maildir_info = 0;
 
+    /* For custom maildir flags */
+    char *c; /* to iterate over combined_flags */
+    const char *custom_flag_dbase_name;
+    int index;
+    notmuch_bool_t cancel_custom_flags = FALSE;
+    notmuch_bool_t must_free = FALSE;
+
     for (filenames = notmuch_message_get_filenames (message);
 	 notmuch_filenames_valid (filenames);
 	 notmuch_filenames_move_to_next (filenames))
@@ -1349,6 +1356,87 @@ notmuch_message_maildir_flags_to_tags (notmuch_message_t *message)
 	if (status)
 	    return status;
     }
+
+    /* Now let's find custom maildir flags */
+
+    status = notmuch_message_freeze (message);
+    if (status)
+	goto finish;
+
+    cancel_custom_flags = FALSE;
+
+    /* First we remove the tags for custom maildir flags, then
+     * we add only the ones in combined_flags
+     */
+    char letter;
+    for (letter = 'a'; letter <= 'z'; letter++) {
+	index = letter - 'a';
+	status = notmuch_database_get_maildir_keyword (
+	    message->notmuch, index, &custom_flag_dbase_name);
+	if (status) {
+	    /* TODO probably OOM, what now? */
+	}
+
+	if (custom_flag_dbase_name == NULL) {
+	    /* We don't have a custom flag for this letter, try the next
+	     * one now
+	     */
+	    continue;
+	}
+
+	status = notmuch_message_remove_tag (message, custom_flag_dbase_name);
+	if (status) {
+	    /* TODO tag too long? */
+	}
+    }
+
+    /* Go through combined_flags and tag the message accordingly */
+
+    for (c = combined_flags; *c; c++) {
+	if (*c >= 'a' && *c <= 'z') {
+	    index = *c - 'a';
+
+	    status = notmuch_database_get_maildir_keyword(
+		message->notmuch, index, &custom_flag_dbase_name);
+	    if (status) {
+		cancel_custom_flags = TRUE;
+		break;
+	    } else {
+		if (custom_flag_dbase_name == NULL) {
+		    /* Custom flag does not yet exist */
+		    custom_flag_dbase_name = talloc_asprintf (message,
+			"maildir_keyword_%c", 'a' + index);
+		    /* Add to the database */
+		    notmuch_database_set_maildir_keyword (
+			message->notmuch, index, custom_flag_dbase_name);
+
+		    must_free = TRUE;
+		}
+
+		/* Tag the message */
+		status = notmuch_message_add_tag (message,
+		    custom_flag_dbase_name);
+
+		if (must_free) {
+		    talloc_free((void*)custom_flag_dbase_name);
+		    must_free = FALSE;
+		}
+
+		if (status) {
+		    cancel_custom_flags = TRUE;
+		    break;
+		}
+	    }
+	}
+    }
+
+    if (cancel_custom_flags) {
+	/* TODO rollback the add_tag's */
+    }
+
+    status = notmuch_message_thaw (message);
+
+finish:
     status = notmuch_message_thaw (message);
 
     talloc_free (combined_flags);
-- 
2.5.3



More information about the notmuch mailing list