Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id 8C865431FBD for ; Sun, 6 Dec 2009 11:55:25 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Jq4++xPeRDab for ; Sun, 6 Dec 2009 11:55:24 -0800 (PST) Received: from aegir.org.uk (aegir.org.uk [87.238.170.13]) by olra.theworths.org (Postfix) with ESMTP id 29638431FBC for ; Sun, 6 Dec 2009 11:55:24 -0800 (PST) Received: from localhost (109-9-ftth.onsnetstudenten.nl [145.120.9.109]) (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by aegir.org.uk (Postfix) with ESMTPSA id ED35A2E01B; Sun, 6 Dec 2009 20:55:22 +0100 (CET) From: Michiel Buddingh' To: Carl Worth , notmuch@notmuchmail.org In-Reply-To: <87ws1bjpmm.fsf@yoom.home.cworth.org> References: <87fx8bygi7.fsf@linux.vnet.ibm.com> <87bpiv4t9h.fsf@yoom.home.cworth.org> <87y6lz39nd.fsf@yoom.home.cworth.org> <20091121221207.GB17268@jukie.net> <9cce5525b093b87fe74d427954ffad89@localhost> <87d43b2oif.fsf@yoom.home.cworth.org> <9bfdedddeab9c58cd45d8d448323d0fc@localhost> <87skc23327.fsf@yoom.home.cworth.org> <4b0eef22.JwxdgTGElffx149F%michiel@michielbuddingh.net> <87ws1bjpmm.fsf@yoom.home.cworth.org> Date: Sun, 06 Dec 2009 20:55:22 +0100 Message-ID: <878wdfkhcl.fsf@aegir.org.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Subject: Re: [notmuch] [PATCH] notmuch: Add Maildir directory name as tag name for messages X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 06 Dec 2009 19:55:25 -0000 First of all, apologies for taking so long to get back to this. On Fri, 27 Nov 2009, Carl Worth wrote: > The auto-detection is just three additional stats (at most) for each > directory, right? That seems cheap enough to me. If that's cheap enough, then I won't disagree with auto-detection. Jan Janak's patch seems to take most of the disk access cost out of it, in any case. > That seems orthogonal to me. Would the dovecot index files be easy to > skip with a pattern-based blacklist? Yes, and that's a much more elegant solution. > > I'll be happy to implement them, although I'd like for others to > > chime in on the configure-as-Maildir vs. autodetect-Maildir issue. > > And thanks for your patience in working through my patch. I didn't mean to call a vote--rather to solicit the opinions of others with possibly even more exotic mail storage configurations. A new patch is attached. Apologies for the rather verbose Maildir handling logic, but I couldn't find a way to minimize the calls to is_maildir that was both neat and readable. -- Michiel --- notmuch-client.h | 1 + notmuch-new.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 90 insertions(+), 4 deletions(-) diff --git a/notmuch-client.h b/notmuch-client.h index 50a30fe..7bc84a1 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -77,6 +77,7 @@ typedef struct { int saw_read_only_directory; int output_is_a_tty; int verbose; + int tag_maildir; int total_files; int processed_files; diff --git a/notmuch-new.c b/notmuch-new.c index 9d20616..8742ab4 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -109,6 +109,60 @@ is_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' (path_mtime) @@ -142,6 +196,7 @@ add_files_recursive (notmuch_database_t *notmuch, notmuch_status_t status, ret = NOTMUCH_STATUS_SUCCESS; notmuch_message_t *message = NULL; struct dirent **namelist = NULL; + int maildir_detected = -1; /* -1 = unset */ int num_entries; /* If we're told to, we bail out on encountering a read-only @@ -189,13 +244,37 @@ add_files_recursive (notmuch_database_t *notmuch, if (strcmp (entry->d_name, ".") == 0 || strcmp (entry->d_name, "..") == 0 || (entry->d_type == DT_DIR && - (strcmp (entry->d_name, "tmp") == 0) && - is_maildir (namelist, num_entries)) || - strcmp (entry->d_name, ".notmuch") ==0) + strcmp (entry->d_name, ".notmuch") == 0)) { 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 && + ((strcmp (entry->d_name, "tmp") == 0) || + (strcmp (entry->d_name, "new") == 0) || + (strcmp (entry->d_name, "cur") == 0))) { + + /* is_maildir scans the entire directory. No need to + do this more than once, if at all */ + if (maildir_detected == -1) { + maildir_detected = is_maildir (namelist, num_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); if (stat (next, st)) { @@ -240,7 +319,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: @@ -282,6 +366,7 @@ add_files_recursive (notmuch_database_t *notmuch, status = add_files_recursive (notmuch, next, st, state); if (status && ret == NOTMUCH_STATUS_SUCCESS) ret = status; + state->tag_maildir = FALSE; } talloc_free (next); -- 1.6.5.4