]> git.notmuchmail.org Git - notmuch/blob - test/corpus/cur/32:2,
contrib: pick: use notmuch-start-notmuch
[notmuch] / test / corpus / cur / 32:2,
1 From: "Jan Janak" <jan@ryngle.com>
2 To: notmuch@notmuchmail.org
3 Date: Wed, 18 Nov 2009 05:57:03 +0100
4 Subject: [notmuch] [PATCH] notmuch new: Support for conversion of spool
5         subdirectories into tags
6 Message-ID: <1258520223-15328-1-git-send-email-jan@ryngle.com>
7
8 This patch makes it possible to convert subdirectory names inside the
9 spool directory into message tags. Messages stored in subdirectory
10 "foo" will be marked with tag "foo". Message duplicates found in several
11 subdirectories will be given one tag per subdirectory.
12
13 This feature can be used to synchronize notmuch's tags with with gmail
14 tags, for example. Gmail IMAP servers convert tags to IMAP
15 subdirectories and those subdirectories can be converted back to tags
16 in notmuch.
17
18 The patch modifies notmuch_database_add_message function to return a
19 pointer to the message even if a message duplicate was found in the
20 database. This is needed if we want to add a tag for each subdirectory
21 in which a message duplicate was found.
22
23 In addition to that, it makes the pointer to notmuch_config_t global
24 (previously it was a local variable in notmuch_new_command). The
25 configuration data structure is used by the function which converts
26 subdirectory names to tags.
27
28 Finally, there is a new function called subdir_to_tag. The function
29 extracts the name of the subdirectory inside the spool from the full
30 path of the message (also removing Maildir's cur,dir,and tmp
31 subdirectories) and adds it as a new tag to the message.
32
33 Signed-off-by: Jan Janak <jan at ryngle.com>
34 ---
35  lib/database.cc |    3 +-
36  notmuch-new.c   |   74 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
37  2 files changed, 74 insertions(+), 3 deletions(-)
38
39 diff --git a/lib/database.cc b/lib/database.cc
40 index 3c8d626..f7799d2 100644
41 --- a/lib/database.cc
42 +++ b/lib/database.cc
43 @@ -949,7 +949,8 @@ notmuch_database_add_message (notmuch_database_t *notmuch,
44  
45    DONE:
46      if (message) {
47 -       if (ret == NOTMUCH_STATUS_SUCCESS && message_ret)
48 +               if ((ret == NOTMUCH_STATUS_SUCCESS ||
49 +                        ret == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) && message_ret)
50             *message_ret = message;
51         else
52             notmuch_message_destroy (message);
53 diff --git a/notmuch-new.c b/notmuch-new.c
54 index 83a05ba..d94ce16 100644
55 --- a/notmuch-new.c
56 +++ b/notmuch-new.c
57 @@ -19,6 +19,9 @@
58   */
59  
60  #include "notmuch-client.h"
61 +#include <libgen.h>
62 +
63 +static notmuch_config_t *config = 0;
64  
65  static volatile sig_atomic_t do_add_files_print_progress = 0;
66  
67 @@ -45,6 +48,69 @@ tag_inbox_and_unread (notmuch_message_t *message)
68      notmuch_message_add_tag (message, "unread");
69  }
70  
71 +/*
72 + * Extracts the sub-directory from the filename and adds it as a new tag to
73 + * the message. The filename must begin with the database directory configured
74 + * in the configuration file. This prefix is then removed. If the remaining
75 + * sub-directory ends with one of the Maildir special directories (/tmp, /new,
76 + * /cur) then they are removed as well. If there is anything left then the
77 + * function adds it as a new tag to the message.
78 + *
79 + * The function does nothing if it cannot extract a sub-directory from
80 + * filename.
81 + */
82 +static void
83 +subdir_to_tag (char* filename, notmuch_message_t *message)
84 +{
85 +       const char* db_path;
86 +       char *msg_dir, *tmp;
87 +       int db_path_len, msg_dir_len;
88 +
89 +       if (config == NULL) return;
90 +    db_path = notmuch_config_get_database_path (config);
91 +       if (db_path == NULL) return;
92 +       db_path_len = strlen(db_path);
93 +
94 +       /* Make a copy of the string as dirname may need to modify it. */
95 +       tmp = talloc_strdup(message, filename);
96 +       msg_dir = dirname(tmp);
97 +       msg_dir_len = strlen(msg_dir);
98 +
99 +       /* If msg_dir starts with db_path, remove it, including the / which delimits
100 +        * it from the rest of the directory name. */
101 +       if (db_path_len < msg_dir_len &&
102 +               !strncmp(db_path, msg_dir, db_path_len)) {
103 +               msg_dir += db_path_len + 1;
104 +               msg_dir_len -= db_path_len + 1;
105 +       } else {
106 +               /* If we get here, either the message filename is not inside the
107 +                * database directory configured in the configuration file, or it is a
108 +                * file in the root directory of the database. Either way we just skip
109 +                * it because we do not know how to convert it to a meaningful
110 +                * subdirectory string that we could add as tag. */
111 +               goto out;
112 +       }
113 +
114 +       /* Special conditioning for Maildirs. If the remainder of the directory
115 +        * name ends with /new, /cur, or /tmp then remove it. */
116 +       if ((msg_dir_len >= 4) &&
117 +               (!strncmp(msg_dir + msg_dir_len - 4, "/new", 4) ||
118 +                !strncmp(msg_dir + msg_dir_len - 4, "/cur", 4) ||
119 +                !strncmp(msg_dir + msg_dir_len - 4, "/tmp", 4))) {
120 +               msg_dir[msg_dir_len - 4] = '\0';
121 +       }
122 +
123 +       /* If, after all the modifications, we still have a subdirectory, add it
124 +        * as tag. */
125 +       if (strlen(msg_dir)) {
126 +               notmuch_message_add_tag (message, msg_dir);
127 +       }
128 +
129 +out:
130 +       talloc_free(tmp);
131 +}
132 +
133 +
134  static void
135  add_files_print_progress (add_files_state_t *state)
136  {
137 @@ -186,10 +252,15 @@ add_files_recursive (notmuch_database_t *notmuch,
138                     case NOTMUCH_STATUS_SUCCESS:
139                         state->added_messages++;
140                         tag_inbox_and_unread (message);
141 +                       subdir_to_tag(next, message);
142                         break;
143                     /* Non-fatal issues (go on to next file) */
144                     case NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID:
145 -                       /* Stay silent on this one. */
146 +                       /* Stay silent on this one. The message already exists in the
147 +                                * database, that means we may have found a duplicate in
148 +                                * another directory. If that's the case then we add another
149 +                                * tag to the message with the sub-directory. */
150 +                               subdir_to_tag(next, message);
151                         break;
152                     case NOTMUCH_STATUS_FILE_NOT_EMAIL:
153                         fprintf (stderr, "Note: Ignoring non-mail file: %s\n",
154 @@ -386,7 +457,6 @@ int
155  notmuch_new_command (void *ctx,
156                      unused (int argc), unused (char *argv[]))
157  {
158 -    notmuch_config_t *config;
159      notmuch_database_t *notmuch;
160      add_files_state_t add_files_state;
161      double elapsed;
162 -- 
163 1.6.3.3
164
165