[PATCH] cli: add --output=address-{from, to, all} to notmuch search
On Fri, Sep 19 2014, David Bremner wrote: > Jani Nikula writes: > >> +if (name && *name) >> +full_address = talloc_asprintf (NULL, "%s <%s>", name, addr); >> +else >> +full_address = talloc_asprintf (NULL, "<%s>", addr > > Is there some reason not to use sprinter as a talloc context here? > >> + >> +if (!full_address) >> +break; > > Is the error here out of memory? Maybe an error message would be a good > idea. > > > Obviously the docs need to be updated as well, and ideally the tests. I > think Jani was hinting that he didn't want to be the person to do > that. Any volunteers? Yes, I'll look at that. It will probably take me a few days. -Michal
[PATCH] cli: add --output=address-{from,to,all} to notmuch search
Jani Nikula writes: > + if (name && *name) > + full_address = talloc_asprintf (NULL, "%s <%s>", name, addr); > + else > + full_address = talloc_asprintf (NULL, "<%s>", addr Is there some reason not to use sprinter as a talloc context here? > + > + if (!full_address) > + break; Is the error here out of memory? Maybe an error message would be a good idea. Obviously the docs need to be updated as well, and ideally the tests. I think Jani was hinting that he didn't want to be the person to do that. Any volunteers? d
Re: [PATCH] cli: add --output=address-{from,to,all} to notmuch search
Jani Nikula j...@nikula.org writes: + if (name *name) + full_address = talloc_asprintf (NULL, %s %s, name, addr); + else + full_address = talloc_asprintf (NULL, %s, addr Is there some reason not to use sprinter as a talloc context here? + + if (!full_address) + break; Is the error here out of memory? Maybe an error message would be a good idea. Obviously the docs need to be updated as well, and ideally the tests. I think Jani was hinting that he didn't want to be the person to do that. Any volunteers? d ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH] cli: add --output=address-{from,to,all} to notmuch search
address-from prints reply-to or from, address-to prints to, cc, and bcc, and address-all prints all of them. --- notmuch-search.c | 109 ++- 1 file changed, 100 insertions(+), 9 deletions(-) diff --git a/notmuch-search.c b/notmuch-search.c index bc9be4593ecc..e7cf3d2a0fdf 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -23,11 +23,14 @@ #include "string-util.h" typedef enum { -OUTPUT_SUMMARY, -OUTPUT_THREADS, -OUTPUT_MESSAGES, -OUTPUT_FILES, -OUTPUT_TAGS +OUTPUT_SUMMARY = 1 << 0, +OUTPUT_THREADS = 1 << 1, +OUTPUT_MESSAGES= 1 << 2, +OUTPUT_FILES = 1 << 3, +OUTPUT_TAGS= 1 << 4, +OUTPUT_SENDER = 1 << 5, +OUTPUT_RECIPIENTS = 1 << 6, +OUTPUT_ADDRESSES = OUTPUT_SENDER | OUTPUT_RECIPIENTS, } output_t; /* Return two stable query strings that identify exactly the matched @@ -214,6 +217,66 @@ do_search_threads (sprinter_t *format, return 0; } +static void +print_address_list (sprinter_t *format, InternetAddressList *list) +{ +InternetAddress *address; +int i; + +for (i = 0; i < internet_address_list_length (list); i++) { + address = internet_address_list_get_address (list, i); + if (INTERNET_ADDRESS_IS_GROUP (address)) { + InternetAddressGroup *group; + InternetAddressList *group_list; + + group = INTERNET_ADDRESS_GROUP (address); + group_list = internet_address_group_get_members (group); + if (group_list == NULL) + continue; + + print_address_list (format, group_list); + } else { + InternetAddressMailbox *mailbox; + const char *name; + const char *addr; + char *full_address; + + mailbox = INTERNET_ADDRESS_MAILBOX (address); + + name = internet_address_get_name (address); + addr = internet_address_mailbox_get_addr (mailbox); + + if (name && *name) + full_address = talloc_asprintf (NULL, "%s <%s>", name, addr); + else + full_address = talloc_asprintf (NULL, "<%s>", addr); + + if (!full_address) + break; + + format->string (format, full_address); + format->separator (format); + + talloc_free (full_address); + } +} +} + +static void +print_address_string (sprinter_t *format, const char *recipients) +{ +InternetAddressList *list; + +if (recipients == NULL) + return; + +list = internet_address_list_parse_string (recipients); +if (list == NULL) + return; + +print_address_list (format, list); +} + static int do_search_messages (sprinter_t *format, notmuch_query_t *query, @@ -264,11 +327,29 @@ do_search_messages (sprinter_t *format, notmuch_filenames_destroy( filenames ); - } else { /* output == OUTPUT_MESSAGES */ + } else if (output == OUTPUT_MESSAGES) { format->set_prefix (format, "id"); format->string (format, notmuch_message_get_message_id (message)); format->separator (format); + } else { + if (output & OUTPUT_SENDER) { + const char *addrs; + + addrs = notmuch_message_get_header (message, "from"); + print_address_string (format, addrs); + } + + if (output & OUTPUT_RECIPIENTS) { + const char *hdrs[] = { "to", "cc", "bcc" }; + const char *addrs; + size_t j; + + for (j = 0; j < ARRAY_SIZE (hdrs); j++) { + addrs = notmuch_message_get_header (message, hdrs[j]); + print_address_string (format, addrs); + } + } } notmuch_message_destroy (message); @@ -338,7 +419,7 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST; sprinter_t *format = NULL; int opt_index, ret; -output_t output = OUTPUT_SUMMARY; +output_t output = 0; int offset = 0; int limit = -1; /* unlimited */ notmuch_exclude_t exclude = NOTMUCH_EXCLUDE_TRUE; @@ -364,10 +445,12 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) { "text0", NOTMUCH_FORMAT_TEXT0 }, { 0, 0 } } }, { NOTMUCH_OPT_INT, _format_version, "format-version", 0, 0 }, - { NOTMUCH_OPT_KEYWORD, , "output", 'o', + { NOTMUCH_OPT_KEYWORD_FLAGS, , "output", 'o', (notmuch_keyword_t []){ { "summary", OUTPUT_SUMMARY }, { "threads", OUTPUT_THREADS }, { "messages", OUTPUT_MESSAGES }, + { "sender", OUTPUT_SENDER }, + { "recipients", OUTPUT_RECIPIENTS },
[PATCH] cli: add --output=address-{from, to, all} to notmuch search
On Sat, 06 Sep 2014, Jani Nikula wrote: > address-from prints reply-to or from, address-to prints to, cc, and > bcc, and address-all prints all of them. This looks good to me. Obviously needs the new commit message. I think we should think about the deduplication possibilities but that can be added later. My timings suggest that there is a 20 times speed up in using this with --output=sender over calling notmuch show --body=false --entire-thread=false. If you want the to,cc then this version is only twice as fast as the notmuch show version. (All the above are with a hot cache: I expect bigger improvements with a cold cache). So this could well speed up dme's address completion patch id:1409921969-65129-1-git-send-email-dme at dme.org by a factor of 20. (The nevermore variants will not get such a big gain as they look at to/cc rather than from) Best wishes Mark > --- > notmuch-search.c | 109 > ++- > 1 file changed, 100 insertions(+), 9 deletions(-) > > diff --git a/notmuch-search.c b/notmuch-search.c > index bc9be4593ecc..e7cf3d2a0fdf 100644 > --- a/notmuch-search.c > +++ b/notmuch-search.c > @@ -23,11 +23,14 @@ > #include "string-util.h" > > typedef enum { > -OUTPUT_SUMMARY, > -OUTPUT_THREADS, > -OUTPUT_MESSAGES, > -OUTPUT_FILES, > -OUTPUT_TAGS > +OUTPUT_SUMMARY = 1 << 0, > +OUTPUT_THREADS = 1 << 1, > +OUTPUT_MESSAGES = 1 << 2, > +OUTPUT_FILES = 1 << 3, > +OUTPUT_TAGS = 1 << 4, > +OUTPUT_SENDER= 1 << 5, > +OUTPUT_RECIPIENTS= 1 << 6, > +OUTPUT_ADDRESSES = OUTPUT_SENDER | OUTPUT_RECIPIENTS, > } output_t; > > /* Return two stable query strings that identify exactly the matched > @@ -214,6 +217,66 @@ do_search_threads (sprinter_t *format, > return 0; > } > > +static void > +print_address_list (sprinter_t *format, InternetAddressList *list) > +{ > +InternetAddress *address; > +int i; > + > +for (i = 0; i < internet_address_list_length (list); i++) { > + address = internet_address_list_get_address (list, i); > + if (INTERNET_ADDRESS_IS_GROUP (address)) { > + InternetAddressGroup *group; > + InternetAddressList *group_list; > + > + group = INTERNET_ADDRESS_GROUP (address); > + group_list = internet_address_group_get_members (group); > + if (group_list == NULL) > + continue; > + > + print_address_list (format, group_list); > + } else { > + InternetAddressMailbox *mailbox; > + const char *name; > + const char *addr; > + char *full_address; > + > + mailbox = INTERNET_ADDRESS_MAILBOX (address); > + > + name = internet_address_get_name (address); > + addr = internet_address_mailbox_get_addr (mailbox); > + > + if (name && *name) > + full_address = talloc_asprintf (NULL, "%s <%s>", name, addr); > + else > + full_address = talloc_asprintf (NULL, "<%s>", addr); > + > + if (!full_address) > + break; > + > + format->string (format, full_address); > + format->separator (format); > + > + talloc_free (full_address); > + } > +} > +} > + > +static void > +print_address_string (sprinter_t *format, const char *recipients) > +{ > +InternetAddressList *list; > + > +if (recipients == NULL) > + return; > + > +list = internet_address_list_parse_string (recipients); > +if (list == NULL) > + return; > + > +print_address_list (format, list); > +} > + > static int > do_search_messages (sprinter_t *format, > notmuch_query_t *query, > @@ -264,11 +327,29 @@ do_search_messages (sprinter_t *format, > > notmuch_filenames_destroy( filenames ); > > - } else { /* output == OUTPUT_MESSAGES */ > + } else if (output == OUTPUT_MESSAGES) { > format->set_prefix (format, "id"); > format->string (format, > notmuch_message_get_message_id (message)); > format->separator (format); > + } else { > + if (output & OUTPUT_SENDER) { > + const char *addrs; > + > + addrs = notmuch_message_get_header (message, "from"); > + print_address_string (format, addrs); > + } > + > + if (output & OUTPUT_RECIPIENTS) { > + const char *hdrs[] = { "to", "cc", "bcc" }; > + const char *addrs; > + size_t j; > + > + for (j = 0; j < ARRAY_SIZE (hdrs); j++) { > + addrs = notmuch_message_get_header (message, hdrs[j]); > + print_address_string (format, addrs); > + } > + } > } > > notmuch_message_destroy (message); > @@ -338,7 +419,7 @@ notmuch_search_command (notmuch_config_t *config, int > argc, char *argv[]) > notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST; > sprinter_t
[PATCH] cli: add --output=address-{from,to,all} to notmuch search
address-from prints reply-to or from, address-to prints to, cc, and bcc, and address-all prints all of them. --- Mark, David - I wrote most of this almost two years ago, but wasn't really happy with it. There's address deduplication, but for large result sets that might use lots of memory. Maybe the --duplicate option could be overloaded for doing or not doing deduplication. I'd like to have some way of picking the prettiest (that's subjective too) name part to go with the address, now it's just the first encountered. And so on. But maybe this will be useful for you, and you can pick some ideas. I won't have the time to do much on this. Cheers, Jani. --- notmuch-search.c | 114 ++- 1 file changed, 113 insertions(+), 1 deletion(-) diff --git a/notmuch-search.c b/notmuch-search.c index bc9be4593ecc..33da90eaceec 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -26,6 +26,9 @@ typedef enum { OUTPUT_SUMMARY, OUTPUT_THREADS, OUTPUT_MESSAGES, +OUTPUT_ADDRESS_FROM, +OUTPUT_ADDRESS_TO, +OUTPUT_ADDRESS_ALL, OUTPUT_FILES, OUTPUT_TAGS } output_t; @@ -214,6 +217,78 @@ do_search_threads (sprinter_t *format, return 0; } +static void +print_address_list (sprinter_t *format, GHashTable *addrs, + InternetAddressList *list) +{ +InternetAddress *address; +int i; + +for (i = 0; i < internet_address_list_length (list); i++) { + address = internet_address_list_get_address (list, i); + if (INTERNET_ADDRESS_IS_GROUP (address)) { + InternetAddressGroup *group; + InternetAddressList *group_list; + + group = INTERNET_ADDRESS_GROUP (address); + group_list = internet_address_group_get_members (group); + if (group_list == NULL) + continue; + + print_address_list (format, addrs, group_list); + } else { + InternetAddressMailbox *mailbox; + const char *name; + const char *addr; + char *full_address; + + mailbox = INTERNET_ADDRESS_MAILBOX (address); + + name = internet_address_get_name (address); + addr = internet_address_mailbox_get_addr (mailbox); + + if (g_hash_table_lookup_extended (addrs, addr, NULL, NULL)) + continue; + + g_hash_table_insert (addrs, talloc_strdup (NULL, addr), NULL); + + if (name && *name) + full_address = talloc_asprintf (NULL, "%s <%s>", name, addr); + else + full_address = talloc_asprintf (NULL, "<%s>", addr); + + if (!full_address) + break; + + format->string (format, full_address); + format->separator (format); + + talloc_free (full_address); + } +} +} + +static void +print_address_string (sprinter_t *format, GHashTable *addrs, const char *recipients) +{ +InternetAddressList *list; + +if (recipients == NULL) + return; + +list = internet_address_list_parse_string (recipients); +if (list == NULL) + return; + +print_address_list (format, addrs, list); +} + +static void +_my_talloc_free_for_g_hash (void *ptr) +{ +talloc_free (ptr); +} + static int do_search_messages (sprinter_t *format, notmuch_query_t *query, @@ -225,8 +300,14 @@ do_search_messages (sprinter_t *format, notmuch_message_t *message; notmuch_messages_t *messages; notmuch_filenames_t *filenames; +GHashTable *addresses = NULL; int i; +if (output == OUTPUT_ADDRESS_FROM || output == OUTPUT_ADDRESS_TO || + output == OUTPUT_ADDRESS_ALL) + addresses = g_hash_table_new_full (g_str_hash, g_str_equal, + _my_talloc_free_for_g_hash, NULL); + if (offset < 0) { offset += notmuch_query_count_messages (query); if (offset < 0) @@ -264,16 +345,41 @@ do_search_messages (sprinter_t *format, notmuch_filenames_destroy( filenames ); - } else { /* output == OUTPUT_MESSAGES */ + } else if (output == OUTPUT_MESSAGES) { format->set_prefix (format, "id"); format->string (format, notmuch_message_get_message_id (message)); format->separator (format); + } else { + if (output == OUTPUT_ADDRESS_FROM || output == OUTPUT_ADDRESS_ALL) { + const char *addrs; + + addrs = notmuch_message_get_header (message, "reply-to"); + + if (addrs == NULL || *addrs == '\0') + addrs = notmuch_message_get_header (message, "from"); + + print_address_string (format, addresses, addrs); + } + + if (output == OUTPUT_ADDRESS_TO || output == OUTPUT_ADDRESS_ALL) { + const char *hdrs[] = { "to", "cc", "bcc" }; + const char *addrs; + size_t j; + + for (j = 0; j <
[PATCH] cli: add --output=address-{from,to,all} to notmuch search
address-from prints reply-to or from, address-to prints to, cc, and bcc, and address-all prints all of them. --- Mark, David - I wrote most of this almost two years ago, but wasn't really happy with it. There's address deduplication, but for large result sets that might use lots of memory. Maybe the --duplicate option could be overloaded for doing or not doing deduplication. I'd like to have some way of picking the prettiest (that's subjective too) name part to go with the address, now it's just the first encountered. And so on. But maybe this will be useful for you, and you can pick some ideas. I won't have the time to do much on this. Cheers, Jani. --- notmuch-search.c | 114 ++- 1 file changed, 113 insertions(+), 1 deletion(-) diff --git a/notmuch-search.c b/notmuch-search.c index bc9be4593ecc..33da90eaceec 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -26,6 +26,9 @@ typedef enum { OUTPUT_SUMMARY, OUTPUT_THREADS, OUTPUT_MESSAGES, +OUTPUT_ADDRESS_FROM, +OUTPUT_ADDRESS_TO, +OUTPUT_ADDRESS_ALL, OUTPUT_FILES, OUTPUT_TAGS } output_t; @@ -214,6 +217,78 @@ do_search_threads (sprinter_t *format, return 0; } +static void +print_address_list (sprinter_t *format, GHashTable *addrs, + InternetAddressList *list) +{ +InternetAddress *address; +int i; + +for (i = 0; i internet_address_list_length (list); i++) { + address = internet_address_list_get_address (list, i); + if (INTERNET_ADDRESS_IS_GROUP (address)) { + InternetAddressGroup *group; + InternetAddressList *group_list; + + group = INTERNET_ADDRESS_GROUP (address); + group_list = internet_address_group_get_members (group); + if (group_list == NULL) + continue; + + print_address_list (format, addrs, group_list); + } else { + InternetAddressMailbox *mailbox; + const char *name; + const char *addr; + char *full_address; + + mailbox = INTERNET_ADDRESS_MAILBOX (address); + + name = internet_address_get_name (address); + addr = internet_address_mailbox_get_addr (mailbox); + + if (g_hash_table_lookup_extended (addrs, addr, NULL, NULL)) + continue; + + g_hash_table_insert (addrs, talloc_strdup (NULL, addr), NULL); + + if (name *name) + full_address = talloc_asprintf (NULL, %s %s, name, addr); + else + full_address = talloc_asprintf (NULL, %s, addr); + + if (!full_address) + break; + + format-string (format, full_address); + format-separator (format); + + talloc_free (full_address); + } +} +} + +static void +print_address_string (sprinter_t *format, GHashTable *addrs, const char *recipients) +{ +InternetAddressList *list; + +if (recipients == NULL) + return; + +list = internet_address_list_parse_string (recipients); +if (list == NULL) + return; + +print_address_list (format, addrs, list); +} + +static void +_my_talloc_free_for_g_hash (void *ptr) +{ +talloc_free (ptr); +} + static int do_search_messages (sprinter_t *format, notmuch_query_t *query, @@ -225,8 +300,14 @@ do_search_messages (sprinter_t *format, notmuch_message_t *message; notmuch_messages_t *messages; notmuch_filenames_t *filenames; +GHashTable *addresses = NULL; int i; +if (output == OUTPUT_ADDRESS_FROM || output == OUTPUT_ADDRESS_TO || + output == OUTPUT_ADDRESS_ALL) + addresses = g_hash_table_new_full (g_str_hash, g_str_equal, + _my_talloc_free_for_g_hash, NULL); + if (offset 0) { offset += notmuch_query_count_messages (query); if (offset 0) @@ -264,16 +345,41 @@ do_search_messages (sprinter_t *format, notmuch_filenames_destroy( filenames ); - } else { /* output == OUTPUT_MESSAGES */ + } else if (output == OUTPUT_MESSAGES) { format-set_prefix (format, id); format-string (format, notmuch_message_get_message_id (message)); format-separator (format); + } else { + if (output == OUTPUT_ADDRESS_FROM || output == OUTPUT_ADDRESS_ALL) { + const char *addrs; + + addrs = notmuch_message_get_header (message, reply-to); + + if (addrs == NULL || *addrs == '\0') + addrs = notmuch_message_get_header (message, from); + + print_address_string (format, addresses, addrs); + } + + if (output == OUTPUT_ADDRESS_TO || output == OUTPUT_ADDRESS_ALL) { + const char *hdrs[] = { to, cc, bcc }; + const char *addrs; + size_t j; + + for (j = 0; j ARRAY_SIZE (hdrs);
[PATCH] cli: add --output=address-{from,to,all} to notmuch search
address-from prints reply-to or from, address-to prints to, cc, and bcc, and address-all prints all of them. --- notmuch-search.c | 109 ++- 1 file changed, 100 insertions(+), 9 deletions(-) diff --git a/notmuch-search.c b/notmuch-search.c index bc9be4593ecc..e7cf3d2a0fdf 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -23,11 +23,14 @@ #include string-util.h typedef enum { -OUTPUT_SUMMARY, -OUTPUT_THREADS, -OUTPUT_MESSAGES, -OUTPUT_FILES, -OUTPUT_TAGS +OUTPUT_SUMMARY = 1 0, +OUTPUT_THREADS = 1 1, +OUTPUT_MESSAGES= 1 2, +OUTPUT_FILES = 1 3, +OUTPUT_TAGS= 1 4, +OUTPUT_SENDER = 1 5, +OUTPUT_RECIPIENTS = 1 6, +OUTPUT_ADDRESSES = OUTPUT_SENDER | OUTPUT_RECIPIENTS, } output_t; /* Return two stable query strings that identify exactly the matched @@ -214,6 +217,66 @@ do_search_threads (sprinter_t *format, return 0; } +static void +print_address_list (sprinter_t *format, InternetAddressList *list) +{ +InternetAddress *address; +int i; + +for (i = 0; i internet_address_list_length (list); i++) { + address = internet_address_list_get_address (list, i); + if (INTERNET_ADDRESS_IS_GROUP (address)) { + InternetAddressGroup *group; + InternetAddressList *group_list; + + group = INTERNET_ADDRESS_GROUP (address); + group_list = internet_address_group_get_members (group); + if (group_list == NULL) + continue; + + print_address_list (format, group_list); + } else { + InternetAddressMailbox *mailbox; + const char *name; + const char *addr; + char *full_address; + + mailbox = INTERNET_ADDRESS_MAILBOX (address); + + name = internet_address_get_name (address); + addr = internet_address_mailbox_get_addr (mailbox); + + if (name *name) + full_address = talloc_asprintf (NULL, %s %s, name, addr); + else + full_address = talloc_asprintf (NULL, %s, addr); + + if (!full_address) + break; + + format-string (format, full_address); + format-separator (format); + + talloc_free (full_address); + } +} +} + +static void +print_address_string (sprinter_t *format, const char *recipients) +{ +InternetAddressList *list; + +if (recipients == NULL) + return; + +list = internet_address_list_parse_string (recipients); +if (list == NULL) + return; + +print_address_list (format, list); +} + static int do_search_messages (sprinter_t *format, notmuch_query_t *query, @@ -264,11 +327,29 @@ do_search_messages (sprinter_t *format, notmuch_filenames_destroy( filenames ); - } else { /* output == OUTPUT_MESSAGES */ + } else if (output == OUTPUT_MESSAGES) { format-set_prefix (format, id); format-string (format, notmuch_message_get_message_id (message)); format-separator (format); + } else { + if (output OUTPUT_SENDER) { + const char *addrs; + + addrs = notmuch_message_get_header (message, from); + print_address_string (format, addrs); + } + + if (output OUTPUT_RECIPIENTS) { + const char *hdrs[] = { to, cc, bcc }; + const char *addrs; + size_t j; + + for (j = 0; j ARRAY_SIZE (hdrs); j++) { + addrs = notmuch_message_get_header (message, hdrs[j]); + print_address_string (format, addrs); + } + } } notmuch_message_destroy (message); @@ -338,7 +419,7 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST; sprinter_t *format = NULL; int opt_index, ret; -output_t output = OUTPUT_SUMMARY; +output_t output = 0; int offset = 0; int limit = -1; /* unlimited */ notmuch_exclude_t exclude = NOTMUCH_EXCLUDE_TRUE; @@ -364,10 +445,12 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) { text0, NOTMUCH_FORMAT_TEXT0 }, { 0, 0 } } }, { NOTMUCH_OPT_INT, notmuch_format_version, format-version, 0, 0 }, - { NOTMUCH_OPT_KEYWORD, output, output, 'o', + { NOTMUCH_OPT_KEYWORD_FLAGS, output, output, 'o', (notmuch_keyword_t []){ { summary, OUTPUT_SUMMARY }, { threads, OUTPUT_THREADS }, { messages, OUTPUT_MESSAGES }, + { sender, OUTPUT_SENDER }, + { recipients, OUTPUT_RECIPIENTS },
Re: [PATCH] cli: add --output=address-{from, to, all} to notmuch search
On Sat, 06 Sep 2014, Jani Nikula j...@nikula.org wrote: address-from prints reply-to or from, address-to prints to, cc, and bcc, and address-all prints all of them. *sigh* this was supposed to be: --- cli: add --output=sender and --output=recipients to notmuch search sender prints from, recipients prints to, cc, and bcc. --- I don't have the time for this, and I'm rushing too much... BR, Jani. --- notmuch-search.c | 109 ++- 1 file changed, 100 insertions(+), 9 deletions(-) diff --git a/notmuch-search.c b/notmuch-search.c index bc9be4593ecc..e7cf3d2a0fdf 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -23,11 +23,14 @@ #include string-util.h typedef enum { -OUTPUT_SUMMARY, -OUTPUT_THREADS, -OUTPUT_MESSAGES, -OUTPUT_FILES, -OUTPUT_TAGS +OUTPUT_SUMMARY = 1 0, +OUTPUT_THREADS = 1 1, +OUTPUT_MESSAGES = 1 2, +OUTPUT_FILES = 1 3, +OUTPUT_TAGS = 1 4, +OUTPUT_SENDER= 1 5, +OUTPUT_RECIPIENTS= 1 6, +OUTPUT_ADDRESSES = OUTPUT_SENDER | OUTPUT_RECIPIENTS, } output_t; /* Return two stable query strings that identify exactly the matched @@ -214,6 +217,66 @@ do_search_threads (sprinter_t *format, return 0; } +static void +print_address_list (sprinter_t *format, InternetAddressList *list) +{ +InternetAddress *address; +int i; + +for (i = 0; i internet_address_list_length (list); i++) { + address = internet_address_list_get_address (list, i); + if (INTERNET_ADDRESS_IS_GROUP (address)) { + InternetAddressGroup *group; + InternetAddressList *group_list; + + group = INTERNET_ADDRESS_GROUP (address); + group_list = internet_address_group_get_members (group); + if (group_list == NULL) + continue; + + print_address_list (format, group_list); + } else { + InternetAddressMailbox *mailbox; + const char *name; + const char *addr; + char *full_address; + + mailbox = INTERNET_ADDRESS_MAILBOX (address); + + name = internet_address_get_name (address); + addr = internet_address_mailbox_get_addr (mailbox); + + if (name *name) + full_address = talloc_asprintf (NULL, %s %s, name, addr); + else + full_address = talloc_asprintf (NULL, %s, addr); + + if (!full_address) + break; + + format-string (format, full_address); + format-separator (format); + + talloc_free (full_address); + } +} +} + +static void +print_address_string (sprinter_t *format, const char *recipients) +{ +InternetAddressList *list; + +if (recipients == NULL) + return; + +list = internet_address_list_parse_string (recipients); +if (list == NULL) + return; + +print_address_list (format, list); +} + static int do_search_messages (sprinter_t *format, notmuch_query_t *query, @@ -264,11 +327,29 @@ do_search_messages (sprinter_t *format, notmuch_filenames_destroy( filenames ); - } else { /* output == OUTPUT_MESSAGES */ + } else if (output == OUTPUT_MESSAGES) { format-set_prefix (format, id); format-string (format, notmuch_message_get_message_id (message)); format-separator (format); + } else { + if (output OUTPUT_SENDER) { + const char *addrs; + + addrs = notmuch_message_get_header (message, from); + print_address_string (format, addrs); + } + + if (output OUTPUT_RECIPIENTS) { + const char *hdrs[] = { to, cc, bcc }; + const char *addrs; + size_t j; + + for (j = 0; j ARRAY_SIZE (hdrs); j++) { + addrs = notmuch_message_get_header (message, hdrs[j]); + print_address_string (format, addrs); + } + } } notmuch_message_destroy (message); @@ -338,7 +419,7 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST; sprinter_t *format = NULL; int opt_index, ret; -output_t output = OUTPUT_SUMMARY; +output_t output = 0; int offset = 0; int limit = -1; /* unlimited */ notmuch_exclude_t exclude = NOTMUCH_EXCLUDE_TRUE; @@ -364,10 +445,12 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) { text0, NOTMUCH_FORMAT_TEXT0 }, { 0, 0 } } }, { NOTMUCH_OPT_INT, notmuch_format_version, format-version, 0, 0 }, - { NOTMUCH_OPT_KEYWORD, output, output, 'o', + { NOTMUCH_OPT_KEYWORD_FLAGS, output, output, 'o', (notmuch_keyword_t []){
Re: [PATCH] cli: add --output=address-{from, to, all} to notmuch search
On Sat, 06 Sep 2014, Jani Nikula j...@nikula.org wrote: address-from prints reply-to or from, address-to prints to, cc, and bcc, and address-all prints all of them. This looks good to me. Obviously needs the new commit message. I think we should think about the deduplication possibilities but that can be added later. My timings suggest that there is a 20 times speed up in using this with --output=sender over calling notmuch show --body=false --entire-thread=false. If you want the to,cc then this version is only twice as fast as the notmuch show version. (All the above are with a hot cache: I expect bigger improvements with a cold cache). So this could well speed up dme's address completion patch id:1409921969-65129-1-git-send-email-...@dme.org by a factor of 20. (The nevermore variants will not get such a big gain as they look at to/cc rather than from) Best wishes Mark --- notmuch-search.c | 109 ++- 1 file changed, 100 insertions(+), 9 deletions(-) diff --git a/notmuch-search.c b/notmuch-search.c index bc9be4593ecc..e7cf3d2a0fdf 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -23,11 +23,14 @@ #include string-util.h typedef enum { -OUTPUT_SUMMARY, -OUTPUT_THREADS, -OUTPUT_MESSAGES, -OUTPUT_FILES, -OUTPUT_TAGS +OUTPUT_SUMMARY = 1 0, +OUTPUT_THREADS = 1 1, +OUTPUT_MESSAGES = 1 2, +OUTPUT_FILES = 1 3, +OUTPUT_TAGS = 1 4, +OUTPUT_SENDER= 1 5, +OUTPUT_RECIPIENTS= 1 6, +OUTPUT_ADDRESSES = OUTPUT_SENDER | OUTPUT_RECIPIENTS, } output_t; /* Return two stable query strings that identify exactly the matched @@ -214,6 +217,66 @@ do_search_threads (sprinter_t *format, return 0; } +static void +print_address_list (sprinter_t *format, InternetAddressList *list) +{ +InternetAddress *address; +int i; + +for (i = 0; i internet_address_list_length (list); i++) { + address = internet_address_list_get_address (list, i); + if (INTERNET_ADDRESS_IS_GROUP (address)) { + InternetAddressGroup *group; + InternetAddressList *group_list; + + group = INTERNET_ADDRESS_GROUP (address); + group_list = internet_address_group_get_members (group); + if (group_list == NULL) + continue; + + print_address_list (format, group_list); + } else { + InternetAddressMailbox *mailbox; + const char *name; + const char *addr; + char *full_address; + + mailbox = INTERNET_ADDRESS_MAILBOX (address); + + name = internet_address_get_name (address); + addr = internet_address_mailbox_get_addr (mailbox); + + if (name *name) + full_address = talloc_asprintf (NULL, %s %s, name, addr); + else + full_address = talloc_asprintf (NULL, %s, addr); + + if (!full_address) + break; + + format-string (format, full_address); + format-separator (format); + + talloc_free (full_address); + } +} +} + +static void +print_address_string (sprinter_t *format, const char *recipients) +{ +InternetAddressList *list; + +if (recipients == NULL) + return; + +list = internet_address_list_parse_string (recipients); +if (list == NULL) + return; + +print_address_list (format, list); +} + static int do_search_messages (sprinter_t *format, notmuch_query_t *query, @@ -264,11 +327,29 @@ do_search_messages (sprinter_t *format, notmuch_filenames_destroy( filenames ); - } else { /* output == OUTPUT_MESSAGES */ + } else if (output == OUTPUT_MESSAGES) { format-set_prefix (format, id); format-string (format, notmuch_message_get_message_id (message)); format-separator (format); + } else { + if (output OUTPUT_SENDER) { + const char *addrs; + + addrs = notmuch_message_get_header (message, from); + print_address_string (format, addrs); + } + + if (output OUTPUT_RECIPIENTS) { + const char *hdrs[] = { to, cc, bcc }; + const char *addrs; + size_t j; + + for (j = 0; j ARRAY_SIZE (hdrs); j++) { + addrs = notmuch_message_get_header (message, hdrs[j]); + print_address_string (format, addrs); + } + } } notmuch_message_destroy (message); @@ -338,7 +419,7 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[]) notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST; sprinter_t *format = NULL; int opt_index, ret; -output_t output = OUTPUT_SUMMARY; +output_t output = 0; int offset = 0; int limit = -1; /* unlimited