[PATCH] cli: add --output=address-{from, to, all} to notmuch search

2014-09-20 Thread Michal Sojka
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

2014-09-19 Thread David Bremner
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

2014-09-19 Thread David Bremner
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

2014-09-06 Thread Jani Nikula
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

2014-09-06 Thread Mark Walters

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

2014-09-06 Thread Jani Nikula
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

2014-09-06 Thread Jani Nikula
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

2014-09-06 Thread Jani Nikula
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

2014-09-06 Thread Jani Nikula
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

2014-09-06 Thread Mark Walters

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