From e6b34728fdec418dff4e2205fb4de3bf4b79ad5b Mon Sep 17 00:00:00 2001 From: Tomi Ollila Date: Fri, 24 Oct 2014 12:38:18 +0300 Subject: [PATCH] Re: [PATCH v3 3/4] cli: Extend the search command for --output={sender, recipients} --- 33/25d0100606c09cca99d8d0be95e339eb61a3fb | 368 ++++++++++++++++++++++ 1 file changed, 368 insertions(+) create mode 100644 33/25d0100606c09cca99d8d0be95e339eb61a3fb diff --git a/33/25d0100606c09cca99d8d0be95e339eb61a3fb b/33/25d0100606c09cca99d8d0be95e339eb61a3fb new file mode 100644 index 000000000..8f61e7f0a --- /dev/null +++ b/33/25d0100606c09cca99d8d0be95e339eb61a3fb @@ -0,0 +1,368 @@ +Return-Path: +X-Original-To: notmuch@notmuchmail.org +Delivered-To: notmuch@notmuchmail.org +Received: from localhost (localhost [127.0.0.1]) + by olra.theworths.org (Postfix) with ESMTP id 13E5E431FD8 + for ; Fri, 24 Oct 2014 02:38:50 -0700 (PDT) +X-Virus-Scanned: Debian amavisd-new at olra.theworths.org +X-Spam-Flag: NO +X-Spam-Score: 0 +X-Spam-Level: +X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none] + autolearn=disabled +Received: from olra.theworths.org ([127.0.0.1]) + by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id nJf74m1qpBbu for ; + Fri, 24 Oct 2014 02:38:41 -0700 (PDT) +Received: from guru.guru-group.fi (guru.guru-group.fi [46.183.73.34]) + by olra.theworths.org (Postfix) with ESMTP id A9723431FBD + for ; Fri, 24 Oct 2014 02:38:40 -0700 (PDT) +Received: from guru.guru-group.fi (localhost [IPv6:::1]) + by guru.guru-group.fi (Postfix) with ESMTP id 8F83110008C; + Fri, 24 Oct 2014 12:38:18 +0300 (EEST) +From: Tomi Ollila +To: Mark Walters , + Michal Sojka , notmuch@notmuchmail.org +Subject: Re: [PATCH v3 3/4] cli: Extend the search command + for --output={sender, recipients} +In-Reply-To: <87egtzazs8.fsf@qmul.ac.uk> +References: <87zjd51phx.fsf@steelpick.2x.cz> + <1413150093-8383-1-git-send-email-sojkam1@fel.cvut.cz> + <1413150093-8383-4-git-send-email-sojkam1@fel.cvut.cz> + <87egtzazs8.fsf@qmul.ac.uk> +User-Agent: Notmuch/0.18.1+130~ga61922f (http://notmuchmail.org) Emacs/24.3.1 + (x86_64-unknown-linux-gnu) +X-Face: HhBM'cA~ +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf-8 +Content-Transfer-Encoding: quoted-printable +X-BeenThere: notmuch@notmuchmail.org +X-Mailman-Version: 2.1.13 +Precedence: list +List-Id: "Use and development of the notmuch mail system." + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +X-List-Received-Date: Fri, 24 Oct 2014 09:38:50 -0000 + +On Thu, Oct 23 2014, Mark Walters wrote: + +> On Sun, 12 Oct 2014, Michal Sojka wrote: +>> The new outputs allow printing senders, recipients or both of matching +>> messages. The --output option is converted from "keyword" argument to +>> "flags" argument, which means that the user can use --output=3Dsender and +>> --output=3Drecipients simultaneously, to print both. Other combinations +>> produce an error. +>> +>> ... +>> +>> +static void +>> +print_address_list (const search_options_t *o, InternetAddressList *lis= +t) +>> +{ +>> + InternetAddress *address; +>> + int i; +>> + +>> + for (i =3D 0; i < internet_address_list_length (list); i++) { +>> + address =3D internet_address_list_get_address (list, i); +>> + if (INTERNET_ADDRESS_IS_GROUP (address)) { +>> + InternetAddressGroup *group; +>> + InternetAddressList *group_list; +>> + +>> + group =3D INTERNET_ADDRESS_GROUP (address); +>> + group_list =3D internet_address_group_get_members (group); +>> + if (group_list =3D=3D NULL) +>> + continue; +>> + +>> + print_address_list (o, group_list); +>> + } else { +>> + InternetAddressMailbox *mailbox; +>> + const char *name; +>> + const char *addr; +>> + char *full_address; +>> + +>> + mailbox =3D INTERNET_ADDRESS_MAILBOX (address); +>> + +>> + name =3D internet_address_get_name (address); +>> + addr =3D internet_address_mailbox_get_addr (mailbox); +>> + +>> + if (name && *name) +>> + full_address =3D talloc_asprintf (o->format, "%s <%s>", name, addr); +>> + else +>> + full_address =3D talloc_strdup (o->format, addr); +>> + +>> + if (!full_address) { +>> + fprintf (stderr, "Error: out of memory\n"); +>> + break; +>> + } +>> + o->format->string (o->format, full_address); +>> + o->format->separator (o->format); +>> + +>> + talloc_free (full_address); +> +> Thinking about this some more how about printing the name and address as +> a structured pair/map (at least for all cases except text/text0 output): +> something like (in JSON) +> [name: "John Doe" address: "john.doe@example.com"] +> +> It seems wrong to me to go to the effort of separating them in the C and +> then combining them in the output. +> +> This could also help with the questions about uniqueness. If the client +> can get the data ready parsed into name/address then it can deal with +> much of the uniqueness itself. + +In that case client can also filter based on some substring, reducing the +memory requirements... + +> +> My preference would be for the default to print one line for each +> distinct full_address, and then any filter-by options to refine from +> there. + +Hmm, now I cannot decide whether this or just print out all addresses of +messages, or do this distinct full_address output -- it looks like all +other --output options prints unique lines, but there is potential of=20 +quite a lot of memory usage there... + +... probably the memory usage is not problem there, OOM-killer eventually +does it's job if necessary (!) (but machine may be slow (and trashing) for +a while (just thinking out loud)) + +(!) but could we have general filter option for search to drop data before +it is even considered for caching! -- maybe later ? + + +> One other advantage of structuring the output is that it is extensible: +> for example, at some later stage, we could include a "count" in the map +> allowing the client can pick the most popular variant. + +, and in this case notmuch cannot print any output until the full address +list is gathered... :D + +> +> Best wishes +> +> Mark + +Tomi + +> +> +> +> +>> + } +>> + } +>> +} +>> + +>> +static void +>> +print_address_string (const search_options_t *o, const char *recipients) +>> +{ +>> + InternetAddressList *list; +>> + +>> + if (recipients =3D=3D NULL) +>> + return; +>> + +>> + list =3D internet_address_list_parse_string (recipients); +>> + if (list =3D=3D NULL) +>> + return; +>> + +>> + print_address_list (o, list); +>> +} +>> + +>> static int +>> do_search_messages (search_options_t *o) +>> { +>> @@ -266,11 +330,29 @@ do_search_messages (search_options_t *o) +>>=20=20=09=20=20=20=20 +>> notmuch_filenames_destroy( filenames ); +>>=20=20 +>> - } else { /* output =3D=3D OUTPUT_MESSAGES */ +>> + } else if (o->output =3D=3D OUTPUT_MESSAGES) { +>> format->set_prefix (format, "id"); +>> format->string (format, +>> notmuch_message_get_message_id (message)); +>> format->separator (format); +>> + } else { +>> + if (o->output & OUTPUT_SENDER) { +>> + const char *addrs; +>> + +>> + addrs =3D notmuch_message_get_header (message, "from"); +>> + print_address_string (o, addrs); +>> + } +>> + +>> + if (o->output & OUTPUT_RECIPIENTS) { +>> + const char *hdrs[] =3D { "to", "cc", "bcc" }; +>> + const char *addrs; +>> + size_t j; +>> + +>> + for (j =3D 0; j < ARRAY_SIZE (hdrs); j++) { +>> + addrs =3D notmuch_message_get_header (message, hdrs[j]); +>> + print_address_string (o, addrs); +>> + } +>> + } +>> } +>>=20=20 +>> notmuch_message_destroy (message); +>> @@ -337,7 +419,7 @@ notmuch_search_command (notmuch_config_t *config, in= +t argc, char *argv[]) +>> notmuch_database_t *notmuch; +>> search_options_t o =3D { +>> .sort =3D NOTMUCH_SORT_NEWEST_FIRST, +>> - .output =3D OUTPUT_SUMMARY, +>> + .output =3D 0, +>> .offset =3D 0, +>> .limit =3D -1, /* unlimited */ +>> .dupe =3D -1, +>> @@ -366,10 +448,12 @@ notmuch_search_command (notmuch_config_t *config, = +int argc, char *argv[]) +>> { "text0", NOTMUCH_FORMAT_TEXT0 }, +>> { 0, 0 } } }, +>> { NOTMUCH_OPT_INT, ¬much_format_version, "format-version", 0, 0 }, +>> - { NOTMUCH_OPT_KEYWORD, &o.output, "output", 'o', +>> + { NOTMUCH_OPT_KEYWORD_FLAGS, &o.output, "output", 'o', +>> (notmuch_keyword_t []){ { "summary", OUTPUT_SUMMARY }, +>> { "threads", OUTPUT_THREADS }, +>> { "messages", OUTPUT_MESSAGES }, +>> + { "sender", OUTPUT_SENDER }, +>> + { "recipients", OUTPUT_RECIPIENTS }, +>> { "files", OUTPUT_FILES }, +>> { "tags", OUTPUT_TAGS }, +>> { 0, 0 } } }, +>> @@ -389,6 +473,9 @@ notmuch_search_command (notmuch_config_t *config, in= +t argc, char *argv[]) +>> if (opt_index < 0) +>> return EXIT_FAILURE; +>>=20=20 +>> + if (! o.output) +>> + o.output =3D OUTPUT_SUMMARY; +>> + +>> switch (format_sel) { +>> case NOTMUCH_FORMAT_TEXT: +>> o.format =3D sprinter_text_create (config, stdout); +>> @@ -455,18 +542,23 @@ notmuch_search_command (notmuch_config_t *config, = +int argc, char *argv[]) +>> } +>>=20=20 +>> switch (o.output) { +>> - default: +>> case OUTPUT_SUMMARY: +>> case OUTPUT_THREADS: +>> ret =3D do_search_threads (&o); +>> break; +>> case OUTPUT_MESSAGES: +>> + case OUTPUT_SENDER: +>> + case OUTPUT_RECIPIENTS: +>> + case OUTPUT_ADDRESSES: +>> case OUTPUT_FILES: +>> ret =3D do_search_messages (&o); +>> break; +>> case OUTPUT_TAGS: +>> ret =3D do_search_tags (notmuch, o.format, o.query); +>> break; +>> + default: +>> + fprintf (stderr, "Error: the combination of outputs is not supported.\= +n"); +>> + ret =3D 1; +>> } +>>=20=20 +>> notmuch_query_destroy (o.query); +>> diff --git a/test/T090-search-output.sh b/test/T090-search-output.sh +>> index 947d572..e696c01 100755 +>> --- a/test/T090-search-output.sh +>> +++ b/test/T090-search-output.sh +>> @@ -387,6 +387,70 @@ cat <EXPECTED +>> EOF +>> test_expect_equal_file OUTPUT EXPECTED +>>=20=20 +>> +test_begin_subtest "--output=3Dsender" +>> +notmuch search --output=3Dsender '*' | sort | uniq --count >OUTPUT +>> +cat <EXPECTED +>> + 1 Adrian Perez de Castro +>> + 2 Alex Botero-Lowry +>> + 4 Alexander Botero-Lowry +>> + 1 Aron Griffis +>> + 12 Carl Worth +>> + 1 Chris Wilson +>> + 1 Fran=C3=A7ois Boulogne +>> + 1 Ingmar Vanhassel +>> + 1 Israel Herraiz +>> + 4 Jan Janak +>> + 2 Jjgod Jiang +>> + 7 Keith Packard +>> + 5 Lars Kellogg-Stedman +>> + 5 Mikhail Gusarov +>> + 1 Olivier Berger +>> + 1 Rolland Santimano +>> + 3 Stewart Smith +>> +EOF +>> +test_expect_equal_file OUTPUT EXPECTED +>> + +>> +test_begin_subtest "--output=3Drecipients" +>> +notmuch search --output=3Drecipients '*' | sort | uniq --count >OUTPUT +>> +cat <EXPECTED +>> + 1 Allan McRae +>> + 1 Discussion about the Arch User Repository (AUR) +>> + 1 Keith Packard +>> + 1 Mikhail Gusarov +>> + 2 notmuch +>> + 48 notmuch@notmuchmail.org +>> + 1 olivier.berger@it-sudparis.eu +>> +EOF +>> +test_expect_equal_file OUTPUT EXPECTED +>> + +>> +test_begin_subtest "--output=3Dsender --output=3Drecipients" +>> +notmuch search --output=3Dsender --output=3Drecipients '*' | sort | uni= +q --count >OUTPUT +>> +cat <EXPECTED +>> + 1 Adrian Perez de Castro +>> + 2 Alex Botero-Lowry +>> + 4 Alexander Botero-Lowry +>> + 1 Allan McRae +>> + 1 Aron Griffis +>> + 12 Carl Worth +>> + 1 Chris Wilson +>> + 1 Discussion about the Arch User Repository (AUR) +>> + 1 Fran=C3=A7ois Boulogne +>> + 1 Ingmar Vanhassel +>> + 1 Israel Herraiz +>> + 4 Jan Janak +>> + 2 Jjgod Jiang +>> + 8 Keith Packard +>> + 5 Lars Kellogg-Stedman +>> + 6 Mikhail Gusarov +>> + 1 Olivier Berger +>> + 1 Rolland Santimano +>> + 3 Stewart Smith +>> + 2 notmuch +>> + 48 notmuch@notmuchmail.org +>> + 1 olivier.berger@it-sudparis.eu +>> +EOF +>> +test_expect_equal_file OUTPUT EXPECTED +>> + +>> test_begin_subtest "sanitize output for quoted-printable line-breaks in= + author and subject" +>> add_message "[subject]=3D'two =3D?ISO-8859-1?Q?line=3D0A_subject?=3D +>> headers'" +>> --=20 +>> 2.1.1 +>> +>> _______________________________________________ +>> notmuch mailing list +>> notmuch@notmuchmail.org +>> http://notmuchmail.org/mailman/listinfo/notmuch +> _______________________________________________ +> notmuch mailing list +> notmuch@notmuchmail.org +> http://notmuchmail.org/mailman/listinfo/notmuch -- 2.26.2