[PATCH v6 6/7] cli: search: Add --output=count

Mark Walters markwalters1009 at gmail.com
Fri Oct 31 18:16:20 PDT 2014


On Fri, 31 Oct 2014, Michal Sojka <sojkam1 at fel.cvut.cz> wrote:
> This output can be used with --output=recipients or --output=sender
> and in addition to the addresses, it prints how many times was each
> address encountered during search.

Hi

I have a couple comments on this patch.

> ---
>  completion/notmuch-completion.bash |  2 +-
>  completion/notmuch-completion.zsh  |  2 +-
>  doc/man1/notmuch-search.rst        |  9 +++++--
>  notmuch-search.c                   | 51 ++++++++++++++++++++++++++++++++------
>  4 files changed, 52 insertions(+), 12 deletions(-)
>
> diff --git a/completion/notmuch-completion.bash b/completion/notmuch-completion.bash
> index cfbd389..39cd829 100644
> --- a/completion/notmuch-completion.bash
> +++ b/completion/notmuch-completion.bash
> @@ -294,7 +294,7 @@ _notmuch_search()
>  	    return
>  	    ;;
>  	--output)
> -	    COMPREPLY=( $( compgen -W "summary threads messages files tags sender recipients" -- "${cur}" ) )
> +	    COMPREPLY=( $( compgen -W "summary threads messages files tags sender recipients count" -- "${cur}" ) )
>  	    return
>  	    ;;
>  	--sort)
> diff --git a/completion/notmuch-completion.zsh b/completion/notmuch-completion.zsh
> index 3e52a00..d7e5a5e 100644
> --- a/completion/notmuch-completion.zsh
> +++ b/completion/notmuch-completion.zsh
> @@ -53,7 +53,7 @@ _notmuch_search()
>      '--max-threads=[display only the first x threads from the search results]:number of threads to show: ' \
>      '--first=[omit the first x threads from the search results]:number of threads to omit: ' \
>      '--sort=[sort results]:sorting:((newest-first\:"reverse chronological order" oldest-first\:"chronological order"))' \
> -    '--output=[select what to output]:output:((summary threads messages files tags sender recipients))'
> +    '--output=[select what to output]:output:((summary threads messages files tags sender recipients count))'
>  }
>  
>  _notmuch()
> diff --git a/doc/man1/notmuch-search.rst b/doc/man1/notmuch-search.rst
> index 42f17e4..ec89200 100644
> --- a/doc/man1/notmuch-search.rst
> +++ b/doc/man1/notmuch-search.rst
> @@ -96,9 +96,14 @@ Supported options for **search** include
>              Like **sender** but for addresses from *To*, *Cc* and
>  	    *Bcc* headers.
>  
> +	**count**
> +	    Can be used in combination with **sender** or
> +	    **recipients** to print the count of how many times was
> +	    the address encountered during search.
> +
>  	This option can be given multiple times to combine different
> -	outputs. Currently, this is only supported for **sender** and
> -	**recipients** outputs.
> +	outputs. Currently, this is only supported for **sender**,
> +	**recipients** and **count** outputs.

It might be worth saying that the results will be slower if count is
specified.

>      ``--sort=``\ (**newest-first**\ \|\ **oldest-first**)

I think sort works as expected if count is not specified, but does not
with count. Maybe count can be done by doing two passes? If it is
difficult it might be sufficient to just document that sort has no
effect.

Best wishes

Mark



>          This option can be used to present results in either
> diff --git a/notmuch-search.c b/notmuch-search.c
> index 43d42c6..4b39dfc 100644
> --- a/notmuch-search.c
> +++ b/notmuch-search.c
> @@ -30,9 +30,10 @@ typedef enum {
>      OUTPUT_TAGS		= 1 << 4,
>      OUTPUT_SENDER	= 1 << 5,
>      OUTPUT_RECIPIENTS	= 1 << 6,
> +    OUTPUT_COUNT	= 1 << 7,
>  } output_t;
>  
> -#define OUTPUT_ADDRESS_FLAGS (OUTPUT_SENDER | OUTPUT_RECIPIENTS)
> +#define OUTPUT_ADDRESS_FLAGS (OUTPUT_SENDER | OUTPUT_RECIPIENTS | OUTPUT_COUNT)
>  
>  typedef struct {
>      sprinter_t *format;
> @@ -47,6 +48,7 @@ typedef struct {
>  typedef struct {
>      const char *name;
>      const char *addr;
> +    int count;
>  } mailbox_t;
>  
>  /* Return two stable query strings that identify exactly the matched
> @@ -235,17 +237,24 @@ is_duplicate (const search_options_t *opt, GHashTable *addrs, const char *name,
>  {
>      notmuch_bool_t duplicate;
>      char *key;
> +    mailbox_t *mailbox;
>  
>      key = talloc_asprintf (opt->format, "%s <%s>", name, addr);
>      if (! key)
>  	return FALSE;
>  
> -    duplicate = g_hash_table_lookup_extended (addrs, key, NULL, NULL);
> +    duplicate = g_hash_table_lookup_extended (addrs, key, NULL, (gpointer)&mailbox);
>  
> -    if (! duplicate)
> -	g_hash_table_insert (addrs, key, NULL);
> -    else
> +    if (! duplicate) {
> +	mailbox = talloc (opt->format, mailbox_t);
> +	mailbox->name = talloc_strdup (mailbox, name);
> +	mailbox->addr = talloc_strdup (mailbox, addr);
> +	mailbox->count = 1;
> +	g_hash_table_insert (addrs, key, mailbox);
> +    } else {
> +	mailbox->count++;
>  	talloc_free (key);
> +    }
>  
>      return duplicate;
>  }
> @@ -255,6 +264,7 @@ print_mailbox (const search_options_t *opt, const mailbox_t *mailbox)
>  {
>      const char *name = mailbox->name;
>      const char *addr = mailbox->addr;
> +    int count = mailbox->count;
>      sprinter_t *format = opt->format;
>      InternetAddress *ia = internet_address_mailbox_new (name, addr);
>      char *name_addr;
> @@ -264,6 +274,10 @@ print_mailbox (const search_options_t *opt, const mailbox_t *mailbox)
>      name_addr = internet_address_to_string (ia, FALSE);
>  
>      if (format->is_text_printer) {
> +	if (count > 0) {
> +	    format->integer (format, count);
> +	    format->string (format, "\t");
> +	}
>  	format->string (format, name_addr);
>  	format->separator (format);
>      } else {
> @@ -274,6 +288,10 @@ print_mailbox (const search_options_t *opt, const mailbox_t *mailbox)
>  	format->string (format, addr);
>  	format->map_key (format, "name-addr");
>  	format->string (format, name_addr);
> +	if (count > 0) {
> +	    format->map_key (format, "count");
> +	    format->integer (format, count);
> +	}
>  	format->end (format);
>  	format->separator (format);
>      }
> @@ -282,7 +300,7 @@ print_mailbox (const search_options_t *opt, const mailbox_t *mailbox)
>      g_free (name_addr);
>  }
>  
> -/* Print addresses from InternetAddressList.  */
> +/* Print or prepare for printing addresses from InternetAddressList. */
>  static void
>  process_address_list (const search_options_t *opt, GHashTable *addrs,
>  		      InternetAddressList *list)
> @@ -307,17 +325,21 @@ process_address_list (const search_options_t *opt, GHashTable *addrs,
>  	    mailbox_t mbx = {
>  		.name = internet_address_get_name (address),
>  		.addr = internet_address_mailbox_get_addr (mailbox),
> +		.count = 0,
>  	    };
>  
>  	    if (is_duplicate (opt, addrs, mbx.name, mbx.addr))
>  		continue;
>  
> +	    if (opt->output & OUTPUT_COUNT)
> +		continue;
> +
>  	    print_mailbox (opt, &mbx);
>  	}
>      }
>  }
>  
> -/* Print addresses from a message header.  */
> +/* Print or prepare for printing addresses from a message header. */
>  static void
>  process_address_header (const search_options_t *opt, GHashTable *addrs, const char *value)
>  {
> @@ -341,6 +363,15 @@ _my_talloc_free_for_g_hash (void *ptr)
>      talloc_free (ptr);
>  }
>  
> +static void
> +print_hash_value (unused (gpointer key), gpointer value, gpointer user_data)
> +{
> +    const mailbox_t *mailbox = value;
> +    search_options_t *opt = user_data;
> +
> +    print_mailbox (opt, mailbox);
> +}
> +
>  static int
>  do_search_messages (search_options_t *opt)
>  {
> @@ -353,7 +384,7 @@ do_search_messages (search_options_t *opt)
>  
>      if (opt->output & OUTPUT_ADDRESS_FLAGS)
>  	addresses = g_hash_table_new_full (g_str_hash, g_str_equal,
> -					   _my_talloc_free_for_g_hash, NULL);
> +					   _my_talloc_free_for_g_hash, _my_talloc_free_for_g_hash);
>  
>      if (opt->offset < 0) {
>  	opt->offset += notmuch_query_count_messages (opt->query);
> @@ -420,6 +451,9 @@ do_search_messages (search_options_t *opt)
>  	notmuch_message_destroy (message);
>      }
>  
> +    if (addresses && opt->output & OUTPUT_COUNT)
> +	g_hash_table_foreach (addresses, print_hash_value, opt);
> +
>      if (addresses)
>  	g_hash_table_unref (addresses);
>  
> @@ -522,6 +556,7 @@ notmuch_search_command (notmuch_config_t *config, int argc, char *argv[])
>  				  { "recipients", OUTPUT_RECIPIENTS },
>  				  { "files", OUTPUT_FILES },
>  				  { "tags", OUTPUT_TAGS },
> +				  { "count", OUTPUT_COUNT },
>  				  { 0, 0 } } },
>          { NOTMUCH_OPT_KEYWORD, &exclude, "exclude", 'x',
>            (notmuch_keyword_t []){ { "true", NOTMUCH_EXCLUDE_TRUE },
> -- 
> 2.1.1
>
> _______________________________________________
> notmuch mailing list
> notmuch at notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch


More information about the notmuch mailing list