Re: [PATCH 3/3] search: Support automatic tag exclusions
authorJani Nikula <jani@nikula.org>
Wed, 11 Jan 2012 19:27:52 +0000 (21:27 +0200)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:41:55 +0000 (09:41 -0800)
2f/fe3367e71c7a55b035c4b11e11626385894a16 [new file with mode: 0644]

diff --git a/2f/fe3367e71c7a55b035c4b11e11626385894a16 b/2f/fe3367e71c7a55b035c4b11e11626385894a16
new file mode 100644 (file)
index 0000000..60ff308
--- /dev/null
@@ -0,0 +1,326 @@
+Return-Path: <jani@nikula.org>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+       by olra.theworths.org (Postfix) with ESMTP id 5E6AF429E21\r
+       for <notmuch@notmuchmail.org>; Wed, 11 Jan 2012 11:28:00 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.7\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5\r
+       tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+       by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+       with ESMTP id kqCOtOIto7h8 for <notmuch@notmuchmail.org>;\r
+       Wed, 11 Jan 2012 11:27:59 -0800 (PST)\r
+Received: from mail-ee0-f53.google.com (mail-ee0-f53.google.com\r
+ [74.125.83.53])       (using TLSv1 with cipher RC4-SHA (128/128 bits))        (No client\r
+ certificate requested)        by olra.theworths.org (Postfix) with ESMTPS id\r
+ 291FC431FB6   for <notmuch@notmuchmail.org>; Wed, 11 Jan 2012 11:27:59 -0800\r
+ (PST)\r
+Received: by eeke51 with SMTP id e51so644885eek.26\r
+       for <notmuch@notmuchmail.org>; Wed, 11 Jan 2012 11:27:58 -0800 (PST)\r
+Received: by 10.14.32.20 with SMTP id n20mr208666eea.42.1326310077866;\r
+       Wed, 11 Jan 2012 11:27:57 -0800 (PST)\r
+Received: from localhost (dsl-hkibrasgw4-fe5cdc00-23.dhcp.inet.fi.\r
+       [80.220.92.23])\r
+       by mx.google.com with ESMTPS id b49sm9358011eec.9.2012.01.11.11.27.54\r
+       (version=SSLv3 cipher=OTHER); Wed, 11 Jan 2012 11:27:55 -0800 (PST)\r
+From: Jani Nikula <jani@nikula.org>\r
+To: Austin Clements <amdragon@MIT.EDU>, notmuch@notmuchmail.org\r
+Subject: Re: [PATCH 3/3] search: Support automatic tag exclusions\r
+In-Reply-To: <1326258173-21163-4-git-send-email-amdragon@mit.edu>\r
+References: <20120109043101.GH20796@mit.edu>\r
+       <1326258173-21163-1-git-send-email-amdragon@mit.edu>\r
+       <1326258173-21163-4-git-send-email-amdragon@mit.edu>\r
+User-Agent: Notmuch/0.10.2+193~ga73a411 (http://notmuchmail.org) Emacs/23.3.1\r
+       (i686-pc-linux-gnu)\r
+Date: Wed, 11 Jan 2012 21:27:52 +0200\r
+Message-ID: <87ty42ca4n.fsf@nikula.org>\r
+MIME-Version: 1.0\r
+Content-Type: text/plain; charset=utf-8\r
+Content-Transfer-Encoding: quoted-printable\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+       <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Wed, 11 Jan 2012 19:28:00 -0000\r
+\r
+On Wed, 11 Jan 2012 00:02:53 -0500, Austin Clements <amdragon@MIT.EDU> wrot=\r
+e:\r
+> This adds a "search" section to the config file and an\r
+> "auto_tag_exclusions" setting in that section.  The search and count\r
+> commands pass tag tags from the configuration to the library.\r
+\r
+Looks good.\r
+\r
+Perhaps a few subtests like this in test/count on a corpus with some\r
+"deleted" or "spam" tags would be in order:\r
+\r
+test_begin_subtest "message count with --output=3Dmessages"\r
+test_expect_equal \\r
+    "`notmuch search --output=3Dmessages ${SEARCH} | wc -l`" \\r
+    "`notmuch count --output=3Dmessages ${SEARCH}`"\r
+\r
+test_begin_subtest "thread count with --output=3Dthreads"\r
+test_expect_equal \\r
+    "`notmuch search --output=3Dthreads ${SEARCH} | wc -l`" \\r
+    "`notmuch count --output=3Dthreads ${SEARCH}`"\r
+\r
+That's copy-paste from test/count; doing the same after some exclude\r
+tagging (and making sure it actually affects count) should be enough.\r
+\r
+\r
+BR,\r
+Jani.\r
+\r
+\r
+\r
+\r
+> ---\r
+>  notmuch-client.h |    8 ++++++++\r
+>  notmuch-config.c |   42 ++++++++++++++++++++++++++++++++++++++++++\r
+>  notmuch-count.c  |    8 ++++++++\r
+>  notmuch-search.c |    8 ++++++++\r
+>  test/search      |   18 ++++++++++++++++++\r
+>  5 files changed, 84 insertions(+), 0 deletions(-)\r
+>=20\r
+> diff --git a/notmuch-client.h b/notmuch-client.h\r
+> index 517c010..62ede28 100644\r
+> --- a/notmuch-client.h\r
+> +++ b/notmuch-client.h\r
+> @@ -235,6 +235,14 @@ void\r
+>  notmuch_config_set_maildir_synchronize_flags (notmuch_config_t *config,\r
+>                                            notmuch_bool_t synchronize_flags);\r
+>=20=20\r
+> +const char **\r
+> +notmuch_config_get_auto_exclude_tags (notmuch_config_t *config, size_t *=\r
+length);\r
+> +\r
+> +void\r
+> +notmuch_config_set_auto_exclude_tags (notmuch_config_t *config,\r
+> +                                  const char *list[],\r
+> +                                  size_t length);\r
+> +\r
+>  int\r
+>  notmuch_run_hook (const char *db_path, const char *hook);\r
+>=20=20\r
+> diff --git a/notmuch-config.c b/notmuch-config.c\r
+> index d697138..6c3123b 100644\r
+> --- a/notmuch-config.c\r
+> +++ b/notmuch-config.c\r
+> @@ -84,6 +84,15 @@ static const char maildir_config_comment[] =3D\r
+>      "\tand update tags, while the \"notmuch tag\" and \"notmuch restore\=\r
+"\n"\r
+>      "\tcommands will notice tag changes and update flags in filenames\n";\r
+>=20=20\r
+> +static const char search_config_comment[] =3D\r
+> +    " Search configuration\n"\r
+> +    "\n"\r
+> +    " The following option is supported here:\n"\r
+> +    "\n"\r
+> +    "\tauto_exclude_tags      A ;-separated list of tags that will be\n"\r
+> +    "\t excluded from queries by default.  This can be overridden by inc=\r
+luding\n"\r
+> +    "\t these tags in a query.\n";\r
+> +\r
+>  struct _notmuch_config {\r
+>      char *filename;\r
+>      GKeyFile *key_file;\r
+> @@ -96,6 +105,8 @@ struct _notmuch_config {\r
+>      const char **new_tags;\r
+>      size_t new_tags_length;\r
+>      notmuch_bool_t maildir_synchronize_flags;\r
+> +    const char **auto_exclude_tags;\r
+> +    size_t auto_exclude_tags_length;\r
+>  };\r
+>=20=20\r
+>  static int\r
+> @@ -221,6 +232,7 @@ notmuch_config_open (void *ctx,\r
+>      int file_had_new_group;\r
+>      int file_had_user_group;\r
+>      int file_had_maildir_group;\r
+> +    int file_had_search_group;\r
+>=20=20\r
+>      if (is_new_ret)\r
+>      *is_new_ret =3D 0;\r
+> @@ -252,6 +264,8 @@ notmuch_config_open (void *ctx,\r
+>      config->new_tags =3D NULL;\r
+>      config->new_tags_length =3D 0;\r
+>      config->maildir_synchronize_flags =3D TRUE;\r
+> +    config->auto_exclude_tags =3D NULL;\r
+> +    config->auto_exclude_tags_length =3D 0;\r
+>=20=20\r
+>      if (! g_key_file_load_from_file (config->key_file,\r
+>                                   config->filename,\r
+> @@ -295,6 +309,7 @@ notmuch_config_open (void *ctx,\r
+>      file_had_new_group =3D g_key_file_has_group (config->key_file, "new"=\r
+);\r
+>      file_had_user_group =3D g_key_file_has_group (config->key_file, "use=\r
+r");\r
+>      file_had_maildir_group =3D g_key_file_has_group (config->key_file, "=\r
+maildir");\r
+> +    file_had_search_group =3D g_key_file_has_group (config->key_file, "s=\r
+earch");\r
+>=20=20\r
+>=20=20\r
+>      if (notmuch_config_get_database_path (config) =3D=3D NULL) {\r
+> @@ -345,6 +360,11 @@ notmuch_config_open (void *ctx,\r
+>      notmuch_config_set_new_tags (config, tags, 2);\r
+>      }\r
+>=20=20\r
+> +    if (notmuch_config_get_auto_exclude_tags (config, &tmp) =3D=3D NULL)=\r
+ {\r
+> +    const char *tags[] =3D { "deleted", "spam" };\r
+> +    notmuch_config_set_auto_exclude_tags (config, tags, 2);\r
+> +    }\r
+> +\r
+>      error =3D NULL;\r
+>      config->maildir_synchronize_flags =3D\r
+>      g_key_file_get_boolean (config->key_file,\r
+> @@ -387,6 +407,11 @@ notmuch_config_open (void *ctx,\r
+>                              maildir_config_comment, NULL);\r
+>      }\r
+>=20=20\r
+> +    if (! file_had_search_group) {\r
+> +    g_key_file_set_comment (config->key_file, "search", NULL,\r
+> +                            search_config_comment, NULL);\r
+> +    }\r
+> +\r
+>      if (is_new_ret)\r
+>      *is_new_ret =3D is_new;\r
+>=20=20\r
+> @@ -597,6 +622,23 @@ notmuch_config_set_new_tags (notmuch_config_t *confi=\r
+g,\r
+>                   &(config->new_tags));\r
+>  }\r
+>=20=20\r
+> +const char **\r
+> +notmuch_config_get_auto_exclude_tags (notmuch_config_t *config, size_t *=\r
+length)\r
+> +{\r
+> +    return _config_get_list (config, "search", "auto_exclude_tags",\r
+> +                         &(config->auto_exclude_tags),\r
+> +                         &(config->auto_exclude_tags_length), length);\r
+> +}\r
+> +\r
+> +void\r
+> +notmuch_config_set_auto_exclude_tags (notmuch_config_t *config,\r
+> +                                  const char *list[],\r
+> +                                  size_t length)\r
+> +{\r
+> +    _config_set_list (config, "search", "auto_exclude_tags", list, lengt=\r
+h,\r
+> +                  &(config->auto_exclude_tags));\r
+> +}\r
+> +\r
+>  /* Given a configuration item of the form <group>.<key> return the\r
+>   * component group and key. If any error occurs, print a message on\r
+>   * stderr and return 1. Otherwise, return 0.\r
+> diff --git a/notmuch-count.c b/notmuch-count.c\r
+> index fb7401b..494619f 100644\r
+> --- a/notmuch-count.c\r
+> +++ b/notmuch-count.c\r
+> @@ -35,6 +35,9 @@ notmuch_count_command (void *ctx, int argc, char *argv[=\r
+])\r
+>      char *query_str;\r
+>      int opt_index;\r
+>      output_t output =3D OUTPUT_MESSAGES;\r
+> +    const char **auto_exclude_tags;\r
+> +    size_t auto_exclude_tags_length;\r
+> +    unsigned int i;\r
+>=20=20\r
+>      notmuch_opt_desc_t options[] =3D {\r
+>      { NOTMUCH_OPT_KEYWORD, &output, "output", 'o',\r
+> @@ -75,6 +78,11 @@ notmuch_count_command (void *ctx, int argc, char *argv=\r
+[])\r
+>      return 1;\r
+>      }\r
+>=20=20\r
+> +    auto_exclude_tags =3D notmuch_config_get_auto_exclude_tags\r
+> +    (config, &auto_exclude_tags_length);\r
+> +    for (i =3D 0; i < auto_exclude_tags_length; i++)\r
+> +    notmuch_query_add_tag_exclude (query, auto_exclude_tags[i]);\r
+> +\r
+>      switch (output) {\r
+>      case OUTPUT_MESSAGES:\r
+>      printf ("%u\n", notmuch_query_count_messages (query));\r
+> diff --git a/notmuch-search.c b/notmuch-search.c\r
+> index 4baab56..8867aab 100644\r
+> --- a/notmuch-search.c\r
+> +++ b/notmuch-search.c\r
+> @@ -423,6 +423,9 @@ notmuch_search_command (void *ctx, int argc, char *ar=\r
+gv[])\r
+>      output_t output =3D OUTPUT_SUMMARY;\r
+>      int offset =3D 0;\r
+>      int limit =3D -1; /* unlimited */\r
+> +    const char **auto_exclude_tags;\r
+> +    size_t auto_exclude_tags_length;\r
+> +    unsigned int i;\r
+>=20=20\r
+>      enum { NOTMUCH_FORMAT_JSON, NOTMUCH_FORMAT_TEXT }\r
+>      format_sel =3D NOTMUCH_FORMAT_TEXT;\r
+> @@ -490,6 +493,11 @@ notmuch_search_command (void *ctx, int argc, char *a=\r
+rgv[])\r
+>=20=20\r
+>      notmuch_query_set_sort (query, sort);\r
+>=20=20\r
+> +    auto_exclude_tags =3D notmuch_config_get_auto_exclude_tags\r
+> +    (config, &auto_exclude_tags_length);\r
+> +    for (i =3D 0; i < auto_exclude_tags_length; i++)\r
+> +    notmuch_query_add_tag_exclude (query, auto_exclude_tags[i]);\r
+> +\r
+>      switch (output) {\r
+>      default:\r
+>      case OUTPUT_SUMMARY:\r
+> diff --git a/test/search b/test/search\r
+> index a7a0b18..f421ae3 100755\r
+> --- a/test/search\r
+> +++ b/test/search\r
+> @@ -129,4 +129,22 @@ add_message '[subject]=3D"utf8-message-body-subject"=\r
+' '[date]=3D"Sat, 01 Jan 2000 12\r
+>  output=3D$(notmuch search "b=C3=B6d=C3=BD" | notmuch_search_sanitize)\r
+>  test_expect_equal "$output" "thread:XXX   2000-01-01 [1/1] Notmuch Test =\r
+Suite; utf8-message-body-subject (inbox unread)"\r
+>=20=20\r
+> +test_begin_subtest "Search hides deleted"\r
+> +generate_message '[subject]=3D"Not deleted"'\r
+> +generate_message '[subject]=3D"Deleted"'\r
+> +notmuch new > /dev/null\r
+> +notmuch tag +deleted id:$gen_msg_id\r
+> +output=3D$(notmuch search subject:deleted | notmuch_search_sanitize)\r
+> +test_expect_equal "$output" "thread:XXX   2001-01-05 [1/1] Notmuch Test =\r
+Suite; Not deleted (inbox unread)"\r
+> +\r
+> +test_begin_subtest "Search shows deleted if requested"\r
+> +output=3D$(notmuch search subject:deleted and tag:deleted | notmuch_sear=\r
+ch_sanitize)\r
+> +test_expect_equal "$output" "thread:XXX   2001-01-05 [1/1] Notmuch Test =\r
+Suite; Deleted (deleted inbox unread)"\r
+> +\r
+> +test_begin_subtest "Search hides deleted in threads"\r
+> +add_message '[subject]=3D"Not deleted reply"' '[in-reply-to]=3D"<$gen_ms=\r
+g_id>"'\r
+> +output=3D$(notmuch search subject:deleted | notmuch_search_sanitize)\r
+> +test_expect_equal "$output" "thread:XXX   2001-01-05 [1/1] Notmuch Test =\r
+Suite; Not deleted (inbox unread)\r
+> +thread:XXX   2001-01-05 [1/2] Notmuch Test Suite; Not deleted reply (del=\r
+eted inbox unread)"\r
+> +\r
+>  test_done\r
+> --=20\r
+> 1.7.7.3\r
+>=20\r
+> _______________________________________________\r
+> notmuch mailing list\r
+> notmuch@notmuchmail.org\r
+> http://notmuchmail.org/mailman/listinfo/notmuch\r