Re: [PATCH] notmuch: Add "maildir:" search option
authorAustin Clements <aclements@csail.mit.edu>
Tue, 12 Nov 2013 19:31:25 +0000 (14:31 +1900)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:58:12 +0000 (09:58 -0800)
f1/ede4bafcaf7b27284cfcf8bb3f5e8de6aed2cd [new file with mode: 0644]

diff --git a/f1/ede4bafcaf7b27284cfcf8bb3f5e8de6aed2cd b/f1/ede4bafcaf7b27284cfcf8bb3f5e8de6aed2cd
new file mode 100644 (file)
index 0000000..ba06c98
--- /dev/null
@@ -0,0 +1,294 @@
+Return-Path: <amdragon@mit.edu>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+       by olra.theworths.org (Postfix) with ESMTP id 11380431FD7\r
+       for <notmuch@notmuchmail.org>; Tue, 12 Nov 2013 11:31:42 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.7\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5\r
+       tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+       by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+       with ESMTP id jWYG7YjnaAk7 for <notmuch@notmuchmail.org>;\r
+       Tue, 12 Nov 2013 11:31:32 -0800 (PST)\r
+Received: from dmz-mailsec-scanner-1.mit.edu (dmz-mailsec-scanner-1.mit.edu\r
+       [18.9.25.12])\r
+       (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))\r
+       (No client certificate requested)\r
+       by olra.theworths.org (Postfix) with ESMTPS id BFAFE431FD2\r
+       for <notmuch@notmuchmail.org>; Tue, 12 Nov 2013 11:31:31 -0800 (PST)\r
+X-AuditID: 1209190c-b7f7f6d000000bbd-d5-5282821241d3\r
+Received: from mailhub-auth-4.mit.edu ( [18.7.62.39])\r
+       (using TLS with cipher AES256-SHA (256/256 bits))\r
+       (Client did not present a certificate)\r
+       by dmz-mailsec-scanner-1.mit.edu (Symantec Messaging Gateway) with SMTP\r
+       id 6A.27.03005.21282825; Tue, 12 Nov 2013 14:31:30 -0500 (EST)\r
+Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11])\r
+       by mailhub-auth-4.mit.edu (8.13.8/8.9.2) with ESMTP id rACJVS2o009792; \r
+       Tue, 12 Nov 2013 14:31:29 -0500\r
+Received: from awakening.csail.mit.edu (awakening.csail.mit.edu [18.26.4.91])\r
+       (authenticated bits=0)\r
+       (User authenticated as amdragon@ATHENA.MIT.EDU)\r
+       by outgoing.mit.edu (8.13.8/8.12.4) with ESMTP id rACJVP2a000312\r
+       (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NOT);\r
+       Tue, 12 Nov 2013 14:31:27 -0500\r
+Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.80)\r
+       (envelope-from <amdragon@mit.edu>)\r
+       id 1VgJgL-0005wV-Ap; Tue, 12 Nov 2013 14:31:25 -0500\r
+From: Austin Clements <aclements@csail.mit.edu>\r
+To: Peter Zijlstra <peterz@infradead.org>, notmuch@notmuchmail.org\r
+Subject: Re: [PATCH] notmuch: Add "maildir:" search option\r
+In-Reply-To: <20131112155637.GA16796@laptop.programming.kicks-ass.net>\r
+References: <20131112155637.GA16796@laptop.programming.kicks-ass.net>\r
+User-Agent: Notmuch/0.16+154~g96c0ce2 (http://notmuchmail.org) Emacs/23.4.1\r
+       (i486-pc-linux-gnu)\r
+Date: Tue, 12 Nov 2013 14:31:25 -0500\r
+Message-ID: <87mwl94dte.fsf@awakening.csail.mit.edu>\r
+MIME-Version: 1.0\r
+Content-Type: text/plain; charset=us-ascii\r
+X-Brightmail-Tracker:\r
+ H4sIAAAAAAAAA+NgFrrPIsWRmVeSWpSXmKPExsUixG6nrivU1BRksPWmhcX1mzOZLY73HmBy\r
+       YPLYvELL49mqW8wBTFFcNimpOZllqUX6dglcGXv7P7MXbLCo2DZnAVMD43vtLkZODgkBE4m2\r
+       l1dZIWwxiQv31rN1MXJxCAnMZpJoWdfPBOFsZJT48eovI4RzmkmiZ9kMJpAWIYEljBItF3xB\r
+       bDYBfYkVayeBjRIRcJK4+2kqkM3BISxgJbF/VxJImFPATeLLsZPsEK2uEtuX3mcBsUUF4iWm\r
+       LdzJDGKzCKhKHH3RCzaeF+i6vSdPs0HYghInZz4Bq2cW0JK48e8l0wRGgVlIUrOQpBYwMq1i\r
+       lE3JrdLNTczMKU5N1i1OTszLSy3SNdTLzSzRS00p3cQICkdOSZ4djG8OKh1iFOBgVOLhfRDZ\r
+       FCTEmlhWXJl7iFGSg0lJlFe8ACjEl5SfUpmRWJwRX1Sak1p8iFGCg1lJhNctBijHm5JYWZVa\r
+       lA+TkuZgURLnvclhHyQkkJ5YkpqdmlqQWgSTleHgUJLgPVkE1ChYlJqeWpGWmVOCkGbi4AQZ\r
+       zgM0/BlIDW9xQWJucWY6RP4Uo6KUOO8lkIQASCKjNA+uF5YuXjGKA70izHsApIoHmGrgul8B\r
+       DWYCGrzkbiPI4JJEhJRUA2N3Rt2Df5/uKX8PdZYQ5pLzWn22aLJyTX7oD47p7x5vn+12OfRP\r
+       bYFs17Ho3rVdzze/tBJ7zbpkXYBdKPePnsjvQV7mR4ruzN22XOiq3g6hd82d8ns3mUsU7PC7\r
+       ZZruGL1He8dUjS8OqT9/zDoh+bi6xPfSAl+pwp+a1uVmcu4ienE3+ZIXhiixFGckGmoxFxUn\r
+       AgB957TZ8gIAAA==\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+       <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Tue, 12 Nov 2013 19:31:42 -0000\r
+\r
+I think this is a great idea.  Personally I think this is how folder:\r
+should work.  I find the semantics of folder: to be useless except where\r
+they happen to coincide with the boolean semantics used here.\r
+Unfortunately, changing folder: would require versioning the database,\r
+which we have only primordial support for right now.\r
+\r
+Various comments below, though nothing major.  Of course, we'd also need\r
+some tests and man page updates for this.\r
+\r
+On Tue, 12 Nov 2013, Peter Zijlstra <peterz@infradead.org> wrote:\r
+> Subject: notmuch: Add "maildir:" search option\r
+>\r
+> The current "folder:" search terms are near useless when you have\r
+> recursive folders, introduce a boolean "maildir:" search term to\r
+> exactly match the maildir folder.\r
+>\r
+> Given a Maildir++ layout like:\r
+>\r
+>      ~/Maildir/\r
+>      ~/Maildir/cur\r
+>      ~/Maildir/new\r
+>      ~/Maildir/tmp\r
+>      ~/Maildir/.Sent\r
+>      ~/Maildir/.Sent/cur\r
+>      ~/Maildir/.Sent/new\r
+>      ~/Maildir/.Sent/tmp\r
+>      ~/Maildir/.INBOX.LKML\r
+>      ~/Maildir/.INBOX.LKML/cur\r
+>      ~/Maildir/.INBOX.LKML/new\r
+>      ~/Maildir/.INBOX.LKML/tmp\r
+>      ~/Maildir/.INBOX.LKML.netdev\r
+>      ~/Maildir/.INBOX.LKML.netdev/cur\r
+>      ~/Maildir/.INBOX.LKML.netdev/new\r
+>      ~/Maildir/.INBOX.LKML.netdev/tmp\r
+>      ~/Maildir/.INBOX.LKML.arch\r
+>      ~/Maildir/.INBOX.LKML.arch/cur\r
+>      ~/Maildir/.INBOX.LKML.arch/new\r
+>      ~/Maildir/.INBOX.LKML.arch/tmp\r
+>\r
+> This patch generates the following search index:\r
+>\r
+>      $ delve -a Maildir/.notmuch/xapian/ | ~/s XMAILDIR\r
+>      XMAILDIR:INBOX\r
+>      XMAILDIR:INBOX/LKML\r
+>      XMAILDIR:INBOX/LKML/arch\r
+>      XMAILDIR:INBOX/LKML/netdev\r
+>      XMAILDIR:Sent\r
+>\r
+> Which allows one (me!!1) to pose queries like:\r
+>\r
+>      maildir:INBOX and not tag:list\r
+>\r
+> to more easily find offlist mail (from people like my family who don't\r
+> actually send their stuff over LKML :-).\r
+>\r
+> Signed-off-by: Peter Zijlstra <peterz@infradead.org>\r
+> ---\r
+>\r
+> XXX: now I need to go figure out how to do searches like:\r
+>\r
+>   subject:PATCH/0\r
+>\r
+> which would mandate that PATCH is the first word occurring in the\r
+> subject. I think the position index holds enough information but I\r
+> need to look into that and obviously the query parser needs work for\r
+> this.\r
+\r
+This is a frequently requested feature.  Unfortunately, there are two\r
+technical hurdles.  One is that the position information actually\r
+*isn't* enough as it is both because the subject will start at some\r
+arbitrary term offset that depends on the from and to (and maybe other\r
+things) and because the Xapian Query structure doesn't expose a way to\r
+search for a specific term offset (only relative offsets).  The other is\r
+that we currently use Xapian's query parser, which isn't extensible,\r
+though I took a stab at a custom query parser long ago and swear that\r
+one of these days I'll return to it.\r
+\r
+>\r
+>\r
+>  lib/database.cc |  7 ++++---\r
+>  lib/message.cc  | 40 ++++++++++++++++++++++++++++++++++++++++\r
+>  2 files changed, 44 insertions(+), 3 deletions(-)\r
+>\r
+> diff --git a/lib/database.cc b/lib/database.cc\r
+> index a021bf17253c..53aeaa68954d 100644\r
+> --- a/lib/database.cc\r
+> +++ b/lib/database.cc\r
+> @@ -208,15 +208,16 @@ static prefix_t BOOLEAN_PREFIX_EXTERNAL[] = {\r
+>      { "thread",                     "G" },\r
+>      { "tag",                        "K" },\r
+>      { "is",                 "K" },\r
+> -    { "id",                 "Q" }\r
+> +    { "id",                 "Q" },\r
+> +    { "maildir",            "XMAILDIR:" },\r
+\r
+No colon.  That is, the term prefix should just be "XMAILDIR".\r
+\r
+>  };\r
+>  \r
+>  static prefix_t PROBABILISTIC_PREFIX[]= {\r
+>      { "from",                       "XFROM" },\r
+>      { "to",                 "XTO" },\r
+>      { "attachment",         "XATTACHMENT" },\r
+> -    { "subject",            "XSUBJECT"},\r
+> -    { "folder",                     "XFOLDER"}\r
+> +    { "subject",            "XSUBJECT" },\r
+> +    { "folder",                     "XFOLDER" },\r
+\r
+Unintentional whitespace change?\r
+\r
+>  };\r
+>  \r
+>  const char *\r
+> diff --git a/lib/message.cc b/lib/message.cc\r
+> index 1b4637950f8e..45a727a6208f 100644\r
+> --- a/lib/message.cc\r
+> +++ b/lib/message.cc\r
+> @@ -22,6 +22,7 @@\r
+>  #include "database-private.h"\r
+>  \r
+>  #include <stdint.h>\r
+> +#include <string.h>\r
+>  \r
+>  #include <gmime/gmime.h>\r
+>  \r
+> @@ -485,6 +486,8 @@ _notmuch_message_add_filename (notmuch_message_t *message,\r
+>      notmuch_status_t status;\r
+>      void *local = talloc_new (message);\r
+>      char *direntry;\r
+> +    char *maildir;\r
+> +    int i;\r
+>  \r
+>      if (filename == NULL)\r
+>      INTERNAL_ERROR ("Message filename cannot be NULL.");\r
+> @@ -507,6 +510,43 @@ _notmuch_message_add_filename (notmuch_message_t *message,\r
+>      /* New terms allow user to search with folder: specification. */\r
+>      _notmuch_message_gen_terms (message, "folder", directory);\r
+>  \r
+> +    /* Convert the directory into a maildir path */\r
+> +    maildir = talloc_strdup(local, directory);\r
+\r
+Add a space before the "(".  (Same thing throughout the rest of the\r
+patch.)\r
+\r
+> +\r
+> +    /* Strip the maildir "cur", "new" directory entries. */\r
+> +    i = strlen(maildir);\r
+> +    if (strncmp(maildir + i - 3, "cur", 3) == 0 ||\r
+> +    strncmp(maildir + i - 3, "new", 3) == 0) {\r
+\r
+This is unsafe if directory is less than three characters, which I\r
+believe could happen if the message is in the root mail directory (which\r
+shouldn't happen with a well-formed maildir, but notmuch doesn't require\r
+maildir, and, regardless, we should be defensive).\r
+\r
+Also, we have a STRNCMP_LITERAL macro that we often use for comparisons\r
+with string literals, but I'm good with this, too.\r
+\r
+> +        maildir[i - 3] = '\0';\r
+> +        i -= 3;\r
+> +    }\r
+> +\r
+> +    /* Strip trailing '/' */\r
+> +    while (maildir[i-1] == '/') {\r
+\r
+This is also unsafe if maildir is the empty string.\r
+\r
+Also, add spaces around the "-" (likewise on the next line).\r
+\r
+> +        maildir[i-1] = '\0';\r
+> +        i--;\r
+> +    }\r
+> +\r
+> +    /* Strip leading '/' */\r
+> +    while (maildir[0] == '/')\r
+> +        maildir++;\r
+> +\r
+> +    /* Strip leading '.' */\r
+> +    while (maildir[0] == '.')\r
+\r
+Why strip multiple dots?  (I'm not saying you shouldn't, I'm just\r
+curious; and it may be worth explaining in the comment.)\r
+\r
+> +        maildir++;\r
+> +\r
+> +    /* Replace all remaining '.' with '/' */\r
+\r
+I think this should only happen if there was a leading '.', indicating a\r
+Maildir++ folder hierarchy.  A lot of people use the "file system"\r
+Maildir layout, which just consists of nested directories where the\r
+leaves are Maildirs (e.g., Dovecot's LAYOUT=fs,\r
+http://wiki2.dovecot.org/MailboxFormat/Maildir#Directory_Structure).  In\r
+this case, it's perfectly legitimate to have '.'s in folder names and it\r
+would be confusing and unexpected to translate them to '/'s.  This would\r
+also make this compatible with MH folders (which notmuch supports,\r
+though admittedly it's unclear if anyone actually uses them).\r
+\r
+> +    for (i = 0; maildir[i]; i++) {\r
+> +        if (maildir[i] == '.')\r
+> +                maildir[i] = '/';\r
+> +    }\r
+> +\r
+> +    /* If there's no string left, we're the "INBOX" */\r
+> +    if (maildir[0] == '\0')\r
+> +        maildir = talloc_strdup(local, "INBOX");\r
+> +\r
+> +    _notmuch_message_add_term (message, "maildir", maildir);\r
+> +\r
+>      talloc_free (local);\r
+>  \r
+>      return NOTMUCH_STATUS_SUCCESS;\r
+> _______________________________________________\r
+> notmuch mailing list\r
+> notmuch@notmuchmail.org\r
+> http://notmuchmail.org/mailman/listinfo/notmuch\r