Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id EEF80431FBC for ; Sun, 17 Jan 2010 17:25:27 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: 0.001 X-Spam-Level: X-Spam-Status: No, score=0.001 tagged_above=-999 required=5 tests=[BAYES_50=0.001] autolearn=ham Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id maL95tqVy7iq for ; Sun, 17 Jan 2010 17:25:27 -0800 (PST) Received: from mout.perfora.net (mout.perfora.net [74.208.4.194]) by olra.theworths.org (Postfix) with ESMTP id EFCCA431FAE for ; Sun, 17 Jan 2010 17:25:26 -0800 (PST) Received: from po8.org (po8.org [69.168.48.167]) by mx.perfora.net (node=mxus2) with ESMTP (Nemesis) id 0LlCbW-1O6IZH1pJe-00b4ZE for notmuch@notmuchmail.org; Sun, 17 Jan 2010 20:25:26 -0500 Received: from po8.org ([127.0.0.1]) by po8.org with esmtp (Exim 4.69) (envelope-from ) id 1NWgMo-0001qb-Vn for notmuch@notmuchmail.org; Sun, 17 Jan 2010 17:25:23 -0800 To: notmuch@notmuchmail.org From: Bart Massey MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0" Content-ID: <7050.1263777618.0@po8.org> Date: Sun, 17 Jan 2010 17:25:18 -0800 Sender: bart@po8.org Message-Id: Subject: [notmuch] [PATCH] notmuch new: support for filename pattern filtering X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 18 Jan 2010 01:25:28 -0000 ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="us-ascii" Content-ID: <7050.1263777618.1@po8.org> Together with the new support for message deletion (thank you!) this patch lets me use notmuch in parallel with MH pretty successfully. Bart ------- =_aaaaaaaaaa0 Content-Type: text/x-csrc; name="0001-notmuch-new-support-for-filename-pattern-filtering.patch"; charset="us-ascii" Content-ID: <7050.1263777618.2@po8.org> >From 9418781ad8f1efed5e0866d351ce9d5baf584500 Mon Sep 17 00:00:00 2001 From: Bart Massey Date: Sun, 17 Jan 2010 17:00:47 -0800 Subject: [PATCH] notmuch new: support for filename pattern filtering In most maildir formats, only filenames consisting only of digits should be candidate emails. We add a new option "filename_pattern" in the "database" section of the config file that takes a regexp to filter candidate filenames against. By setting this string to "^[0-9]+$" only files that match this pattern will even be considered. This will inhibit bogus "Notice: non-mail" messages, and may also noticeably improve the efficiency of the tool if, for example, large mbox files are left lying around in the maildir. Signed-off-by: Bart Massey --- notmuch-client.h | 7 +++++++ notmuch-config.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- notmuch-new.c | 35 +++++++++++++++++++++++++++++++---- 3 files changed, 82 insertions(+), 6 deletions(-) diff --git a/notmuch-client.h b/notmuch-client.h index 77766de..191988c 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -146,6 +146,13 @@ notmuch_config_set_database_path (notmuch_config_t *config, const char *database_path); const char * +notmuch_config_get_filename_regex (notmuch_config_t *config); + +void +notmuch_config_set_filename_regex (notmuch_config_t *config, + const char *filename_regex); + +const char * notmuch_config_get_user_name (notmuch_config_t *config); void diff --git a/notmuch-config.c b/notmuch-config.c index 95430db..edfb4a6 100644 --- a/notmuch-config.c +++ b/notmuch-config.c @@ -31,11 +31,21 @@ static const char toplevel_config_comment[] = static const char database_config_comment[] = " Database configuration\n" "\n" - " The only value supported here is 'path' which should be the top-level\n" + " The value 'path' should be the top-level\n" " directory where your mail currently exists and to where mail will be\n" " delivered in the future. Files should be individual email messages.\n" " Notmuch will store its database within a sub-directory of the path\n" - " configured here named \".notmuch\".\n"; + " configured here named \".notmuch\".\n" + "\n" + " The optional value 'filename_pattern' should be a POSIX" + " regular expression\n" + " matching only those filenames that will be checked for email\n" + " messages. The match is against the last component of the pathname\n" + " only. Anchors may be used, and probably should be.\n" + " Typically, this is used to match only\n" + " files whose name is a number in standard maildir format. The\n" + " default pattern matches anything.\n" ; + static const char user_config_comment[] = " User configuration\n" @@ -58,6 +68,7 @@ struct _notmuch_config { GKeyFile *key_file; char *database_path; + char *filename_regex; char *user_name; char *user_primary_email; char **user_other_email; @@ -151,6 +162,8 @@ get_username_from_passwd_file (void *ctx) * * database_path: $HOME/mail * + * filename_pattern: .* + * * user_name: From /etc/passwd * * user_primary_mail: $EMAIL variable if set, otherwise @@ -195,6 +208,7 @@ notmuch_config_open (void *ctx, config->key_file = g_key_file_new (); config->database_path = NULL; + config->filename_regex = NULL; config->user_name = NULL; config->user_primary_email = NULL; config->user_other_email = NULL; @@ -354,6 +368,34 @@ notmuch_config_set_database_path (notmuch_config_t *config, } const char * +notmuch_config_get_filename_regex (notmuch_config_t *config) +{ + char *regex; + + if (config->filename_regex == NULL) { + regex = g_key_file_get_string (config->key_file, + "database", "filename_pattern", NULL); + if (regex) { + config->filename_regex = talloc_strdup (config, regex); + free (regex); + } + } + + return config->filename_regex; +} + +void +notmuch_config_set_filename_regex (notmuch_config_t *config, + const char *filename_regex) +{ + g_key_file_set_string (config->key_file, + "database", "filename_pattern", filename_regex); + + talloc_free (config->filename_regex); + config->filename_regex = NULL; +} + +const char * notmuch_config_get_user_name (notmuch_config_t *config) { char *name; diff --git a/notmuch-new.c b/notmuch-new.c index b740ee2..ab7ef9e 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -21,6 +21,8 @@ #include "notmuch-client.h" #include +#include +#include typedef struct _filename_node { char *filename; @@ -207,6 +209,7 @@ _entries_resemble_maildir (struct dirent **entries, int count) static notmuch_status_t add_files_recursive (notmuch_database_t *notmuch, const char *path, + const regex_t *maybe_regex, add_files_state_t *state) { DIR *dir = NULL; @@ -291,7 +294,7 @@ add_files_recursive (notmuch_database_t *notmuch, } next = talloc_asprintf (notmuch, "%s/%s", path, entry->d_name); - status = add_files_recursive (notmuch, next, state); + status = add_files_recursive (notmuch, next, maybe_regex, state); if (status && ret == NOTMUCH_STATUS_SUCCESS) ret = status; talloc_free (next); @@ -372,7 +375,7 @@ add_files_recursive (notmuch_database_t *notmuch, } /* We're now looking at a regular file that doesn't yet exist - * in the database, so add it. */ + * in the database. */ next = talloc_asprintf (notmuch, "%s/%s", path, entry->d_name); state->processed_files++; @@ -390,6 +393,14 @@ add_files_recursive (notmuch_database_t *notmuch, fflush (stdout); } + /* Check against the regex (if any) for valid mail + * file names and bail on failure */ + if (maybe_regex) { + status = regexec(maybe_regex, entry->d_name, 0, 0, 0); + if (status) + goto CLEANUP; + } + status = notmuch_database_add_message (notmuch, next, &message); switch (status) { /* success */ @@ -428,6 +439,7 @@ add_files_recursive (notmuch_database_t *notmuch, message = NULL; } + CLEANUP: if (do_add_files_print_progress) { do_add_files_print_progress = 0; add_files_print_progress (state); @@ -492,6 +504,7 @@ add_files_recursive (notmuch_database_t *notmuch, static notmuch_status_t add_files (notmuch_database_t *notmuch, const char *path, + const regex_t *maybe_regex, add_files_state_t *state) { notmuch_status_t status; @@ -529,7 +542,7 @@ add_files (notmuch_database_t *notmuch, return NOTMUCH_STATUS_FILE_ERROR; } - status = add_files_recursive (notmuch, path, state); + status = add_files_recursive (notmuch, path, maybe_regex, state); if (timer_is_active) { /* Now stop the timer. */ @@ -696,6 +709,9 @@ notmuch_new_command (void *ctx, int argc, char *argv[]) int ret = 0; struct stat st; const char *db_path; + const char *filename_regex; + regex_t regex; + const regex_t *maybe_regex = 0; char *dot_notmuch_path; struct sigaction action; _filename_node_t *f; @@ -721,6 +737,17 @@ notmuch_new_command (void *ctx, int argc, char *argv[]) db_path = notmuch_config_get_database_path (config); + filename_regex = notmuch_config_get_filename_regex (config); + if (filename_regex) { + status = regcomp(®ex, filename_regex, REG_EXTENDED | REG_NOSUB); + if (status) { + fprintf (stderr, "Note: Ignoring bad filename_pattern " + "in config file: %s\n", filename_regex); + } else { + maybe_regex = ®ex; + } + } + dot_notmuch_path = talloc_asprintf (ctx, "%s/%s", db_path, ".notmuch"); if (stat (dot_notmuch_path, &st)) { @@ -774,7 +801,7 @@ notmuch_new_command (void *ctx, int argc, char *argv[]) add_files_state.removed_files = _filename_list_create (ctx); add_files_state.removed_directories = _filename_list_create (ctx); - ret = add_files (notmuch, db_path, &add_files_state); + ret = add_files (notmuch, db_path, maybe_regex, &add_files_state); removed_files = 0; renamed_files = 0; -- 1.5.6.5 ------- =_aaaaaaaaaa0--