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