Re: [PATCH] lib: provide _notmuch_database_log_append
[notmuch-archives.git] / 85 / a0dbba96fd90a1c126ca63da73533f98faa36d
1 Return-Path: <sojkam1@fel.cvut.cz>\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 22E45429E32\r
6         for <notmuch@notmuchmail.org>; Fri, 31 Oct 2014 14:54:40 -0700 (PDT)\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 ohMM3sjlw1Wm for <notmuch@notmuchmail.org>;\r
16         Fri, 31 Oct 2014 14:54:32 -0700 (PDT)\r
17 Received: from max.feld.cvut.cz (max.feld.cvut.cz [147.32.192.36])\r
18         by olra.theworths.org (Postfix) with ESMTP id 97F87431FCB\r
19         for <notmuch@notmuchmail.org>; Fri, 31 Oct 2014 14:54:21 -0700 (PDT)\r
20 Received: from localhost (unknown [192.168.200.7])\r
21         by max.feld.cvut.cz (Postfix) with ESMTP id 841805CD10C\r
22         for <notmuch@notmuchmail.org>; Fri, 31 Oct 2014 22:54:18 +0100 (CET)\r
23 X-Virus-Scanned: IMAP STYX AMAVIS\r
24 Received: from max.feld.cvut.cz ([192.168.200.1])\r
25         by localhost (styx.feld.cvut.cz [192.168.200.7]) (amavisd-new,\r
26         port 10044) with ESMTP id lE4ZSZ6EAiv0 for <notmuch@notmuchmail.org>;\r
27         Fri, 31 Oct 2014 22:54:15 +0100 (CET)\r
28 Received: from imap.feld.cvut.cz (imap.feld.cvut.cz [147.32.192.34])\r
29         by max.feld.cvut.cz (Postfix) with ESMTP id EDD7D3D3E93\r
30         for <notmuch@notmuchmail.org>; Fri, 31 Oct 2014 22:54:14 +0100 (CET)\r
31 Received: from wsh by steelpick.2x.cz with local (Exim 4.84)\r
32         (envelope-from <sojkam1@fel.cvut.cz>)\r
33         id 1XkK92-0007ht-Oj; Fri, 31 Oct 2014 22:54:08 +0100\r
34 From: Michal Sojka <sojkam1@fel.cvut.cz>\r
35 To: notmuch@notmuchmail.org\r
36 Subject: [PATCH v6 5/7] cli: search: Do not output duplicate addresses\r
37 Date: Fri, 31 Oct 2014 22:53:59 +0100\r
38 Message-Id: <1414792441-29555-6-git-send-email-sojkam1@fel.cvut.cz>\r
39 X-Mailer: git-send-email 2.1.1\r
40 In-Reply-To: <1414792441-29555-1-git-send-email-sojkam1@fel.cvut.cz>\r
41 References: <1414792441-29555-1-git-send-email-sojkam1@fel.cvut.cz>\r
42 MIME-Version: 1.0\r
43 Content-Type: text/plain; charset=UTF-8\r
44 Content-Transfer-Encoding: 8bit\r
45 X-BeenThere: notmuch@notmuchmail.org\r
46 X-Mailman-Version: 2.1.13\r
47 Precedence: list\r
48 List-Id: "Use and development of the notmuch mail system."\r
49         <notmuch.notmuchmail.org>\r
50 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
51         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
52 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
53 List-Post: <mailto:notmuch@notmuchmail.org>\r
54 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
55 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
56         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
57 X-List-Received-Date: Fri, 31 Oct 2014 21:54:40 -0000\r
58 \r
59 This filters out duplicate addresses from address outputs (sender,\r
60 receivers).\r
61 \r
62 It also also adds tests for the new outputs.\r
63 \r
64 The code here is an extended version of a patch from Jani Nikula.\r
65 ---\r
66  doc/man1/notmuch-search.rst |  2 ++\r
67  notmuch-search.c            | 51 ++++++++++++++++++++++----\r
68  test/T090-search-output.sh  | 87 +++++++++++++++++++++++++++++++++++++++++++++\r
69  3 files changed, 134 insertions(+), 6 deletions(-)\r
70 \r
71 diff --git a/doc/man1/notmuch-search.rst b/doc/man1/notmuch-search.rst\r
72 index b6607c9..42f17e4 100644\r
73 --- a/doc/man1/notmuch-search.rst\r
74 +++ b/doc/man1/notmuch-search.rst\r
75 @@ -85,6 +85,8 @@ Supported options for **search** include\r
76              (--format=text0), as a JSON array (--format=json), or as\r
77              an S-Expression list (--format=sexp).\r
78  \r
79 +            Duplicate addresses are filtered out.\r
80 +\r
81             Note: Searching for **sender** should be much faster than\r
82             searching for **recipients**, because sender addresses are\r
83             cached directly in the database whereas other addresses\r
84 diff --git a/notmuch-search.c b/notmuch-search.c\r
85 index 671fe41..43d42c6 100644\r
86 --- a/notmuch-search.c\r
87 +++ b/notmuch-search.c\r
88 @@ -229,6 +229,27 @@ do_search_threads (search_options_t *opt)\r
89      return 0;\r
90  }\r
91  \r
92 +/* Returns TRUE iff name and addr is duplicate. */\r
93 +static notmuch_bool_t\r
94 +is_duplicate (const search_options_t *opt, GHashTable *addrs, const char *name, const char *addr)\r
95 +{\r
96 +    notmuch_bool_t duplicate;\r
97 +    char *key;\r
98 +\r
99 +    key = talloc_asprintf (opt->format, "%s <%s>", name, addr);\r
100 +    if (! key)\r
101 +       return FALSE;\r
102 +\r
103 +    duplicate = g_hash_table_lookup_extended (addrs, key, NULL, NULL);\r
104 +\r
105 +    if (! duplicate)\r
106 +       g_hash_table_insert (addrs, key, NULL);\r
107 +    else\r
108 +       talloc_free (key);\r
109 +\r
110 +    return duplicate;\r
111 +}\r
112 +\r
113  static void\r
114  print_mailbox (const search_options_t *opt, const mailbox_t *mailbox)\r
115  {\r
116 @@ -263,7 +284,8 @@ print_mailbox (const search_options_t *opt, const mailbox_t *mailbox)\r
117  \r
118  /* Print addresses from InternetAddressList.  */\r
119  static void\r
120 -process_address_list (const search_options_t *opt, InternetAddressList *list)\r
121 +process_address_list (const search_options_t *opt, GHashTable *addrs,\r
122 +                     InternetAddressList *list)\r
123  {\r
124      InternetAddress *address;\r
125      int i;\r
126 @@ -279,7 +301,7 @@ process_address_list (const search_options_t *opt, InternetAddressList *list)\r
127             if (group_list == NULL)\r
128                 continue;\r
129  \r
130 -           process_address_list (opt, group_list);\r
131 +           process_address_list (opt, addrs, group_list);\r
132         } else {\r
133             InternetAddressMailbox *mailbox = INTERNET_ADDRESS_MAILBOX (address);\r
134             mailbox_t mbx = {\r
135 @@ -287,6 +309,9 @@ process_address_list (const search_options_t *opt, InternetAddressList *list)\r
136                 .addr = internet_address_mailbox_get_addr (mailbox),\r
137             };\r
138  \r
139 +           if (is_duplicate (opt, addrs, mbx.name, mbx.addr))\r
140 +               continue;\r
141 +\r
142             print_mailbox (opt, &mbx);\r
143         }\r
144      }\r
145 @@ -294,7 +319,7 @@ process_address_list (const search_options_t *opt, InternetAddressList *list)\r
146  \r
147  /* Print addresses from a message header.  */\r
148  static void\r
149 -process_address_header (const search_options_t *opt, const char *value)\r
150 +process_address_header (const search_options_t *opt, GHashTable *addrs, const char *value)\r
151  {\r
152      InternetAddressList *list;\r
153  \r
154 @@ -305,11 +330,17 @@ process_address_header (const search_options_t *opt, const char *value)\r
155      if (list == NULL)\r
156         return;\r
157  \r
158 -    process_address_list (opt, list);\r
159 +    process_address_list (opt, addrs, list);\r
160  \r
161      g_object_unref (list);\r
162  }\r
163  \r
164 +static void\r
165 +_my_talloc_free_for_g_hash (void *ptr)\r
166 +{\r
167 +    talloc_free (ptr);\r
168 +}\r
169 +\r
170  static int\r
171  do_search_messages (search_options_t *opt)\r
172  {\r
173 @@ -317,8 +348,13 @@ do_search_messages (search_options_t *opt)\r
174      notmuch_messages_t *messages;\r
175      notmuch_filenames_t *filenames;\r
176      sprinter_t *format = opt->format;\r
177 +    GHashTable *addresses = NULL;\r
178      int i;\r
179  \r
180 +    if (opt->output & OUTPUT_ADDRESS_FLAGS)\r
181 +       addresses = g_hash_table_new_full (g_str_hash, g_str_equal,\r
182 +                                          _my_talloc_free_for_g_hash, NULL);\r
183 +\r
184      if (opt->offset < 0) {\r
185         opt->offset += notmuch_query_count_messages (opt->query);\r
186         if (opt->offset < 0)\r
187 @@ -366,7 +402,7 @@ do_search_messages (search_options_t *opt)\r
188                 const char *addrs;\r
189  \r
190                 addrs = notmuch_message_get_header (message, "from");\r
191 -               process_address_header (opt, addrs);\r
192 +               process_address_header (opt, addresses, addrs);\r
193             }\r
194  \r
195             if (opt->output & OUTPUT_RECIPIENTS) {\r
196 @@ -376,7 +412,7 @@ do_search_messages (search_options_t *opt)\r
197  \r
198                 for (j = 0; j < ARRAY_SIZE (hdrs); j++) {\r
199                     addrs = notmuch_message_get_header (message, hdrs[j]);\r
200 -                   process_address_header (opt, addrs);\r
201 +                   process_address_header (opt, addresses, addrs);\r
202                 }\r
203             }\r
204         }\r
205 @@ -384,6 +420,9 @@ do_search_messages (search_options_t *opt)\r
206         notmuch_message_destroy (message);\r
207      }\r
208  \r
209 +    if (addresses)\r
210 +       g_hash_table_unref (addresses);\r
211 +\r
212      notmuch_messages_destroy (messages);\r
213  \r
214      format->end (format);\r
215 diff --git a/test/T090-search-output.sh b/test/T090-search-output.sh\r
216 index 947d572..82380ac 100755\r
217 --- a/test/T090-search-output.sh\r
218 +++ b/test/T090-search-output.sh\r
219 @@ -387,6 +387,93 @@ cat <<EOF >EXPECTED\r
220  EOF\r
221  test_expect_equal_file OUTPUT EXPECTED\r
222  \r
223 +test_begin_subtest "--output=sender"\r
224 +notmuch search --output=sender '*' >OUTPUT\r
225 +cat <<EOF >EXPECTED\r
226 +François Boulogne <boulogne.f@gmail.com>\r
227 +Olivier Berger <olivier.berger@it-sudparis.eu>\r
228 +Chris Wilson <chris@chris-wilson.co.uk>\r
229 +Carl Worth <cworth@cworth.org>\r
230 +Alexander Botero-Lowry <alex.boterolowry@gmail.com>\r
231 +Keith Packard <keithp@keithp.com>\r
232 +Jjgod Jiang <gzjjgod@gmail.com>\r
233 +Rolland Santimano <rollandsantimano@yahoo.com>\r
234 +Jan Janak <jan@ryngle.com>\r
235 +Stewart Smith <stewart@flamingspork.com>\r
236 +Lars Kellogg-Stedman <lars@seas.harvard.edu>\r
237 +Alex Botero-Lowry <alex.boterolowry@gmail.com>\r
238 +Ingmar Vanhassel <ingmar@exherbo.org>\r
239 +Aron Griffis <agriffis@n01se.net>\r
240 +Adrian Perez de Castro <aperez@igalia.com>\r
241 +Israel Herraiz <isra@herraiz.org>\r
242 +Mikhail Gusarov <dottedmag@dottedmag.net>\r
243 +EOF\r
244 +test_expect_equal_file OUTPUT EXPECTED\r
245 +\r
246 +test_begin_subtest "--output=sender --format=json"\r
247 +notmuch search --output=sender --format=json '*' >OUTPUT\r
248 +cat <<EOF >EXPECTED\r
249 +[{"name": "François Boulogne", "address": "boulogne.f@gmail.com", "name-addr": "François Boulogne <boulogne.f@gmail.com>"},\r
250 +{"name": "Olivier Berger", "address": "olivier.berger@it-sudparis.eu", "name-addr": "Olivier Berger <olivier.berger@it-sudparis.eu>"},\r
251 +{"name": "Chris Wilson", "address": "chris@chris-wilson.co.uk", "name-addr": "Chris Wilson <chris@chris-wilson.co.uk>"},\r
252 +{"name": "Carl Worth", "address": "cworth@cworth.org", "name-addr": "Carl Worth <cworth@cworth.org>"},\r
253 +{"name": "Alexander Botero-Lowry", "address": "alex.boterolowry@gmail.com", "name-addr": "Alexander Botero-Lowry <alex.boterolowry@gmail.com>"},\r
254 +{"name": "Keith Packard", "address": "keithp@keithp.com", "name-addr": "Keith Packard <keithp@keithp.com>"},\r
255 +{"name": "Jjgod Jiang", "address": "gzjjgod@gmail.com", "name-addr": "Jjgod Jiang <gzjjgod@gmail.com>"},\r
256 +{"name": "Rolland Santimano", "address": "rollandsantimano@yahoo.com", "name-addr": "Rolland Santimano <rollandsantimano@yahoo.com>"},\r
257 +{"name": "Jan Janak", "address": "jan@ryngle.com", "name-addr": "Jan Janak <jan@ryngle.com>"},\r
258 +{"name": "Stewart Smith", "address": "stewart@flamingspork.com", "name-addr": "Stewart Smith <stewart@flamingspork.com>"},\r
259 +{"name": "Lars Kellogg-Stedman", "address": "lars@seas.harvard.edu", "name-addr": "Lars Kellogg-Stedman <lars@seas.harvard.edu>"},\r
260 +{"name": "Alex Botero-Lowry", "address": "alex.boterolowry@gmail.com", "name-addr": "Alex Botero-Lowry <alex.boterolowry@gmail.com>"},\r
261 +{"name": "Ingmar Vanhassel", "address": "ingmar@exherbo.org", "name-addr": "Ingmar Vanhassel <ingmar@exherbo.org>"},\r
262 +{"name": "Aron Griffis", "address": "agriffis@n01se.net", "name-addr": "Aron Griffis <agriffis@n01se.net>"},\r
263 +{"name": "Adrian Perez de Castro", "address": "aperez@igalia.com", "name-addr": "Adrian Perez de Castro <aperez@igalia.com>"},\r
264 +{"name": "Israel Herraiz", "address": "isra@herraiz.org", "name-addr": "Israel Herraiz <isra@herraiz.org>"},\r
265 +{"name": "Mikhail Gusarov", "address": "dottedmag@dottedmag.net", "name-addr": "Mikhail Gusarov <dottedmag@dottedmag.net>"}]\r
266 +EOF\r
267 +test_expect_equal_file OUTPUT EXPECTED\r
268 +\r
269 +test_begin_subtest "--output=recipients"\r
270 +notmuch search --output=recipients '*' >OUTPUT\r
271 +cat <<EOF >EXPECTED\r
272 +Allan McRae <allan@archlinux.org>\r
273 +"Discussion about the Arch User Repository (AUR)" <aur-general@archlinux.org>\r
274 +olivier.berger@it-sudparis.eu\r
275 +notmuch@notmuchmail.org\r
276 +notmuch <notmuch@notmuchmail.org>\r
277 +Keith Packard <keithp@keithp.com>\r
278 +Mikhail Gusarov <dottedmag@dottedmag.net>\r
279 +EOF\r
280 +test_expect_equal_file OUTPUT EXPECTED\r
281 +\r
282 +test_begin_subtest "--output=sender --output=recipients"\r
283 +notmuch search --output=sender --output=recipients '*' >OUTPUT\r
284 +cat <<EOF >EXPECTED\r
285 +François Boulogne <boulogne.f@gmail.com>\r
286 +Allan McRae <allan@archlinux.org>\r
287 +"Discussion about the Arch User Repository (AUR)" <aur-general@archlinux.org>\r
288 +Olivier Berger <olivier.berger@it-sudparis.eu>\r
289 +olivier.berger@it-sudparis.eu\r
290 +Chris Wilson <chris@chris-wilson.co.uk>\r
291 +notmuch@notmuchmail.org\r
292 +Carl Worth <cworth@cworth.org>\r
293 +Alexander Botero-Lowry <alex.boterolowry@gmail.com>\r
294 +Keith Packard <keithp@keithp.com>\r
295 +Jjgod Jiang <gzjjgod@gmail.com>\r
296 +Rolland Santimano <rollandsantimano@yahoo.com>\r
297 +Jan Janak <jan@ryngle.com>\r
298 +Stewart Smith <stewart@flamingspork.com>\r
299 +Lars Kellogg-Stedman <lars@seas.harvard.edu>\r
300 +notmuch <notmuch@notmuchmail.org>\r
301 +Alex Botero-Lowry <alex.boterolowry@gmail.com>\r
302 +Ingmar Vanhassel <ingmar@exherbo.org>\r
303 +Aron Griffis <agriffis@n01se.net>\r
304 +Adrian Perez de Castro <aperez@igalia.com>\r
305 +Israel Herraiz <isra@herraiz.org>\r
306 +Mikhail Gusarov <dottedmag@dottedmag.net>\r
307 +EOF\r
308 +test_expect_equal_file OUTPUT EXPECTED\r
309 +\r
310  test_begin_subtest "sanitize output for quoted-printable line-breaks in author and subject"\r
311  add_message "[subject]='two =?ISO-8859-1?Q?line=0A_subject?=\r
312         headers'"\r
313 -- \r
314 2.1.1\r
315 \r