--- /dev/null
+Return-Path: <bart@po8.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 B6919431FBC\r
+ for <notmuch@notmuchmail.org>; Mon, 22 Feb 2010 12:27:37 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.384\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.384 tagged_above=-999 required=5\r
+ tests=[AWL=-0.385, BAYES_50=0.001] autolearn=ham\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 W7Eq1ewMlHVw for <notmuch@notmuchmail.org>;\r
+ Mon, 22 Feb 2010 12:27:34 -0800 (PST)\r
+X-Greylist: delayed 1415 seconds by postgrey-1.32 at olra;\r
+ Mon, 22 Feb 2010 12:27:33 PST\r
+Received: from po8.org (po8.org [69.168.48.167])\r
+ by olra.theworths.org (Postfix) with ESMTP id EE889431FAE\r
+ for <notmuch@notmuchmail.org>; Mon, 22 Feb 2010 12:27:33 -0800 (PST)\r
+Received: from po8.org ([127.0.0.1]) by po8.org with esmtp (Exim 4.69)\r
+ (envelope-from <bart@po8.org>) id 1NjeZ1-0001qw-HZ\r
+ for notmuch@notmuchmail.org; Mon, 22 Feb 2010 12:07:34 -0800\r
+To: Notmuch Mail <notmuch@notmuchmail.org>\r
+From: Bart Massey <bart@po8.org>\r
+Date: Mon, 22 Feb 2010 12:07:31 -0800\r
+Sender: bart@po8.org\r
+Message-Id: <E1NjeZ1-0001qw-HZ@po8.org>\r
+Subject: [notmuch] [PATCH] Added mail directory filename pattern support.\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: Mon, 22 Feb 2010 20:27:38 -0000\r
+\r
+Typically, the filenames in a mail directory that actually\r
+contain mail obey some specific format. For example, in my\r
+MH email directory, all mail filenames consist only of\r
+digits.\r
+\r
+This patch adds support for a config file variable\r
+"filename_pattern" which maybe set to a regex used to filter\r
+only valid mail filenames when scanning. Effective use of\r
+filename_pattern cuts down on the noise from notmuch, and\r
+may speed it up in some cases.\r
+\r
+Signed-off-by: Bart Massey <bart@cs.pdx.edu>\r
+---\r
+ notmuch-client.h | 7 +++++++\r
+ notmuch-config.c | 47 +++++++++++++++++++++++++++++++++++++++++++++--\r
+ notmuch-new.c | 35 +++++++++++++++++++++++++++++++----\r
+ 3 files changed, 83 insertions(+), 6 deletions(-)\r
+\r
+diff --git a/notmuch-client.h b/notmuch-client.h\r
+index 77766de..191988c 100644\r
+--- a/notmuch-client.h\r
++++ b/notmuch-client.h\r
+@@ -146,6 +146,13 @@ notmuch_config_set_database_path (notmuch_config_t *config,\r
+ const char *database_path);\r
+ \r
+ const char *\r
++notmuch_config_get_filename_regex (notmuch_config_t *config);\r
++\r
++void\r
++notmuch_config_set_filename_regex (notmuch_config_t *config,\r
++ const char *filename_regex);\r
++\r
++const char *\r
+ notmuch_config_get_user_name (notmuch_config_t *config);\r
+ \r
+ void\r
+diff --git a/notmuch-config.c b/notmuch-config.c\r
+index 95430db..4189f03 100644\r
+--- a/notmuch-config.c\r
++++ b/notmuch-config.c\r
+@@ -31,11 +31,22 @@ static const char toplevel_config_comment[] =\r
+ static const char database_config_comment[] =\r
+ " Database configuration\n"\r
+ "\n"\r
+- " The only value supported here is 'path' which should be the top-level\n"\r
++ " The value 'path' should be the top-level\n"\r
+ " directory where your mail currently exists and to where mail will be\n"\r
+ " delivered in the future. Files should be individual email messages.\n"\r
+ " Notmuch will store its database within a sub-directory of the path\n"\r
+- " configured here named \".notmuch\".\n";\r
++ " configured here named \".notmuch\".\n"\r
++ "\n"\r
++ " The optional value 'filename_pattern' should be\n"\r
++ " a POSIX regular expression matching only those\n"\r
++ " filenames that will be checked for email\n"\r
++ " messages. The match is against the last\n"\r
++ " component of the pathname only. Anchors may be\n"\r
++ " used, and probably should be. Typically, this\n"\r
++ " is used to match only files whose name is a\n"\r
++ " number ala MH, or to match only files in\n"\r
++ " standard maildir format. The default pattern\n"\r
++ " matches anything.\n";\r
+ \r
+ static const char user_config_comment[] =\r
+ " User configuration\n"\r
+@@ -58,6 +69,7 @@ struct _notmuch_config {\r
+ GKeyFile *key_file;\r
+ \r
+ char *database_path;\r
++ char *filename_regex;\r
+ char *user_name;\r
+ char *user_primary_email;\r
+ char **user_other_email;\r
+@@ -151,6 +163,8 @@ get_username_from_passwd_file (void *ctx)\r
+ *\r
+ * database_path: $HOME/mail\r
+ *\r
++ * filename_pattern: .*\r
++ *\r
+ * user_name: From /etc/passwd\r
+ *\r
+ * user_primary_mail: $EMAIL variable if set, otherwise\r
+@@ -195,6 +209,7 @@ notmuch_config_open (void *ctx,\r
+ config->key_file = g_key_file_new ();\r
+ \r
+ config->database_path = NULL;\r
++ config->filename_regex = NULL;\r
+ config->user_name = NULL;\r
+ config->user_primary_email = NULL;\r
+ config->user_other_email = NULL;\r
+@@ -354,6 +369,34 @@ notmuch_config_set_database_path (notmuch_config_t *config,\r
+ }\r
+ \r
+ const char *\r
++notmuch_config_get_filename_regex (notmuch_config_t *config)\r
++{\r
++ char *regex;\r
++\r
++ if (config->filename_regex == NULL) {\r
++ regex = g_key_file_get_string (config->key_file,\r
++ "database", "filename_pattern", NULL);\r
++ if (regex) {\r
++ config->filename_regex = talloc_strdup (config, regex);\r
++ free (regex);\r
++ }\r
++ }\r
++\r
++ return config->filename_regex;\r
++}\r
++\r
++void\r
++notmuch_config_set_filename_regex (notmuch_config_t *config,\r
++ const char *filename_regex)\r
++{\r
++ g_key_file_set_string (config->key_file,\r
++ "database", "filename_pattern", filename_regex);\r
++\r
++ talloc_free (config->filename_regex);\r
++ config->filename_regex = NULL;\r
++}\r
++\r
++const char *\r
+ notmuch_config_get_user_name (notmuch_config_t *config)\r
+ {\r
+ char *name;\r
+diff --git a/notmuch-new.c b/notmuch-new.c\r
+index f25c71f..531f9a3 100644\r
+--- a/notmuch-new.c\r
++++ b/notmuch-new.c\r
+@@ -21,6 +21,8 @@\r
+ #include "notmuch-client.h"\r
+ \r
+ #include <unistd.h>\r
++#include <sys/types.h>\r
++#include <regex.h>\r
+ \r
+ typedef struct _filename_node {\r
+ char *filename;\r
+@@ -207,6 +209,7 @@ _entries_resemble_maildir (struct dirent **entries, int count)\r
+ static notmuch_status_t\r
+ add_files_recursive (notmuch_database_t *notmuch,\r
+ const char *path,\r
++ const regex_t *maybe_regex,\r
+ add_files_state_t *state)\r
+ {\r
+ DIR *dir = NULL;\r
+@@ -302,7 +305,7 @@ add_files_recursive (notmuch_database_t *notmuch,\r
+ }\r
+ \r
+ next = talloc_asprintf (notmuch, "%s/%s", path, entry->d_name);\r
+- status = add_files_recursive (notmuch, next, state);\r
++ status = add_files_recursive (notmuch, next, maybe_regex, state);\r
+ if (status && ret == NOTMUCH_STATUS_SUCCESS)\r
+ ret = status;\r
+ talloc_free (next);\r
+@@ -389,7 +392,7 @@ add_files_recursive (notmuch_database_t *notmuch,\r
+ }\r
+ \r
+ /* We're now looking at a regular file that doesn't yet exist\r
+- * in the database, so add it. */\r
++ * in the database. */\r
+ next = talloc_asprintf (notmuch, "%s/%s", path, entry->d_name);\r
+ \r
+ state->processed_files++;\r
+@@ -407,6 +410,14 @@ add_files_recursive (notmuch_database_t *notmuch,\r
+ fflush (stdout);\r
+ }\r
+ \r
++ /* Check against the regex (if any) for valid mail\r
++ * file names and bail on failure */\r
++ if (maybe_regex) {\r
++ status = regexec(maybe_regex, entry->d_name, 0, 0, 0);\r
++ if (status)\r
++ goto CLEANUP;\r
++ }\r
++\r
+ status = notmuch_database_add_message (notmuch, next, &message);\r
+ switch (status) {\r
+ /* success */\r
+@@ -445,6 +456,7 @@ add_files_recursive (notmuch_database_t *notmuch,\r
+ message = NULL;\r
+ }\r
+ \r
++ CLEANUP:\r
+ if (do_add_files_print_progress) {\r
+ do_add_files_print_progress = 0;\r
+ add_files_print_progress (state);\r
+@@ -509,6 +521,7 @@ add_files_recursive (notmuch_database_t *notmuch,\r
+ static notmuch_status_t\r
+ add_files (notmuch_database_t *notmuch,\r
+ const char *path,\r
++ const regex_t *maybe_regex,\r
+ add_files_state_t *state)\r
+ {\r
+ notmuch_status_t status;\r
+@@ -546,7 +559,7 @@ add_files (notmuch_database_t *notmuch,\r
+ return NOTMUCH_STATUS_FILE_ERROR;\r
+ }\r
+ \r
+- status = add_files_recursive (notmuch, path, state);\r
++ status = add_files_recursive (notmuch, path, maybe_regex, state);\r
+ \r
+ if (timer_is_active) {\r
+ /* Now stop the timer. */\r
+@@ -713,6 +726,9 @@ notmuch_new_command (void *ctx, int argc, char *argv[])\r
+ int ret = 0;\r
+ struct stat st;\r
+ const char *db_path;\r
++ const char *filename_regex;\r
++ regex_t regex;\r
++ const regex_t *maybe_regex = 0;\r
+ char *dot_notmuch_path;\r
+ struct sigaction action;\r
+ _filename_node_t *f;\r
+@@ -738,6 +754,17 @@ notmuch_new_command (void *ctx, int argc, char *argv[])\r
+ \r
+ db_path = notmuch_config_get_database_path (config);\r
+ \r
++ filename_regex = notmuch_config_get_filename_regex (config);\r
++ if (filename_regex) {\r
++ status = regcomp(®ex, filename_regex, REG_EXTENDED | REG_NOSUB);\r
++ if (status) {\r
++ fprintf (stderr, "Note: Ignoring bad filename_pattern "\r
++ "in config file: %s\n", filename_regex);\r
++ } else {\r
++ maybe_regex = ®ex;\r
++ }\r
++ }\r
++\r
+ dot_notmuch_path = talloc_asprintf (ctx, "%s/%s", db_path, ".notmuch");\r
+ \r
+ if (stat (dot_notmuch_path, &st)) {\r
+@@ -791,7 +818,7 @@ notmuch_new_command (void *ctx, int argc, char *argv[])\r
+ add_files_state.removed_files = _filename_list_create (ctx);\r
+ add_files_state.removed_directories = _filename_list_create (ctx);\r
+ \r
+- ret = add_files (notmuch, db_path, &add_files_state);\r
++ ret = add_files (notmuch, db_path, maybe_regex, &add_files_state);\r
+ \r
+ removed_files = 0;\r
+ renamed_files = 0;\r
+-- \r
+1.6.6.1\r
+\r