Re: notmuch and "mute" -- useful to anyone?
[notmuch-archives.git] / 26 / 29ce253bd24b814ae4cacc841a8703ff007641
1 Return-Path: <peterz@infradead.org>\r
2 X-Original-To: notmuch@notmuchmail.org\r
3 Delivered-To: notmuch@notmuchmail.org\r
4 Received: from localhost (localhost [127.0.0.1])\r
5         by olra.theworths.org (Postfix) with ESMTP id 3C0FD431E82\r
6         for <notmuch@notmuchmail.org>; Wed, 13 Nov 2013 12:09:02 -0800 (PST)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: -2.3\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=-2.3 tagged_above=-999 required=5\r
12         tests=[RCVD_IN_DNSWL_MED=-2.3] autolearn=disabled\r
13 Received: from olra.theworths.org ([127.0.0.1])\r
14         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
15         with ESMTP id svZTLYEtPkGu for <notmuch@notmuchmail.org>;\r
16         Wed, 13 Nov 2013 12:08:56 -0800 (PST)\r
17 Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134])\r
18         (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))\r
19         (No client certificate requested)\r
20         by olra.theworths.org (Postfix) with ESMTPS id 71331431FD0\r
21         for <notmuch@notmuchmail.org>; Wed, 13 Nov 2013 12:08:56 -0800 (PST)\r
22 Received: from dhcp-077-248-225-117.chello.nl ([77.248.225.117] helo=laptop)\r
23         by merlin.infradead.org with esmtpsa (Exim 4.80.1 #2 (Red Hat Linux))\r
24         id 1VggkA-0004CF-5F; Wed, 13 Nov 2013 20:08:54 +0000\r
25 Received: by laptop (Postfix, from userid 1000)\r
26         id 5CD05103BA2D3; Wed, 13 Nov 2013 21:08:52 +0100 (CET)\r
27 Date: Wed, 13 Nov 2013 21:08:52 +0100\r
28 From: Peter Zijlstra <peterz@infradead.org>\r
29 To: Austin Clements <aclements@csail.mit.edu>\r
30 Subject: Re: [PATCH] notmuch: Add "maildir:" search option\r
31 Message-ID: <20131113200852.GG16796@laptop.programming.kicks-ass.net>\r
32 References: <20131112155637.GA16796@laptop.programming.kicks-ass.net>\r
33         <87mwl94dte.fsf@awakening.csail.mit.edu>\r
34         <87k3gd4dfb.fsf@awakening.csail.mit.edu>\r
35 MIME-Version: 1.0\r
36 Content-Type: text/plain; charset=us-ascii\r
37 Content-Disposition: inline\r
38 In-Reply-To: <87k3gd4dfb.fsf@awakening.csail.mit.edu>\r
39 User-Agent: Mutt/1.5.21 (2012-12-30)\r
40 Cc: notmuch@notmuchmail.org\r
41 X-BeenThere: notmuch@notmuchmail.org\r
42 X-Mailman-Version: 2.1.13\r
43 Precedence: list\r
44 List-Id: "Use and development of the notmuch mail system."\r
45         <notmuch.notmuchmail.org>\r
46 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
47         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
48 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
49 List-Post: <mailto:notmuch@notmuchmail.org>\r
50 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
51 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
52         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
53 X-List-Received-Date: Wed, 13 Nov 2013 20:09:02 -0000\r
54 \r
55 On Tue, Nov 12, 2013 at 02:39:52PM -0500, Austin Clements wrote:\r
56 > On Tue, 12 Nov 2013, Austin Clements <aclements@csail.mit.edu> wrote:\r
57 > > I think this is a great idea.  Personally I think this is how folder:\r
58 > > should work.  I find the semantics of folder: to be useless except where\r
59 > > they happen to coincide with the boolean semantics used here.\r
60 > > Unfortunately, changing folder: would require versioning the database,\r
61 > > which we have only primordial support for right now.\r
62 > >\r
63 > > Various comments below, though nothing major.  Of course, we'd also need\r
64 > > some tests and man page updates for this.\r
65\r
66 > Sorry, one important thing I missed: this doesn't correctly handle when\r
67 > file names are removed from a message\r
68 > (_notmuch_message_remove_filename).  Probably the simplest thing would\r
69 > be to follow the template for how folder: works by first removing *all*\r
70 > folder terms and then adding back the still-valid ones.  (Unfortunately,\r
71 > just removing the term for the removed filename's directory won't work\r
72 > because the message could have other filenames in the same directory,\r
73 > though maybe you could just scan for that possibility?)\r
74 \r
75 Oh, right you are. A little something like the below? Its compile tested\r
76 only and I've not yet had time to look at how the test infrastructure\r
77 works.\r
78 \r
79 \r
80 ---\r
81  lib/database.cc |   3 +-\r
82  lib/message.cc  | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++-----\r
83  2 files changed, 104 insertions(+), 10 deletions(-)\r
84 \r
85 diff --git a/lib/database.cc b/lib/database.cc\r
86 index a021bf17253c..e43e17dffcd0 100644\r
87 --- a/lib/database.cc\r
88 +++ b/lib/database.cc\r
89 @@ -208,7 +208,8 @@ static prefix_t BOOLEAN_PREFIX_EXTERNAL[] = {\r
90      { "thread",                        "G" },\r
91      { "tag",                   "K" },\r
92      { "is",                    "K" },\r
93 -    { "id",                    "Q" }\r
94 +    { "id",                    "Q" },\r
95 +    { "maildir",               "XMAILDIR:" },\r
96  };\r
97  \r
98  static prefix_t PROBABILISTIC_PREFIX[]= {\r
99 diff --git a/lib/message.cc b/lib/message.cc\r
100 index 1b4637950f8e..73d3bb65ab67 100644\r
101 --- a/lib/message.cc\r
102 +++ b/lib/message.cc\r
103 @@ -22,6 +22,7 @@\r
104  #include "database-private.h"\r
105  \r
106  #include <stdint.h>\r
107 +#include <string.h>\r
108  \r
109  #include <gmime/gmime.h>\r
110  \r
111 @@ -473,6 +474,71 @@ notmuch_message_get_replies (notmuch_message_t *message)\r
112      return _notmuch_messages_create (message->replies);\r
113  }\r
114  \r
115 +/* Construct a proper 'maildir' from 'directory'\r
116 + *\r
117 + * Takes the relative directory component inside the maildir pathname and\r
118 + * construct a maildir path from it.\r
119 + *\r
120 + * For filesystem layout Maildir we use the regular filesystem path except the\r
121 + * trailing "cur"/"new" component.\r
122 + *\r
123 + * For Maildir++ we strip the leading '.' and replace subsequent '.'s with '/'s\r
124 + */\r
125 +static char *\r
126 +_notmuch_message_maildir (void *ctx, const char *directory)\r
127 +{\r
128 +    char *maildir;\r
129 +    int i;\r
130 +\r
131 +    maildir = talloc_strdup (ctx, directory);\r
132 +    i = strlen (maildir);\r
133 +\r
134 +    /* Strip trailing '/' */\r
135 +    while (i && maildir[i - 1] == '/') {\r
136 +       maildir[i - 1] = '\0';\r
137 +       i--;\r
138 +    }\r
139 +\r
140 +    /* Strip leading '/' */\r
141 +    while (maildir[0] == '/') {\r
142 +       maildir++;\r
143 +       i--;\r
144 +    }\r
145 +\r
146 +    if (i >= 3) {\r
147 +       /* Consume trailing maildir directory entries */\r
148 +       if (STRNCMP_LITERAL (maildir, "cur") == 0 ||\r
149 +           STRNCMP_LITERAL (maildir, "new") == 0)\r
150 +       {\r
151 +           maildir[i - 3] = '\0';\r
152 +           i -= 3;\r
153 +       }\r
154 +\r
155 +       /* Strip trailing '/' */\r
156 +       while (i && maildir[i - 1] == '/') {\r
157 +           maildir[i-1] = '\0';\r
158 +           i--;\r
159 +       }\r
160 +    }\r
161 +\r
162 +    /* Maildir++ */\r
163 +    if (maildir[0] == '.') {\r
164 +       maildir++;\r
165 +\r
166 +       /* Replace all remaining '.' with '/' */\r
167 +       for (i = 0; maildir[i]; i++) {\r
168 +           if (maildir[i] == '.')\r
169 +               maildir[i] = '/';\r
170 +       }\r
171 +    }\r
172 +\r
173 +    /* If there's no string left, we're the "INBOX" */\r
174 +    if (maildir[0] == '\0')\r
175 +           maildir = talloc_strdup (ctx, "INBOX");\r
176 +\r
177 +    return maildir;\r
178 +}\r
179 +\r
180  /* Add an additional 'filename' for 'message'.\r
181   *\r
182   * This change will not be reflected in the database until the next\r
183 @@ -485,6 +551,7 @@ _notmuch_message_add_filename (notmuch_message_t *message,\r
184      notmuch_status_t status;\r
185      void *local = talloc_new (message);\r
186      char *direntry;\r
187 +    char *maildir;\r
188  \r
189      if (filename == NULL)\r
190         INTERNAL_ERROR ("Message filename cannot be NULL.");\r
191 @@ -507,6 +574,10 @@ _notmuch_message_add_filename (notmuch_message_t *message,\r
192      /* New terms allow user to search with folder: specification. */\r
193      _notmuch_message_gen_terms (message, "folder", directory);\r
194  \r
195 +    /* New terms allow user to serarch with maildir: specification. */\r
196 +    maildir = _notmuch_message_maildir (local, directory);\r
197 +    _notmuch_message_add_term (message, "maildir", maildir);\r
198 +\r
199      talloc_free (local);\r
200  \r
201      return NOTMUCH_STATUS_SUCCESS;\r
202 @@ -535,11 +606,18 @@ _notmuch_message_remove_filename (notmuch_message_t *message,\r
203      void *local = talloc_new (message);\r
204      char *zfolder_prefix = talloc_asprintf(local, "Z%s", folder_prefix);\r
205      int zfolder_prefix_len = strlen (zfolder_prefix);\r
206 -    char *direntry;\r
207 +    const char *relative, *directory;\r
208 +    char *direntry, *maildir;\r
209      notmuch_private_status_t private_status;\r
210      notmuch_status_t status;\r
211      Xapian::TermIterator i, last;\r
212  \r
213 +    relative = _notmuch_database_relative_path (message->notmuch, filename);\r
214 +\r
215 +    status = _notmuch_database_split_path (local, relative, &directory, NULL);\r
216 +    if (status)\r
217 +       return status;\r
218 +\r
219      status = _notmuch_database_filename_to_direntry (\r
220         local, message->notmuch, filename, NOTMUCH_FIND_LOOKUP, &direntry);\r
221      if (status || !direntry)\r
222 @@ -553,12 +631,21 @@ _notmuch_message_remove_filename (notmuch_message_t *message,\r
223      if (status)\r
224         return status;\r
225  \r
226 -    /* Re-synchronize "folder:" terms for this message. This requires:\r
227 -     *  1. removing all "folder:" terms\r
228 -     *  2. removing all "folder:" stemmed terms\r
229 -     *  3. adding back terms for all remaining filenames of the message. */\r
230 -\r
231 -    /* 1. removing all "folder:" terms */\r
232 +    /* Re-synchronize "folder:" and "maildir:" terms for this message. This\r
233 +     * requires:\r
234 +     *  1. removing "maildir:" for this filename\r
235 +     *  2. removing all "folder:" terms\r
236 +     *  3. removing all "folder:" stemmed terms\r
237 +     *\r
238 +     * For all remaining filenames of the message:\r
239 +     *  4. adding back "folder:" terms\r
240 +     *  5. adding back "maildir:" */\r
241 +\r
242 +    /* 1. remove "maildir:" for this message */\r
243 +    maildir = _notmuch_message_maildir (local, directory);\r
244 +    _notmuch_message_remove_term (message, "maildir", maildir);\r
245 +\r
246 +    /* 2. removing all "folder:" terms */\r
247      while (1) {\r
248         i = message->doc.termlist_begin ();\r
249         i.skip_to (folder_prefix);\r
250 @@ -577,7 +664,7 @@ _notmuch_message_remove_filename (notmuch_message_t *message,\r
251         }\r
252      }\r
253  \r
254 -    /* 2. removing all "folder:" stemmed terms */\r
255 +    /* 3. removing all "folder:" stemmed terms */\r
256      while (1) {\r
257         i = message->doc.termlist_begin ();\r
258         i.skip_to (zfolder_prefix);\r
259 @@ -596,7 +683,7 @@ _notmuch_message_remove_filename (notmuch_message_t *message,\r
260         }\r
261      }\r
262  \r
263 -    /* 3. adding back terms for all remaining filenames of the message. */\r
264 +    /* for all remaining filenames of the message */\r
265      i = message->doc.termlist_begin ();\r
266      i.skip_to (direntry_prefix);\r
267  \r
268 @@ -623,8 +710,14 @@ _notmuch_message_remove_filename (notmuch_message_t *message,\r
269         directory = _notmuch_database_get_directory_path (local,\r
270                                                           message->notmuch,\r
271                                                           directory_id);\r
272 +\r
273 +       /* 4. adding back "folder:" terms */\r
274         if (strlen (directory))\r
275             _notmuch_message_gen_terms (message, "folder", directory);\r
276 +\r
277 +       /* 5. adding back "maildir:" */\r
278 +       maildir = _notmuch_message_maildir (local, directory);\r
279 +       _notmuch_message_add_term (message, "maildir", maildir);\r
280      }\r
281  \r
282      talloc_free (local);\r