1 Return-Path: <m.walters@qmul.ac.uk>
\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 0FD8A429E41
\r
6 for <notmuch@notmuchmail.org>; Tue, 4 Nov 2014 01:12:03 -0800 (PST)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\r
11 X-Spam-Status: No, score=-1.098 tagged_above=-999 required=5
\r
12 tests=[DKIM_ADSP_CUSTOM_MED=0.001, FREEMAIL_FROM=0.001,
\r
13 NML_ADSP_CUSTOM_MED=1.2, RCVD_IN_DNSWL_MED=-2.3] autolearn=disabled
\r
14 Received: from olra.theworths.org ([127.0.0.1])
\r
15 by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)
\r
16 with ESMTP id 4QqeirgmkbYb for <notmuch@notmuchmail.org>;
\r
17 Tue, 4 Nov 2014 01:11:59 -0800 (PST)
\r
18 Received: from mail2.qmul.ac.uk (mail2.qmul.ac.uk [138.37.6.6])
\r
19 (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
\r
20 (No client certificate requested)
\r
21 by olra.theworths.org (Postfix) with ESMTPS id A3862429E37
\r
22 for <notmuch@notmuchmail.org>; Tue, 4 Nov 2014 01:11:58 -0800 (PST)
\r
23 Received: from smtp.qmul.ac.uk ([138.37.6.40])
\r
24 by mail2.qmul.ac.uk with esmtp (Exim 4.71)
\r
25 (envelope-from <m.walters@qmul.ac.uk>)
\r
26 id 1Xla9J-00078p-2q; Tue, 04 Nov 2014 09:11:57 +0000
\r
27 Received: from 5751dfa2.skybroadband.com ([87.81.223.162] helo=localhost)
\r
28 by smtp.qmul.ac.uk with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.71)
\r
29 (envelope-from <m.walters@qmul.ac.uk>)
\r
30 id 1Xla9I-0005Em-6X; Tue, 04 Nov 2014 09:11:36 +0000
\r
31 From: Mark Walters <markwalters1009@gmail.com>
\r
32 To: Michal Sojka <sojkam1@fel.cvut.cz>, notmuch@notmuchmail.org
\r
33 Subject: Re: [PATCH v2 09/10] cli: address: Add --output=count
\r
34 In-Reply-To: <1415058622-21162-10-git-send-email-sojkam1@fel.cvut.cz>
\r
35 References: <1415058622-21162-1-git-send-email-sojkam1@fel.cvut.cz>
\r
36 <1415058622-21162-10-git-send-email-sojkam1@fel.cvut.cz>
\r
37 User-Agent: Notmuch/0.18.1+86~gef5e66a (http://notmuchmail.org) Emacs/23.4.1
\r
38 (x86_64-pc-linux-gnu)
\r
39 Date: Tue, 04 Nov 2014 09:11:35 +0000
\r
40 Message-ID: <87tx2f2uuw.fsf@qmul.ac.uk>
\r
42 Content-Type: text/plain; charset=utf-8
\r
43 Content-Transfer-Encoding: quoted-printable
\r
44 X-Sender-Host-Address: 87.81.223.162
\r
45 X-QM-Geographic: According to ripencc,
\r
46 this message was delivered by a machine in Britain (UK) (GB).
\r
47 X-QM-SPAM-Info: Sender has good ham record. :)
\r
48 X-QM-Body-MD5: 32b1b13e68061787bee67abbe2103240 (of first 20000 bytes)
\r
49 X-SpamAssassin-Score: -0.1
\r
50 X-SpamAssassin-SpamBar: /
\r
51 X-SpamAssassin-Report: The QM spam filters have analysed this message to
\r
53 spam. We require at least 5.0 points to mark a message as spam.
\r
54 This message scored -0.1 points.
\r
55 Summary of the scoring:
\r
56 * 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail
\r
57 provider * (markwalters1009[at]gmail.com)
\r
58 * -0.1 AWL AWL: From: address is in the auto white-list
\r
59 X-QM-Scan-Virus: ClamAV says the message is clean
\r
60 X-BeenThere: notmuch@notmuchmail.org
\r
61 X-Mailman-Version: 2.1.13
\r
63 List-Id: "Use and development of the notmuch mail system."
\r
64 <notmuch.notmuchmail.org>
\r
65 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
66 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
67 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
68 List-Post: <mailto:notmuch@notmuchmail.org>
\r
69 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
70 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
71 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
72 X-List-Received-Date: Tue, 04 Nov 2014 09:12:03 -0000
\r
75 On Mon, 03 Nov 2014, Michal Sojka <sojkam1@fel.cvut.cz> wrote:
\r
76 > This output prints how many times was each address encountered during
\r
79 > completion/notmuch-completion.bash | 2 +-
\r
80 > completion/notmuch-completion.zsh | 2 +-
\r
81 > doc/man1/notmuch-address.rst | 7 ++++++
\r
82 > notmuch-search.c | 49 ++++++++++++++++++++++++++++++++=
\r
84 > test/T095-address.sh | 48 ++++++++++++++++++++++++++++++++=
\r
86 > 5 files changed, 99 insertions(+), 9 deletions(-)
\r
88 > diff --git a/completion/notmuch-completion.bash b/completion/notmuch-comp=
\r
90 > index 94ea2d5..db152f3 100644
\r
91 > --- a/completion/notmuch-completion.bash
\r
92 > +++ b/completion/notmuch-completion.bash
\r
93 > @@ -332,7 +332,7 @@ _notmuch_address()
\r
97 > - COMPREPLY=3D( $( compgen -W "sender recipients" -- "${cur}" ) )
\r
98 > + COMPREPLY=3D( $( compgen -W "sender recipients count" -- "${cur}" )=
\r
103 > diff --git a/completion/notmuch-completion.zsh b/completion/notmuch-compl=
\r
105 > index c606b75..8968562 100644
\r
106 > --- a/completion/notmuch-completion.zsh
\r
107 > +++ b/completion/notmuch-completion.zsh
\r
108 > @@ -61,7 +61,7 @@ _notmuch_address()
\r
110 > _arguments -s : \
\r
111 > '--sort=3D[sort results]:sorting:((newest-first\:"reverse chronologi=
\r
112 cal order" oldest-first\:"chronological order"))' \
\r
113 > - '--output=3D[select what to output]:output:((sender recipients))'
\r
114 > + '--output=3D[select what to output]:output:((sender recipients count=
\r
119 > diff --git a/doc/man1/notmuch-address.rst b/doc/man1/notmuch-address.rst
\r
120 > index 96512b7..18473a7 100644
\r
121 > --- a/doc/man1/notmuch-address.rst
\r
122 > +++ b/doc/man1/notmuch-address.rst
\r
123 > @@ -48,6 +48,13 @@ Supported options for **address** include
\r
124 > Output all addresses from the *To*, *Cc* and *Bcc*
\r
128 > + Print the count of how many times was the address
\r
129 > + encountered during search.
\r
131 > + Note: With this option, addresses are printed only after
\r
132 > + the whole search is finished. This may take long time.
\r
137 I think count should be added to the --output=3D(sender|recipients) line a
\r
140 Also it should say that count ignores the sort order (or possibly that
\r
141 should go with sort?)
\r
149 > ``--sort=3D``\ (**newest-first**\ \|\ **oldest-first**)
\r
150 > This option can be used to present results in either
\r
151 > chronological order (**oldest-first**) or reverse chronological
\r
152 > diff --git a/notmuch-search.c b/notmuch-search.c
\r
153 > index 741702a..d99e530 100644
\r
154 > --- a/notmuch-search.c
\r
155 > +++ b/notmuch-search.c
\r
156 > @@ -33,6 +33,7 @@ typedef enum {
\r
157 > /* Address command */
\r
158 > OUTPUT_SENDER =3D 1 << 5,
\r
159 > OUTPUT_RECIPIENTS =3D 1 << 6,
\r
160 > + OUTPUT_COUNT =3D 1 << 7,
\r
164 > @@ -59,6 +60,7 @@ typedef struct {
\r
166 > const char *name;
\r
167 > const char *addr;
\r
171 > /* Return two stable query strings that identify exactly the matched
\r
172 > @@ -247,17 +249,24 @@ is_duplicate (const search_context_t *ctx, const ch=
\r
173 ar *name, const char *addr)
\r
175 > notmuch_bool_t duplicate;
\r
177 > + mailbox_t *mailbox;
\r
179 > key =3D talloc_asprintf (ctx->format, "%s <%s>", name, addr);
\r
183 > - duplicate =3D g_hash_table_lookup_extended (ctx->addresses, key, NUL=
\r
185 > + duplicate =3D g_hash_table_lookup_extended (ctx->addresses, key, NUL=
\r
186 L, (gpointer)&mailbox);
\r
188 > - if (! duplicate)
\r
189 > - g_hash_table_insert (ctx->addresses, key, NULL);
\r
191 > + if (! duplicate) {
\r
192 > + mailbox =3D talloc (ctx->format, mailbox_t);
\r
193 > + mailbox->name =3D talloc_strdup (mailbox, name);
\r
194 > + mailbox->addr =3D talloc_strdup (mailbox, addr);
\r
195 > + mailbox->count =3D 1;
\r
196 > + g_hash_table_insert (ctx->addresses, key, mailbox);
\r
198 > + mailbox->count++;
\r
199 > talloc_free (key);
\r
202 > return duplicate;
\r
204 > @@ -267,6 +276,7 @@ print_mailbox (const search_context_t *ctx, const mai=
\r
207 > const char *name =3D mailbox->name;
\r
208 > const char *addr =3D mailbox->addr;
\r
209 > + int count =3D mailbox->count;
\r
210 > sprinter_t *format =3D ctx->format;
\r
211 > InternetAddress *ia =3D internet_address_mailbox_new (name, addr);
\r
213 > @@ -276,6 +286,10 @@ print_mailbox (const search_context_t *ctx, const ma=
\r
215 > name_addr =3D internet_address_to_string (ia, FALSE);
\r
217 > if (format->is_text_printer) {
\r
218 > + if (count > 0) {
\r
219 > + format->integer (format, count);
\r
220 > + format->string (format, "\t");
\r
222 > format->string (format, name_addr);
\r
223 > format->separator (format);
\r
225 > @@ -286,6 +300,10 @@ print_mailbox (const search_context_t *ctx, const ma=
\r
227 > format->string (format, addr);
\r
228 > format->map_key (format, "name-addr");
\r
229 > format->string (format, name_addr);
\r
230 > + if (count > 0) {
\r
231 > + format->map_key (format, "count");
\r
232 > + format->integer (format, count);
\r
234 > format->end (format);
\r
235 > format->separator (format);
\r
237 > @@ -294,7 +312,7 @@ print_mailbox (const search_context_t *ctx, const mai=
\r
239 > g_free (name_addr);
\r
242 > -/* Print addresses from InternetAddressList. */
\r
243 > +/* Print or prepare for printing addresses from InternetAddressList. */
\r
245 > process_address_list (const search_context_t *ctx,
\r
246 > InternetAddressList *list)
\r
247 > @@ -319,17 +337,21 @@ process_address_list (const search_context_t *ctx,
\r
248 > mailbox_t mbx =3D {
\r
249 > .name =3D internet_address_get_name (address),
\r
250 > .addr =3D internet_address_mailbox_get_addr (mailbox),
\r
254 > if (is_duplicate (ctx, mbx.name, mbx.addr))
\r
257 > + if (ctx->output & OUTPUT_COUNT)
\r
260 > print_mailbox (ctx, &mbx);
\r
265 > -/* Print addresses from a message header. */
\r
266 > +/* Print or prepare for printing addresses from a message header. */
\r
268 > process_address_header (const search_context_t *ctx, const char *value)
\r
270 > @@ -353,6 +375,15 @@ _my_talloc_free_for_g_hash (void *ptr)
\r
271 > talloc_free (ptr);
\r
275 > +print_hash_value (unused (gpointer key), gpointer value, gpointer user_d=
\r
278 > + const mailbox_t *mailbox =3D value;
\r
279 > + search_context_t *ctx =3D user_data;
\r
281 > + print_mailbox (ctx, mailbox);
\r
285 > _count_filenames (notmuch_message_t *message)
\r
287 > @@ -448,6 +479,9 @@ do_search_messages (search_context_t *ctx)
\r
288 > notmuch_message_destroy (message);
\r
291 > + if (ctx->addresses && ctx->output & OUTPUT_COUNT)
\r
292 > + g_hash_table_foreach (ctx->addresses, print_hash_value, ctx);
\r
294 > notmuch_messages_destroy (messages);
\r
296 > format->end (format);
\r
297 > @@ -685,6 +719,7 @@ notmuch_address_command (notmuch_config_t *config, in=
\r
298 t argc, char *argv[])
\r
299 > { NOTMUCH_OPT_KEYWORD_FLAGS, &ctx->output, "output", 'o',
\r
300 > (notmuch_keyword_t []){ { "sender", OUTPUT_SENDER },
\r
301 > { "recipients", OUTPUT_RECIPIENTS },
\r
302 > + { "count", OUTPUT_COUNT },
\r
304 > { NOTMUCH_OPT_INHERIT, &common_options, NULL, 0, 0 },
\r
305 > { 0, 0, 0, 0, 0 }
\r
306 > @@ -702,7 +737,7 @@ notmuch_address_command (notmuch_config_t *config, in=
\r
307 t argc, char *argv[])
\r
308 > return EXIT_FAILURE;
\r
310 > ctx->addresses =3D g_hash_table_new_full (g_str_hash, g_str_equal,
\r
311 > - _my_talloc_free_for_g_hash, NULL);
\r
312 > + _my_talloc_free_for_g_hash, _my_talloc_free_for_g_hash);
\r
314 > ret =3D do_search_messages (ctx);
\r
316 > diff --git a/test/T095-address.sh b/test/T095-address.sh
\r
317 > index 8a256d2..92e17b0 100755
\r
318 > --- a/test/T095-address.sh
\r
319 > +++ b/test/T095-address.sh
\r
320 > @@ -96,5 +96,53 @@ notmuch address --output=3Dsender --output=3Drecipient=
\r
322 > # Use EXPECTED from previous subtest
\r
323 > test_expect_equal_file OUTPUT EXPECTED
\r
325 > +test_begin_subtest "--output=3Dsender --output=3Dcount"
\r
326 > +notmuch address --output=3Dsender --output=3Dcount '*' | sort -n >OUTPUT
\r
327 > +cat <<EOF >EXPECTED
\r
328 > +1 Adrian Perez de Castro <aperez@igalia.com>
\r
329 > +1 Aron Griffis <agriffis@n01se.net>
\r
330 > +1 Chris Wilson <chris@chris-wilson.co.uk>
\r
331 > +1 Fran=C3=A7ois Boulogne <boulogne.f@gmail.com>
\r
332 > +1 Ingmar Vanhassel <ingmar@exherbo.org>
\r
333 > +1 Israel Herraiz <isra@herraiz.org>
\r
334 > +1 Olivier Berger <olivier.berger@it-sudparis.eu>
\r
335 > +1 Rolland Santimano <rollandsantimano@yahoo.com>
\r
336 > +2 Alex Botero-Lowry <alex.boterolowry@gmail.com>
\r
337 > +2 Jjgod Jiang <gzjjgod@gmail.com>
\r
338 > +3 Stewart Smith <stewart@flamingspork.com>
\r
339 > +4 Alexander Botero-Lowry <alex.boterolowry@gmail.com>
\r
340 > +4 Jan Janak <jan@ryngle.com>
\r
341 > +5 Lars Kellogg-Stedman <lars@seas.harvard.edu>
\r
342 > +5 Mikhail Gusarov <dottedmag@dottedmag.net>
\r
343 > +7 Keith Packard <keithp@keithp.com>
\r
344 > +12 Carl Worth <cworth@cworth.org>
\r
346 > +test_expect_equal_file OUTPUT EXPECTED
\r
348 > +test_begin_subtest "--output=3Dsender --output=3Dcount --format=3Djson"
\r
349 > +# Since the iteration order of GHashTable is not specified, we
\r
350 > +# preprocess and sort the results to keep the order stable here.
\r
351 > +notmuch address --output=3Dsender --output=3Dcount --format=3Djson '*' |=
\r
353 > + sed -e 's/^\[//' -e 's/]$//' -e 's/,$//' | sort >OUTPUT
\r
354 > +cat <<EOF >EXPECTED
\r
355 > +{"name": "Adrian Perez de Castro", "address": "aperez@igalia.com", "name=
\r
356 -addr": "Adrian Perez de Castro <aperez@igalia.com>", "count": 1}
\r
357 > +{"name": "Alex Botero-Lowry", "address": "alex.boterolowry@gmail.com", "=
\r
358 name-addr": "Alex Botero-Lowry <alex.boterolowry@gmail.com>", "count": 2}
\r
359 > +{"name": "Alexander Botero-Lowry", "address": "alex.boterolowry@gmail.co=
\r
360 m", "name-addr": "Alexander Botero-Lowry <alex.boterolowry@gmail.com>", "co=
\r
362 > +{"name": "Aron Griffis", "address": "agriffis@n01se.net", "name-addr": "=
\r
363 Aron Griffis <agriffis@n01se.net>", "count": 1}
\r
364 > +{"name": "Carl Worth", "address": "cworth@cworth.org", "name-addr": "Car=
\r
365 l Worth <cworth@cworth.org>", "count": 12}
\r
366 > +{"name": "Chris Wilson", "address": "chris@chris-wilson.co.uk", "name-ad=
\r
367 dr": "Chris Wilson <chris@chris-wilson.co.uk>", "count": 1}
\r
368 > +{"name": "Fran=C3=A7ois Boulogne", "address": "boulogne.f@gmail.com", "n=
\r
369 ame-addr": "Fran=C3=A7ois Boulogne <boulogne.f@gmail.com>", "count": 1}
\r
370 > +{"name": "Ingmar Vanhassel", "address": "ingmar@exherbo.org", "name-addr=
\r
371 ": "Ingmar Vanhassel <ingmar@exherbo.org>", "count": 1}
\r
372 > +{"name": "Israel Herraiz", "address": "isra@herraiz.org", "name-addr": "=
\r
373 Israel Herraiz <isra@herraiz.org>", "count": 1}
\r
374 > +{"name": "Jan Janak", "address": "jan@ryngle.com", "name-addr": "Jan Jan=
\r
375 ak <jan@ryngle.com>", "count": 4}
\r
376 > +{"name": "Jjgod Jiang", "address": "gzjjgod@gmail.com", "name-addr": "Jj=
\r
377 god Jiang <gzjjgod@gmail.com>", "count": 2}
\r
378 > +{"name": "Keith Packard", "address": "keithp@keithp.com", "name-addr": "=
\r
379 Keith Packard <keithp@keithp.com>", "count": 7}
\r
380 > +{"name": "Lars Kellogg-Stedman", "address": "lars@seas.harvard.edu", "na=
\r
381 me-addr": "Lars Kellogg-Stedman <lars@seas.harvard.edu>", "count": 5}
\r
382 > +{"name": "Mikhail Gusarov", "address": "dottedmag@dottedmag.net", "name-=
\r
383 addr": "Mikhail Gusarov <dottedmag@dottedmag.net>", "count": 5}
\r
384 > +{"name": "Olivier Berger", "address": "olivier.berger@it-sudparis.eu", "=
\r
385 name-addr": "Olivier Berger <olivier.berger@it-sudparis.eu>", "count": 1}
\r
386 > +{"name": "Rolland Santimano", "address": "rollandsantimano@yahoo.com", "=
\r
387 name-addr": "Rolland Santimano <rollandsantimano@yahoo.com>", "count": 1}
\r
388 > +{"name": "Stewart Smith", "address": "stewart@flamingspork.com", "name-a=
\r
389 ddr": "Stewart Smith <stewart@flamingspork.com>", "count": 3}
\r
391 > +test_expect_equal_file OUTPUT EXPECTED
\r
397 > _______________________________________________
\r
398 > notmuch mailing list
\r
399 > notmuch@notmuchmail.org
\r
400 > http://notmuchmail.org/mailman/listinfo/notmuch
\r