Re: [notmuch] [PATCH] notmuch: Add Maildir directory name as tag name for messages
[notmuch-archives.git] / f0 / e3acf72503ccd79e84634ec570314525e3a65e
1 Return-Path: <michiel@michielbuddingh.net>\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 8C865431FBD\r
6         for <notmuch@notmuchmail.org>; Sun,  6 Dec 2009 11:55:25 -0800 (PST)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 Received: from olra.theworths.org ([127.0.0.1])\r
9         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
10         with ESMTP id Jq4++xPeRDab for <notmuch@notmuchmail.org>;\r
11         Sun,  6 Dec 2009 11:55:24 -0800 (PST)\r
12 Received: from aegir.org.uk (aegir.org.uk [87.238.170.13])\r
13         by olra.theworths.org (Postfix) with ESMTP id 29638431FBC\r
14         for <notmuch@notmuchmail.org>; Sun,  6 Dec 2009 11:55:24 -0800 (PST)\r
15 Received: from localhost (109-9-ftth.onsnetstudenten.nl [145.120.9.109])\r
16         (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits))\r
17         (No client certificate requested)\r
18         by aegir.org.uk (Postfix) with ESMTPSA id ED35A2E01B;\r
19         Sun,  6 Dec 2009 20:55:22 +0100 (CET)\r
20 From: Michiel Buddingh' <michiel@michielbuddingh.net>\r
21 To: Carl Worth <cworth@cworth.org>, notmuch@notmuchmail.org\r
22 In-Reply-To: <87ws1bjpmm.fsf@yoom.home.cworth.org>\r
23 References: <87fx8bygi7.fsf@linux.vnet.ibm.com>\r
24         <87bpiv4t9h.fsf@yoom.home.cworth.org>\r
25         <87y6lz39nd.fsf@yoom.home.cworth.org>\r
26         <20091121221207.GB17268@jukie.net>\r
27         <9cce5525b093b87fe74d427954ffad89@localhost>\r
28         <87d43b2oif.fsf@yoom.home.cworth.org>\r
29         <9bfdedddeab9c58cd45d8d448323d0fc@localhost>\r
30         <87skc23327.fsf@yoom.home.cworth.org>\r
31         <4b0eef22.JwxdgTGElffx149F%michiel@michielbuddingh.net>\r
32         <87ws1bjpmm.fsf@yoom.home.cworth.org>\r
33 Date: Sun, 06 Dec 2009 20:55:22 +0100\r
34 Message-ID: <878wdfkhcl.fsf@aegir.org.uk>\r
35 MIME-Version: 1.0\r
36 Content-Type: text/plain; charset=us-ascii\r
37 Subject: Re: [notmuch] [PATCH] notmuch: Add Maildir directory name as tag\r
38  name for messages\r
39 X-BeenThere: notmuch@notmuchmail.org\r
40 X-Mailman-Version: 2.1.12\r
41 Precedence: list\r
42 List-Id: "Use and development of the notmuch mail system."\r
43         <notmuch.notmuchmail.org>\r
44 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
45         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
46 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
47 List-Post: <mailto:notmuch@notmuchmail.org>\r
48 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
49 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
50         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
51 X-List-Received-Date: Sun, 06 Dec 2009 19:55:25 -0000\r
52 \r
53 \r
54 First of all, apologies for taking so long to get back to this.\r
55 \r
56 On Fri, 27 Nov 2009, Carl Worth <cworth@cworth.org> wrote:\r
57 > The auto-detection is just three additional stats (at most) for each\r
58 > directory, right? That seems cheap enough to me.\r
59 \r
60 If that's cheap enough, then I won't disagree with auto-detection.  \r
61 Jan Janak's patch seems to take most of the disk access cost out of it,\r
62 in any case.\r
63 \r
64 > That seems orthogonal to me. Would the dovecot index files be easy to\r
65 > skip with a pattern-based blacklist?\r
66 \r
67 Yes, and that's a much more elegant solution.\r
68 \r
69 > > I'll be happy to implement them, although I'd like for others to\r
70 > > chime in on the configure-as-Maildir vs. autodetect-Maildir issue.\r
71 > > And thanks for your patience in working through my patch.\r
72 \r
73 I didn't mean to call a vote--rather to solicit the opinions of others\r
74 with possibly even more exotic mail storage configurations.\r
75 \r
76 A new patch is attached.  Apologies for the rather verbose Maildir\r
77 handling logic, but I couldn't find a way to minimize the calls to\r
78 is_maildir that was both neat and readable.\r
79 \r
80 -- \r
81 Michiel\r
82 \r
83 ---\r
84  notmuch-client.h |    1 +\r
85  notmuch-new.c    |   93 +++++++++++++++++++++++++++++++++++++++++++++++++++--\r
86  2 files changed, 90 insertions(+), 4 deletions(-)\r
87 \r
88 diff --git a/notmuch-client.h b/notmuch-client.h\r
89 index 50a30fe..7bc84a1 100644\r
90 --- a/notmuch-client.h\r
91 +++ b/notmuch-client.h\r
92 @@ -77,6 +77,7 @@ typedef struct {\r
93      int saw_read_only_directory;\r
94      int output_is_a_tty;\r
95      int verbose;\r
96 +    int tag_maildir;\r
97  \r
98      int total_files;\r
99      int processed_files;\r
100 diff --git a/notmuch-new.c b/notmuch-new.c\r
101 index 9d20616..8742ab4 100644\r
102 --- a/notmuch-new.c\r
103 +++ b/notmuch-new.c\r
104 @@ -109,6 +109,60 @@ is_maildir (struct dirent **entries, int count)\r
105      return 0;\r
106  }\r
107  \r
108 +/* Tag new mail according to its Maildir attribute flags.\r
109 + *\r
110 + * Test if the mail file's filename contains any of the\r
111 + * standard Maildir attributes, and translate these to\r
112 + * the corresponding standard notmuch tags.\r
113 + *\r
114 + * If the message is not marked as 'seen', or if no\r
115 + * flags are present, tag as 'inbox, unread'.\r
116 + */\r
117 +static void\r
118 +derive_tags_from_maildir_flags (notmuch_message_t *message,\r
119 +                               const char * path)\r
120 +{\r
121 +    int seen = FALSE;\r
122 +    int end_of_flags = FALSE;\r
123 +    size_t l = strlen(path);\r
124 +\r
125 +    /* Non-experimental message flags start with this */\r
126 +    char * i = strstr(path, ":2,");\r
127 +    i = (i) ? i : strstr(path, "!2,"); /* This format is used on VFAT */\r
128 +    if (i != NULL) {\r
129 +       i += 3;\r
130 +       for (; i < (path + l) && !end_of_flags; i++) {\r
131 +           switch (*i) {\r
132 +           case 'F' :\r
133 +               notmuch_message_add_tag (message, "flagged");\r
134 +               break;\r
135 +           case 'R': /* replied */\r
136 +               notmuch_message_add_tag (message, "answered");\r
137 +               break;\r
138 +           case 'D':\r
139 +               notmuch_message_add_tag (message, "draft");\r
140 +               break;\r
141 +           case 'S': /* seen */\r
142 +               seen = TRUE;\r
143 +               break;\r
144 +           case 'T': /* trashed */\r
145 +               notmuch_message_add_tag (message, "deleted");\r
146 +               break;\r
147 +           case 'P': /* passed */\r
148 +               notmuch_message_add_tag (message, "forwarded");\r
149 +               break;\r
150 +           default:\r
151 +               end_of_flags = TRUE;\r
152 +               break;\r
153 +           }\r
154 +       }\r
155 +    }\r
156 +\r
157 +    if (i == NULL || !seen) {\r
158 +       tag_inbox_and_unread (message);\r
159 +    }\r
160 +}\r
161 +\r
162  /* Examine 'path' recursively as follows:\r
163   *\r
164   *   o Ask the filesystem for the mtime of 'path' (path_mtime)\r
165 @@ -142,6 +196,7 @@ add_files_recursive (notmuch_database_t *notmuch,\r
166      notmuch_status_t status, ret = NOTMUCH_STATUS_SUCCESS;\r
167      notmuch_message_t *message = NULL;\r
168      struct dirent **namelist = NULL;\r
169 +    int maildir_detected = -1; /* -1 = unset */\r
170      int num_entries;\r
171  \r
172      /* If we're told to, we bail out on encountering a read-only\r
173 @@ -189,13 +244,37 @@ add_files_recursive (notmuch_database_t *notmuch,\r
174         if (strcmp (entry->d_name, ".") == 0 ||\r
175             strcmp (entry->d_name, "..") == 0 ||\r
176             (entry->d_type == DT_DIR &&\r
177 -            (strcmp (entry->d_name, "tmp") == 0) &&\r
178 -            is_maildir (namelist, num_entries)) ||\r
179 -           strcmp (entry->d_name, ".notmuch") ==0)\r
180 +            strcmp (entry->d_name, ".notmuch") == 0))\r
181         {\r
182             continue;\r
183         }\r
184  \r
185 +\r
186 +       /* If this directory is a Maildir folder, we need to\r
187 +        * ignore any subdirectories marked tmp/, and scan for\r
188 +        * Maildir attributes on messages contained in the sub-\r
189 +        * directories 'new' and 'cur'. */\r
190 +       if (maildir_detected != 0 &&\r
191 +           entry->d_type == DT_DIR &&\r
192 +           ((strcmp (entry->d_name, "tmp") == 0) ||\r
193 +            (strcmp (entry->d_name, "new") == 0) ||\r
194 +            (strcmp (entry->d_name, "cur") == 0))) {\r
195 +\r
196 +           /* is_maildir scans the entire directory.  No need to\r
197 +              do this more than once, if at all */\r
198 +           if (maildir_detected == -1) {\r
199 +               maildir_detected = is_maildir (namelist, num_entries);\r
200 +           }\r
201 +\r
202 +           if (maildir_detected == 1) {\r
203 +               if (strcmp (entry->d_name, "tmp") == 0) {\r
204 +                   continue;\r
205 +               } else {\r
206 +                   state->tag_maildir = TRUE;\r
207 +               }\r
208 +           }\r
209 +       }\r
210 +\r
211         next = talloc_asprintf (notmuch, "%s/%s", path, entry->d_name);\r
212  \r
213         if (stat (next, st)) {\r
214 @@ -240,7 +319,12 @@ add_files_recursive (notmuch_database_t *notmuch,\r
215                     /* success */\r
216                     case NOTMUCH_STATUS_SUCCESS:\r
217                         state->added_messages++;\r
218 -                       tag_inbox_and_unread (message);\r
219 +                       if (state->tag_maildir) {\r
220 +                           derive_tags_from_maildir_flags (message,\r
221 +                                                           entry->d_name);\r
222 +                       } else {\r
223 +                           tag_inbox_and_unread (message);\r
224 +                       }\r
225                         break;\r
226                     /* Non-fatal issues (go on to next file) */\r
227                     case NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID:\r
228 @@ -282,6 +366,7 @@ add_files_recursive (notmuch_database_t *notmuch,\r
229             status = add_files_recursive (notmuch, next, st, state);\r
230             if (status && ret == NOTMUCH_STATUS_SUCCESS)\r
231                 ret = status;\r
232 +           state->tag_maildir = FALSE;\r
233         }\r
234  \r
235         talloc_free (next);\r
236 -- \r
237 1.6.5.4\r