[DRAFT PATCH] emacs: support limiting the number of results shown in search results
On Sun, 04 Dec 2011 13:21:40 +0530, "Aneesh Kumar K.V" wrote: > On Thu, 17 Nov 2011 22:07:38 +0200, Jani Nikula wrote: > > Add support for limiting the maximum number of results initially displayed > > in search results. When enabled, the search results will contain push > > buttons to double the number of results displayed or to show unlimited > > results. > > > > The approach is inspired by vc-print-log in Emacs vc.el. > > > > Signed-off-by: Jani Nikula > > > > This break notmuch-search-operate-all, I guess the change should also > make sure notmuch-search-operate-all also limit its operation to > notmuch-search-limit ? Hi Aneesh, thanks for the report. I'll look into this, but I'm afraid I can't make any promises when it'll be. BR, Jani.
[PATCH 1/4] notmuch-opts.[ch]: new argument parsing framework for notmuch.
On Sun, 4 Dec 2011 11:47:52 -0400, David Bremner wrote: > + case NOTMUCH_OPT_INT: > + if (try->output_var) > + *((int *)try->output_var) = > + atol (arg + strlen (try->name) + 1); Looking at patch 4 and the existing handling of int params, I'd really like this one to check that the string is non-empty and that all of the string is parsed (and doesn't contain garbage at the end). BR, Jani.
[PATCH 3/4] notmuch-restore: convert to notmuch-opts argument handling.
On Sun, 4 Dec 2011 11:47:54 -0400, David Bremner wrote: > From: David Bremner > > The new argument handling is a bit more concise, and bit more > flexible. It allows the input file name to go before the --accumulate > option. > --- > notmuch-restore.c | 38 -- > 1 files changed, 16 insertions(+), 22 deletions(-) > > diff --git a/notmuch-restore.c b/notmuch-restore.c > index 13b4325..d0aa7a8 100644 > --- a/notmuch-restore.c > +++ b/notmuch-restore.c > @@ -18,9 +18,8 @@ > * Author: Carl Worth > */ > > -#include > - > #include "notmuch-client.h" > +#include "notmuch-opts.h" I guess this will eventually be included almost everywhere, so in that sense could be put in notmuch-client.h too. > > int > notmuch_restore_command (unused (void *ctx), int argc, char *argv[]) > @@ -29,12 +28,14 @@ notmuch_restore_command (unused (void *ctx), int argc, > char *argv[]) > notmuch_database_t *notmuch; > notmuch_bool_t synchronize_flags; > notmuch_bool_t accumulate = FALSE; > +char *input_file_name = NULL; > FILE *input = stdin; > char *line = NULL; > size_t line_size; > ssize_t line_len; > regex_t regex; > int rerr; > +int opt_index; > > config = notmuch_config_open (ctx, NULL, NULL); > if (config == NULL) > @@ -47,37 +48,30 @@ notmuch_restore_command (unused (void *ctx), int argc, > char *argv[]) > > synchronize_flags = notmuch_config_get_maildir_synchronize_flags > (config); > > -struct option options[] = { > - { "accumulate", no_argument, 0, 'a' }, > - { 0, 0, 0, 0} > +notmuch_opt_desc_t options[] = { > + { "in-file", 'i', NOTMUCH_OPT_POSITION, 0, _file_name }, Unless I'm mistaken in review of patch 1, specifying the input file using --in-file=file doesn't work; it only works as a positional argument. > + { "accumulate", 'a', NOTMUCH_OPT_BOOLEAN, 0, }, > + { 0, 0, 0, 0, 0 } > }; > > -int opt; > -do { > - opt = getopt_long (argc, argv, "", options, NULL); > +opt_index = notmuch_parse_args (argc, argv, options, 1); > > - switch (opt) { > - case 'a': > - accumulate = 1; > - break; > - case '?': > - return 1; > - break; > - } > - > -} while (opt != -1); > +if (opt_index < 0) { > + /* diagnostics already printed */ > + exit(1); return 1 rather than exit(1)? BR, Jani. > +} > > -if (optind < argc) { > - input = fopen (argv[optind], "r"); > +if (input_file_name) { > + input = fopen (input_file_name, "r"); > if (input == NULL) { > fprintf (stderr, "Error opening %s for reading: %s\n", > - argv[optind], strerror (errno)); > + input_file_name, strerror (errno)); > return 1; > } > optind++; > } > > -if (optind < argc) { > +if (opt_index < argc) { > fprintf (stderr, >"Cannot read dump from more than one file: %s\n", >argv[optind]); > -- > 1.7.7.3 > > ___ > notmuch mailing list > notmuch at notmuchmail.org > http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 2/4] notmuch-dump: convert to notmuch-opts argument handling.
On Sun, 4 Dec 2011 11:47:53 -0400, David Bremner wrote: > From: David Bremner > > The output file is handled via positional arguments. There are > currently no "normal" options. > --- > notmuch-dump.c | 32 > 1 files changed, 20 insertions(+), 12 deletions(-) > > diff --git a/notmuch-dump.c b/notmuch-dump.c > index a490917..6fbdc81 100644 > --- a/notmuch-dump.c > +++ b/notmuch-dump.c > @@ -19,6 +19,7 @@ > */ > > #include "notmuch-client.h" > +#include "notmuch-opts.h" > > int > notmuch_dump_command (unused (void *ctx), int argc, char *argv[]) > @@ -41,27 +42,34 @@ notmuch_dump_command (unused (void *ctx), int argc, char > *argv[]) > if (notmuch == NULL) > return 1; > > -argc--; argv++; /* skip subcommand argument */ > +char *output_file_name = NULL; > +int opt_index; > > -if (argc && strcmp (argv[0], "--") != 0) { > +notmuch_opt_desc_t options[] = { > + { "out-file", 'o', NOTMUCH_OPT_POSITION, 0, _file_name }, > + { 0, 0, 0, 0, 0 } > +}; > + > +opt_index = notmuch_parse_args (argc, argv, options, 1); > + > +if (opt_index < 0) { > + /* diagnostics already printed */ > + exit(1); return 1 rather than exit(1)? BR, Jani. > +} > + > +if (output_file_name) { > fprintf (stderr, "Warning: the output file argument of dump is > deprecated.\n"); > - output = fopen (argv[0], "w"); > + output = fopen (output_file_name, "w"); > if (output == NULL) { > fprintf (stderr, "Error opening %s for writing: %s\n", > - argv[0], strerror (errno)); > + output_file_name, strerror (errno)); > return 1; > } > - argc--; > - argv++; > } > > -if (argc && strcmp (argv[0], "--") == 0){ > - argc--; > - argv++; > -} > > -if (argc) { > - query_str = query_string_from_args (notmuch, argc, argv); > +if (opt_index < argc) { > + query_str = query_string_from_args (notmuch, argc-opt_index, > argv+opt_index); > if (query_str == NULL) { > fprintf (stderr, "Out of memory.\n"); > return 1; > -- > 1.7.7.3 > > ___ > notmuch mailing list > notmuch at notmuchmail.org > http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 1/4] notmuch-opts.[ch]: new argument parsing framework for notmuch.
On Sun, 4 Dec 2011 11:47:52 -0400, David Bremner wrote: > From: David Bremner > > As we noticed when Jani kindly converted things to getopt_long, much > of the work in argument parsing in notmuch is due to the the key-value > style arguments like --format=(raw|json|text). Hi David - Apologies for not finding time to do proper review earlier. All in all I think this is good work, and I especially like the simplicity of defining arguments in the commands. Even if it makes me slightly sad to have to reinvent the argument parsing wheel... but this is much better than just using getopt_long() like I did. So the design is good, but there are a few issues and nitpicks; please find my comments below. BR, Jani. > In this version I implement Austin Clements' suggestion of basing the > main API on taking pointers to output variables. > --- > Makefile.local |1 + > notmuch-opts.c | 136 > > notmuch-opts.h | 44 ++ > 3 files changed, 181 insertions(+), 0 deletions(-) > create mode 100644 notmuch-opts.c > create mode 100644 notmuch-opts.h > > diff --git a/Makefile.local b/Makefile.local > index c94402b..6606be8 100644 > --- a/Makefile.local > +++ b/Makefile.local > @@ -303,6 +303,7 @@ notmuch_client_srcs = \ > notmuch-count.c \ > notmuch-dump.c \ > notmuch-new.c \ > + notmuch-opts.c \ We chatted about reserving notmuch-*.c to notmuch commands, but I guess it was only after you sent these. I think it would make sense though. > notmuch-reply.c \ > notmuch-restore.c \ > notmuch-search.c\ > diff --git a/notmuch-opts.c b/notmuch-opts.c > new file mode 100644 > index 000..62d94bf > --- /dev/null > +++ b/notmuch-opts.c > @@ -0,0 +1,136 @@ > +#include > +#include > +#include > +#include "error_util.h" > +#include "notmuch-opts.h" > + > +/* > + Search the list of keywords for a given argument, assigning the > + output variable to the corresponding value. Return FALSE if nothing > + matches. > +*/ Array of keywords to be really pedantic. > + > +static notmuch_bool_t > +_process_keyword_arg (const notmuch_opt_desc_t *arg_desc, const char > *arg_str) { > + > +if (arg_str[0] != ':' && arg_str[0] != '=') { > + return FALSE; > +} > + > +/* skip delimiter */ > +arg_str++; I think the caller should check and skip the delimiters. See my comments below where this gets called. > + > +notmuch_keyword_t *keywords = arg_desc->keywords; > + > +while (keywords->name) { > + if (strcmp (arg_str, keywords->name) == 0) { > + if (arg_desc->output_var) { > + *((int *)arg_desc->output_var) = keywords->value; > + } So if ->output_var is NULL, the parameter is accepted but silently ignored? I'm not sure if I should consider this a feature or a bug. :) This applies below in similar places; I'll not repeat myself. > + return TRUE; > + } > + keywords++; > +} > +fprintf (stderr, "unknown keyword: %s\n", arg_str); > +return FALSE; > +} > + > +/* > + Search for the {pos_arg_index}th position argument, return FALSE if > + that does not exist. > +*/ > + > +notmuch_bool_t > +parse_position_arg (const char *arg_str, int pos_arg_index, const > notmuch_opt_desc_t *arg_desc) { > + > +int pos_arg_counter = 0; > +while (arg_desc->name){ > + if (arg_desc->opt_type == NOTMUCH_OPT_POSITION) { > + if (pos_arg_counter == pos_arg_index) { > + if (arg_desc->output_var) { > + *((const char **)arg_desc->output_var) = arg_str; > + } > + return TRUE; > + } > + pos_arg_counter++; > + } > + arg_desc++; > +} > +return FALSE; > +} > + > +notmuch_bool_t > +parse_option (const char *arg, > + const notmuch_opt_desc_t *options){ Missing space between ) and {. > + > +assert(arg); > +assert(options); > + > +arg += 2; > + > +const notmuch_opt_desc_t *try = options; > +while (try->name) { > + if (strncmp (arg, try->name, strlen(try->name)) == 0) { I think here you should check that arg[strlen(try->name)] is '=' or ':' for NOTMUCH_OPT_KEYWORD and NOTMUCH_OPT_INT, and '\0' otherwise. After the check, you could pass just the value part to _process_keyword_arg(). I can't figure out if and how you handle arguments with arbitrary string values (for example --file=/path/to/file). You do specify --in-file and --out-file in later patches, but those are with NOTMUCH_OPT_POSITION, which, AFAICT, would fall in the internal error path below. They'll *only* be handled as positional arguments, not option args. I'm not sure if much weight should be put to getopt_long() compatibility, but it accepts "--parameter value" as well as "--parameter=value". > + > + switch (try->opt_type) { > + case NOTMUCH_OPT_KEYWORD: > + return
[PATCH v3 0/2] notmuch hooks
On Tue, 06 Dec 2011 18:47:01 -0800, Jameson Graef Rollins wrote: > Also, what if we make it so that the post-new hook script only runs if > notmuch new processes new messages? All of my post-new functions don't > need to be run at all if there is no new mail. Or would it make sense to pass this information to the hook somehow? I currently run 'git pull && notmuch new && git commit && git push" or so ... Tom
[PATCH] fix format string in Message.__unicode__
Since 2b0116119160f2dc83, Message.__str__ doesn't construct a hash containing the thread data before constructing the formatstring. This changes the formatstring to accept positional parameters instead of a hash. --- bindings/python/notmuch/message.py |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/bindings/python/notmuch/message.py b/bindings/python/notmuch/message.py index f95e50e..ce8e718 100644 --- a/bindings/python/notmuch/message.py +++ b/bindings/python/notmuch/message.py @@ -799,7 +799,7 @@ class Message(object): return unicode(self).encode('utf-8') def __unicode__(self): -format = "%(from)s (%(date)s) (%(tags)s)" +format = "%s (%s) (%s)" return format % (self.get_header('from'), self.get_tags(), date.fromtimestamp(self.get_date()), -- 1.7.4.1
fix error introduced in pushed patch
Hi, A friend of mine just complained about an issue he had with upstream notmuch python that is due to my recent reformating of Message.__str__. This patch fixes it. Sorry for the inconveniences, /p
notmuch release 0.10.2 now available
Where to obtain notmuch 0.10.2 === http://notmuchmail.org/releases/notmuch-0.10.2.tar.gz Which can be verified with: http://notmuchmail.org/releases/notmuch-0.10.2.tar.gz.sha1 3064c1722d30c71f287e1ab63ac13a5847e20c14 notmuch-0.10.2.tar.gz http://notmuchmail.org/releases/notmuch-0.10.2.tar.gz.sha1.asc (signed by David Bremner) What's new in notmuch 0.10.2 = Bug-fix release. Fix crash in python bindings. The python bindings did not call g_type_init, which caused crashes for some, but not all users. What is notmuch === Notmuch is a system for indexing, searching, reading, and tagging large collections of email messages in maildir or mh format. It uses the Xapian library to provide fast, full-text search with a convenient search syntax. For more about notmuch, see http://notmuchmail.org -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 315 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20111206/6009fe79/attachment.pgp>
[PATCH v3 0/2] notmuch hooks
Also, what if we make it so that the post-new hook script only runs if notmuch new processes new messages? All of my post-new functions don't need to be run at all if there is no new mail. jamie. -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 835 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20111206/5219bbdd/attachment.pgp>
[PATCH v3 0/2] notmuch hooks
On Tue, 6 Dec 2011 15:22:36 +0200, Jani Nikula wrote: > Hi all, this is v3 of the notmuch hooks patches. I think this is nearing > completion apart from final review and, most notably, tests. Hey, Jani. Thanks so much for these patches. I think this is a really neat idea and it will be very useful. I already know that this will cut out a lot of extraneous shell scripting that I'm relying on now. > I've been using this for some days now, and (subjective as it is) I have to > say > I like offlineimap being run from notmuch new "pre-new" hook much better than > vice versa. Even more so for "post-new" tagging scripts. I think the only thing that I was not particularly clear about is that I guess the "pre-new" and "post-new" scripts actually need to be scripts named "pre-new" and "post-new" in the hooks directory. For some reason I didn't quite grok that from the help pages, and was confused if I needed to make a new "pre-new" subdirectory in the hooks directory or what. I think just expecting a script at hook/pre-new is fine, but it maybe could be made a little more explicit in the documentation. In fact, I think the best thing would actually be for notmuch new to make the .notmuch/hooks directory itself and to pre-fill it with "turned off" hook scripts that contain some useful comments on how to use them. This is what git does, and I think it's very handy, since it's all fairly self documenting. The notmuch help could then just refer to the fact that they're there, and point people to the comments in the various scripts for how to use them. jamie. -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 835 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20111206/31bc3e3e/attachment.pgp>
ANNOUNCE: nottoomuch-addresses.pl
Hi Tomi, I made the changes for case insensitivity and I much prefer that. Perhaps it could be an option if you like it the other way around. Kind regards Bart
[PATCH v3 1/2] cli: introduce the concept of user defined hooks
On Tue, 6 Dec 2011 15:22:37 +0200, Jani Nikula wrote: > +if (!WIFEXITED (status) || WEXITSTATUS (status)) { > + if (WEXITSTATUS (status)) { Grrh, the above should be "if (WIFEXITED (status))". Please review otherwise. Jani. > + fprintf (stderr, "Error: %s hook failed with status %d\n", > + hook, WEXITSTATUS (status)); > + } else if (WIFSIGNALED (status)) { > + fprintf (stderr, "Error: %s hook terminated with signal %d\n", > + hook, WTERMSIG (status)); > + } > + status = 1; > +}
[PATCH v3 2/2] cli: add support for pre and post notmuch new hooks
Run notmuch new pre and post hooks, named "pre-new" and "post-new", if present in the notmuch hooks directory. The hooks will be run before and after incorporating new messages to the database. Typical use cases for pre-new and post-new hooks are fetching or delivering new mail to the maildir, and custom tagging of the mail incorporated to the database. Also add command line option --no-hooks to notmuch new to bypass the hooks. Signed-off-by: Jani Nikula --- NEWS | 10 ++ notmuch-new.c | 12 notmuch.1 | 50 +- notmuch.c | 39 ++- 4 files changed, 109 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 2b2f08a..a7c13a8 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,16 @@ Notmuch 0.11 (201x-xx-xx) = +New command-line features +- + +Hooks + + Hooks have been introduced to notmuch. Hooks are scripts that notmuch + invokes before and after certain actions. Initially, "notmuch new" + supports "pre-new" and "post-new" hooks that are run before and after + importing new messages into the database. + Performance --- diff --git a/notmuch-new.c b/notmuch-new.c index 81a9350..bfb4600 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -811,6 +811,7 @@ notmuch_new_command (void *ctx, int argc, char *argv[]) _filename_node_t *f; int i; notmuch_bool_t timer_is_active = FALSE; +notmuch_bool_t run_hooks = TRUE; add_files_state.verbose = 0; add_files_state.output_is_a_tty = isatty (fileno (stdout)); @@ -820,6 +821,8 @@ notmuch_new_command (void *ctx, int argc, char *argv[]) for (i = 0; i < argc && argv[i][0] == '-'; i++) { if (STRNCMP_LITERAL (argv[i], "--verbose") == 0) { add_files_state.verbose = 1; + } else if (strcmp (argv[i], "--no-hooks") == 0) { + run_hooks = FALSE; } else { fprintf (stderr, "Unrecognized option: %s\n", argv[i]); return 1; @@ -833,6 +836,12 @@ notmuch_new_command (void *ctx, int argc, char *argv[]) add_files_state.synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config); db_path = notmuch_config_get_database_path (config); +if (run_hooks) { + ret = notmuch_run_hook (db_path, "pre-new"); + if (ret) + return ret; +} + dot_notmuch_path = talloc_asprintf (ctx, "%s/%s", db_path, ".notmuch"); if (stat (dot_notmuch_path, )) { @@ -981,5 +990,8 @@ notmuch_new_command (void *ctx, int argc, char *argv[]) notmuch_database_close (notmuch); +if (run_hooks && !ret && !interrupted) + ret = notmuch_run_hook (db_path, "post-new"); + return ret || interrupted; } diff --git a/notmuch.1 b/notmuch.1 index 92931d7..f631a5e 100644 --- a/notmuch.1 +++ b/notmuch.1 @@ -85,7 +85,7 @@ The command is used to incorporate new mail into the notmuch database. .RS 4 .TP 4 -.B new +.BR new " [options...]" Find and import any new messages to the database. @@ -118,6 +118,22 @@ if has previously been completed, but .B "notmuch new" has not previously been run. + +The +.B new +command supports hooks. See the +.B "HOOKS" +section below for more details on hooks. + +Supported options for +.B new +include +.RS 4 +.TP 4 +.BR \-\-no\-hooks + +Prevents hooks from being run. +.RE .RE Several of the notmuch commands accept search terms with a common @@ -705,6 +721,38 @@ specify a date range to return messages from 2009\-10\-01 until the current time: $(date +%s \-d 2009\-10\-01)..$(date +%s) +.SH HOOKS +Hooks are scripts (or arbitrary executables or symlinks to such) that notmuch +invokes before and after certain actions. These scripts reside in +the .notmuch/hooks directory within the database directory and must have +executable permissions. + +The currently available hooks are described below. +.RS 4 +.TP 4 +.B pre\-new +This hook is invoked by the +.B new +command before scanning or importing new messages into the database. If this +hook exits with a non-zero status, notmuch will abort further processing of the +.B new +command. + +Typically this hook is used for fetching or delivering new mail to be imported +into the database. +.RE +.RS 4 +.TP 4 +.B post\-new +This hook is invoked by the +.B new +command after new messages have been imported into the database and initial tags +have been applied. The hook will not be run if there have been any errors during +the scan or import. + +Typically this hook is used to perform additional query\-based tagging on the +imported messages. +.RE .SH ENVIRONMENT The following environment variables can be used to control the behavior of notmuch. diff --git a/notmuch.c b/notmuch.c index d44ce9a..c0ce026 100644 --- a/notmuch.c +++ b/notmuch.c @@ -127,6 +127,32 @@ static const char search_terms_help[] = "\n" "\t\t$(date +%%s -d 2009-10-01)..$(date +%%s)\n\n"; +static const char
[PATCH v3 1/2] cli: introduce the concept of user defined hooks
Add mechanism for running user defined hooks. Hooks are executables or symlinks to executables stored under the new notmuch hooks directory, /.notmuch/hooks. No hooks are introduced here, but adding support for a hook is now a simple matter of calling the new notmuch_run_hook() function at an appropriate location with the hook name. Signed-off-by: Jani Nikula --- Makefile.local |1 + hooks.c | 93 ++ notmuch-client.h |3 ++ 3 files changed, 97 insertions(+), 0 deletions(-) create mode 100644 hooks.c diff --git a/Makefile.local b/Makefile.local index c94402b..60ae9cb 100644 --- a/Makefile.local +++ b/Makefile.local @@ -298,6 +298,7 @@ notmuch_client_srcs = \ debugger.c \ gmime-filter-reply.c\ gmime-filter-headers.c \ + hooks.c \ notmuch.c \ notmuch-config.c\ notmuch-count.c \ diff --git a/hooks.c b/hooks.c new file mode 100644 index 000..c2d59c1 --- /dev/null +++ b/hooks.c @@ -0,0 +1,93 @@ +/* notmuch - Not much of an email program, (just index and search) + * + * This file is part of notmuch. + * + * Copyright ? 2011 Jani Nikula + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ . + * + * Author: Jani Nikula + */ + +#include "notmuch-client.h" +#include + +int +notmuch_run_hook (const char *db_path, const char *hook) +{ +char *hook_path; +int status = 0; +pid_t pid; + +hook_path = talloc_asprintf (NULL, "%s/%s/%s/%s", db_path, ".notmuch", +"hooks", hook); +if (hook_path == NULL) { + fprintf (stderr, "Out of memory\n"); + return 1; +} + +/* Check access before fork() for speed and simplicity of error handling. */ +if (access (hook_path, X_OK) == -1) { + /* Ignore ENOENT. It's okay not to have a hook, hook dir, or even +* notmuch dir. Dangling symbolic links also result in ENOENT, but +* we'll ignore that too for simplicity. */ + if (errno != ENOENT) { + fprintf (stderr, "Error: %s hook access failed: %s\n", hook, +strerror (errno)); + status = 1; + } + goto DONE; +} + +pid = fork(); +if (pid == -1) { + fprintf (stderr, "Error: %s hook fork failed: %s\n", hook, +strerror (errno)); + status = 1; + goto DONE; +} else if (pid == 0) { + execl (hook_path, hook_path, NULL); + /* Same as above for ENOENT, but unlikely now. Indicate all other errors +* to parent through non-zero exit status. */ + if (errno != ENOENT) { + fprintf (stderr, "Error: %s hook execution failed: %s\n", hook, +strerror (errno)); + status = 1; + } + exit (status); +} + +if (waitpid (pid, , 0) == -1) { + fprintf (stderr, "Error: %s hook wait failed: %s\n", hook, +strerror (errno)); + status = 1; + goto DONE; +} + +if (!WIFEXITED (status) || WEXITSTATUS (status)) { + if (WEXITSTATUS (status)) { + fprintf (stderr, "Error: %s hook failed with status %d\n", +hook, WEXITSTATUS (status)); + } else if (WIFSIGNALED (status)) { + fprintf (stderr, "Error: %s hook terminated with signal %d\n", +hook, WTERMSIG (status)); + } + status = 1; +} + + DONE: +talloc_free (hook_path); + +return status; +} diff --git a/notmuch-client.h b/notmuch-client.h index b50cb38..a91ad6c 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -235,6 +235,9 @@ void notmuch_config_set_maildir_synchronize_flags (notmuch_config_t *config, notmuch_bool_t synchronize_flags); +int +notmuch_run_hook (const char *db_path, const char *hook); + notmuch_bool_t debugger_is_active (void); -- 1.7.5.4
[PATCH v3 0/2] notmuch hooks
Hi all, this is v3 of the notmuch hooks patches. I think this is nearing completion apart from final review and, most notably, tests. Changes in v3: * Incorporate Austin's review comments (id:"20111204034210.GA16405 at mit.edu" and id:"20111204040047.GB16405 at mit.edu"), the biggest change being the switch from system() to fork()/execl(). * Rename notmuch-hook.c to hooks.c (reserving notmuch- prefixed files to notmuch commands). * Add "notmuch help" documentation. * Add NEWS. I've been using this for some days now, and (subjective as it is) I have to say I like offlineimap being run from notmuch new "pre-new" hook much better than vice versa. Even more so for "post-new" tagging scripts. BR, Jani. Jani Nikula (2): cli: introduce the concept of user defined hooks cli: add support for pre and post notmuch new hooks Makefile.local |1 + NEWS | 10 ++ hooks.c | 93 ++ notmuch-client.h |3 ++ notmuch-new.c| 12 +++ notmuch.1| 50 - notmuch.c| 39 ++- 7 files changed, 206 insertions(+), 2 deletions(-) create mode 100644 hooks.c -- 1.7.5.4
[PATCH 3/3] errors='ignore' when decode to unicode
Just for reference, all three patches went in. Perhaps this warrants a NEWS entry such as: * python: using more unicode throughout and robustify against unicode errors (credits to Patrick Totzke) -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20111206/58df338e/attachment.pgp>
[python] documentation & TODO list
On Mon, 05 Dec 2011 22:36:06 +, Patrick Totzke wrote: > These are the things I noticed when going through the code today: > 1) in filenames.py, __str__ of Filenames: should the return value be >'\n'.join(self._files)? alternatively, define __iter__ to make this object >behave as iterator. To be honest, I don't remember why the code looks the way it looks, but it certainly is not right like this. Defining __iter__ sounds like a correct thing to me, but it could be that there was some reason why I don't have it... Feel free to implement a working __iter__ and provide a patch :-). > 2) in message.py: tags_to_maildir_flags and maildir_flags_to_tags never > return a >:class:`STATUS` as advertised. But it has been doing that for, , 1 minute :-) [master ecf8da3] python: Return a STATUS value in tags_to_flags and flags_to_tags (thanks) > I would like to see up-to-date API docs online, even if only the > version string changed. > Sebastian suggested using readthedocs.org for building and hosting APIdocs. I currently manually upload a generated API doc to the packages.python.org website. I kind of like that address because it sounds official ;-), but it is manual work. I am currently not looking into expending the efforts I have to do on python notmuch. So setting > I tested this recently for alot and it looks quite promising. > A simple http get and their build-host checks out the new sources from git > and builds > them. This could be easily integrated into notmuch the release process. > Comments on this? I think that it would be cool to have that automatically been done on notmuchmail.org. But given that it takes some work to set that up and readthedocs.org is already there, I am all for using that for now. > Lastly, does anyone have an opinion on how to share a TODO list/issue tracker > for the bindings? I'm OK with github, we could move all this to the list > and use David's nmbug.. Ohh, there is already notmuch::python in nmbug :-) Sebastian -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20111206/08dbb04d/attachment.pgp>
[PATCH 2/2] python: annotate all calls into libnotmuch with types
On Tue, 06 Dec 2011 10:46:31 +, Patrick Totzke wrote: > This commit breaks raising XapianErrors for me. > > If I lock the index with some `notmuch tag +test '*'` > and try to write to it in alot, i get a segfault and > the following on stderr: > > Xapian exception occurred opening database: Unable to get write lock on > /home/pazz/mail/.notmuch/xapian: already locked Hi Justus, I can confirm that this patch breaks as Totzke has described it: http://git.notmuchmail.org/git/notmuch/commitdiff/3434d194026ff65217d9342ffe511f67fd71e79f This change makes python segfault with a Xapianerror on stdout rather than the python exception that we were seeing before this patch. - _open.restype = c_void_p + _open.restype = NotmuchDatabaseP As the patch obviously fixed other crashers I would like to not revert it. Can you have a look and see if you find a cause of that? Sebastian -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20111206/9f0ffc2b/attachment.pgp>
[PATCH] lib: call g_type_init from notmuch_database_open
On Sun, 4 Dec 2011 15:35:14 -0400, David Bremner wrote: > From: David Bremner > This seems to fix the segfault for me. Any other comments/experiences? > +/* Initialize the GLib type system and threads */ > +g_type_init (); > + Thanks the patch looks sane, and relieves me from doing ugly things with gmime from the python side of things. +1 Sebastian -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20111206/06ebc245/attachment.pgp>
[PATCH 2/2] python: annotate all calls into libnotmuch with types
On Tue, 06 Dec 2011 10:46:31 +, Patrick Totzke wrote: > This commit breaks raising XapianErrors for me. > > If I lock the index with some `notmuch tag +test '*'` > and try to write to it in alot, i get a segfault and > the following on stderr: > > Xapian exception occurred opening database: Unable to get write lock on > /home/pazz/mail/.notmuch/xapian: already locked Can you confirm that this only occurs with this patch and not without? To be honest, I don't see how the patch would change things in a way that make it throw XapianErrors that would not also occur before this patch. Sebastian -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20111206/23b3e233/attachment.pgp>
Re: [PATCH 2/2] python: annotate all calls into libnotmuch with types
yes, i can. here's how to reproduce it on master: fire a `notmuch tag +TEST1 '*'`, which should block the db for a while. Then use the attached script to write to the index (this could make a nice second testcase for the bindings in case the test body is large enough). On master, the script fails like this: A Xapian exception occurred opening database: Unable to get write lock on /home/pazz/mail/.notmuch/xapian: already locked Segmentation fault When you reset using `git reset e92b438f46a3a` (to 4winters first patch), the script fails like this, which is the intended behaviour: A Xapian exception occurred opening database: Unable to get write lock on /home/pazz/mail/.notmuch/xapian: already locked Traceback (most recent call last): File "./p.py", line 3, in db = notmuch.Database(mode=notmuch.Database.MODE.READ_WRITE) File "/usr/local/lib/python2.7/dist-packages/notmuch/database.py", line 121, in __init__ self.open(path, mode) File "/usr/local/lib/python2.7/dist-packages/notmuch/database.py", line 173, in open raise NotmuchError(message="Could not open the specified database") notmuch.globals.NotmuchError: Could not open the specified database best, /p Quoting Sebastian Spaeth (2011-12-06 11:12:42) >On Tue, 06 Dec 2011 10:46:31 +, Patrick Totzke googlemail.com> wrote: >> This commit breaks raising XapianErrors for me. >> >> If I lock the index with some `notmuch tag +test '*'` >> and try to write to it in alot, i get a segfault and >> the following on stderr: >> >> Xapian exception occurred opening database: Unable to get write lock on >> /home/pazz/mail/.notmuch/xapian: already locked > >Can you confirm that this only occurs with this patch and not without? >To be honest, I don't see how the patch would change things in a way >that make it throw XapianErrors that would not also occur before this >patch. > >Sebastian -- next part -- A non-text attachment was scrubbed... Name: exceptiontest.py Type: text/x-python Size: 181 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20111206/9fc1327c/attachment-0001.py>
[PATCH] python: use wrapped notmuch_*_t types instead of raw pointers
Now that types are checked correctly, we also need to make sure that all the arguments actually are instances of these types. Otherwise the function calls will fail and raise an exception similar to this one: ctypes.ArgumentError: argument 3: : expected LP_LP_NotmuchMessageS instance instead of pointer to c_void_p --- bindings/python/notmuch/database.py |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py index 25b4b1b..c24555e 100644 --- a/bindings/python/notmuch/database.py +++ b/bindings/python/notmuch/database.py @@ -378,7 +378,7 @@ class Database(object): be added. """ self._assert_db_is_initialized() -msg_p = c_void_p() +msg_p = NotmuchMessageP() status = self._add_message(self._db, _str(filename), byref(msg_p)) if not status in [STATUS.SUCCESS, STATUS.DUPLICATE_MESSAGE_ID]: @@ -446,7 +446,7 @@ class Database(object): the database was not intitialized. """ self._assert_db_is_initialized() -msg_p = c_void_p() +msg_p = NotmuchMessageP() status = Database._find_message(self._db, _str(msgid), byref(msg_p)) if status != STATUS.SUCCESS: raise NotmuchError(status) @@ -479,7 +479,7 @@ class Database(object): *Added in notmuch 0.9*""" self._assert_db_is_initialized() -msg_p = c_void_p() +msg_p = NotmuchMessageP() status = Database._find_message_by_filename(self._db, _str(filename), byref(msg_p)) if status != STATUS.SUCCESS: -- 1.7.7.4
Re: [PATCH 2/2] python: annotate all calls into libnotmuch with types
This commit breaks raising XapianErrors for me. If I lock the index with some `notmuch tag +test '*'` and try to write to it in alot, i get a segfault and the following on stderr: Xapian exception occurred opening database: Unable to get write lock on /home/pazz/mail/.notmuch/xapian: already locked /p
[PATCH] make release: remove LATEST-$(PACKAGE)-*
On Mon, 05 Dec 2011 13:39:32 +0200, Tomi Ollila wrote: > The tar file of particular package (notmuch in this case) is named > as $(PACKAGE)-$(VERSION).tar.gz. Therefore the best way to remove > previous link to LATEST is to remove all files beginning with > LATEST-$(PACKAGE)- and not relying how $(VERSION) string is constructed. > --- > > Applies on top of id:"yf6ty5ttfs2.fsf at taco2.nixu.fi" Both are pushed to master. d
[PATCH] test: add test-binaries target
On Sun, 4 Dec 2011 11:58:49 -0400, David Bremner wrote: > From: David Bremner > > The goal here is to have a simple way of making sure all of the > binaries needed to run tests are available. Pushed to master d
ANNOUNCE: nottoomuch-addresses.pl
Hi, I agree with Jamie on this one. The case sensitivity appears to get in the way of searching. I also think that enabling the regular expressionsearching is a good idea. All in all though this is great. The only other idea I have, which is only half formed, is that it would be nice to prioritize emails that are more important than others. I'm not sure exactly how this would work but something like: - Addresses I have actualy sent email to rather than jjust received from get a high priority in the result. - Addresses that have sent me email directly rather than just to a list get next priority. - All other emails after that. Also some sort of weighting within the groups to do with frequency of emails sent or something. Does that make sense? Would it be hard to implement? Cheers Bart > On Mon, 05 Dec 2011 14:35:03 +0200, Tomi Ollila wrote: > > Yes, the search is deliberately case sensitive. > > I haven't had a chance to play around with this but I will say that it > makes more sense to me that this kind of search should deliberately be > case *in*sensitive. Case sensitivity seems fairly detrimental here, > actually, considering there is no consistency in case in names or email > addresses. > > jamie.
[PATCH] python: use wrapped notmuch_*_t types instead of raw pointers
Now that types are checked correctly, we also need to make sure that all the arguments actually are instances of these types. Otherwise the function calls will fail and raise an exception similar to this one: ctypes.ArgumentError: argument 3: type 'exceptions.TypeError': expected LP_LP_NotmuchMessageS instance instead of pointer to c_void_p --- bindings/python/notmuch/database.py |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py index 25b4b1b..c24555e 100644 --- a/bindings/python/notmuch/database.py +++ b/bindings/python/notmuch/database.py @@ -378,7 +378,7 @@ class Database(object): be added. self._assert_db_is_initialized() -msg_p = c_void_p() +msg_p = NotmuchMessageP() status = self._add_message(self._db, _str(filename), byref(msg_p)) if not status in [STATUS.SUCCESS, STATUS.DUPLICATE_MESSAGE_ID]: @@ -446,7 +446,7 @@ class Database(object): the database was not intitialized. self._assert_db_is_initialized() -msg_p = c_void_p() +msg_p = NotmuchMessageP() status = Database._find_message(self._db, _str(msgid), byref(msg_p)) if status != STATUS.SUCCESS: raise NotmuchError(status) @@ -479,7 +479,7 @@ class Database(object): *Added in notmuch 0.9* self._assert_db_is_initialized() -msg_p = c_void_p() +msg_p = NotmuchMessageP() status = Database._find_message_by_filename(self._db, _str(filename), byref(msg_p)) if status != STATUS.SUCCESS: -- 1.7.7.4 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 2/2] python: annotate all calls into libnotmuch with types
This commit breaks raising XapianErrors for me. If I lock the index with some `notmuch tag +test '*'` and try to write to it in alot, i get a segfault and the following on stderr: Xapian exception occurred opening database: Unable to get write lock on /home/pazz/mail/.notmuch/xapian: already locked /p ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 2/2] python: annotate all calls into libnotmuch with types
On Tue, 06 Dec 2011 10:46:31 +, Patrick Totzke patricktot...@googlemail.com wrote: This commit breaks raising XapianErrors for me. If I lock the index with some `notmuch tag +test '*'` and try to write to it in alot, i get a segfault and the following on stderr: Xapian exception occurred opening database: Unable to get write lock on /home/pazz/mail/.notmuch/xapian: already locked Can you confirm that this only occurs with this patch and not without? To be honest, I don't see how the patch would change things in a way that make it throw XapianErrors that would not also occur before this patch. Sebastian pgpNwJ881bCzM.pgp Description: PGP signature ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH] lib: call g_type_init from notmuch_database_open
On Sun, 4 Dec 2011 15:35:14 -0400, David Bremner da...@tethera.net wrote: From: David Bremner brem...@debian.org This seems to fix the segfault for me. Any other comments/experiences? +/* Initialize the GLib type system and threads */ +g_type_init (); + Thanks the patch looks sane, and relieves me from doing ugly things with gmime from the python side of things. +1 Sebastian pgpoL5xlHakVZ.pgp Description: PGP signature ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 2/2] python: annotate all calls into libnotmuch with types
yes, i can. here's how to reproduce it on master: fire a `notmuch tag +TEST1 '*'`, which should block the db for a while. Then use the attached script to write to the index (this could make a nice second testcase for the bindings in case the test body is large enough). On master, the script fails like this: A Xapian exception occurred opening database: Unable to get write lock on /home/pazz/mail/.notmuch/xapian: already locked Segmentation fault When you reset using `git reset e92b438f46a3a` (to 4winters first patch), the script fails like this, which is the intended behaviour: A Xapian exception occurred opening database: Unable to get write lock on /home/pazz/mail/.notmuch/xapian: already locked Traceback (most recent call last): File ./p.py, line 3, in module db = notmuch.Database(mode=notmuch.Database.MODE.READ_WRITE) File /usr/local/lib/python2.7/dist-packages/notmuch/database.py, line 121, in __init__ self.open(path, mode) File /usr/local/lib/python2.7/dist-packages/notmuch/database.py, line 173, in open raise NotmuchError(message=Could not open the specified database) notmuch.globals.NotmuchError: Could not open the specified database best, /p Quoting Sebastian Spaeth (2011-12-06 11:12:42) On Tue, 06 Dec 2011 10:46:31 +, Patrick Totzke patricktot...@googlemail.com wrote: This commit breaks raising XapianErrors for me. If I lock the index with some `notmuch tag +test '*'` and try to write to it in alot, i get a segfault and the following on stderr: Xapian exception occurred opening database: Unable to get write lock on /home/pazz/mail/.notmuch/xapian: already locked Can you confirm that this only occurs with this patch and not without? To be honest, I don't see how the patch would change things in a way that make it throw XapianErrors that would not also occur before this patch. Sebastian #!/usr/bin/python import notmuch db = notmuch.Database(mode=notmuch.Database.MODE.READ_WRITE) q_new = notmuch.Query(db, '*') for m in q_new.search_messages(): m.add_tag('TEST') ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 2/2] python: annotate all calls into libnotmuch with types
On Tue, 06 Dec 2011 10:46:31 +, Patrick Totzke patricktot...@googlemail.com wrote: This commit breaks raising XapianErrors for me. If I lock the index with some `notmuch tag +test '*'` and try to write to it in alot, i get a segfault and the following on stderr: Xapian exception occurred opening database: Unable to get write lock on /home/pazz/mail/.notmuch/xapian: already locked Hi Justus, I can confirm that this patch breaks as Totzke has described it: http://git.notmuchmail.org/git/notmuch/commitdiff/3434d194026ff65217d9342ffe511f67fd71e79f This change makes python segfault with a Xapianerror on stdout rather than the python exception that we were seeing before this patch. - _open.restype = c_void_p + _open.restype = NotmuchDatabaseP As the patch obviously fixed other crashers I would like to not revert it. Can you have a look and see if you find a cause of that? Sebastian pgpZCeuOyXxgz.pgp Description: PGP signature ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [python] documentation TODO list
On Mon, 05 Dec 2011 22:36:06 +, Patrick Totzke wrote: These are the things I noticed when going through the code today: 1) in filenames.py, __str__ of Filenames: should the return value be '\n'.join(self._files)? alternatively, define __iter__ to make this object behave as iterator. To be honest, I don't remember why the code looks the way it looks, but it certainly is not right like this. Defining __iter__ sounds like a correct thing to me, but it could be that there was some reason why I don't have it... Feel free to implement a working __iter__ and provide a patch :-). 2) in message.py: tags_to_maildir_flags and maildir_flags_to_tags never return a :class:`STATUS` as advertised. But it has been doing that for, , 1 minute :-) [master ecf8da3] python: Return a STATUS value in tags_to_flags and flags_to_tags (thanks) I would like to see up-to-date API docs online, even if only the version string changed. Sebastian suggested using readthedocs.org for building and hosting APIdocs. I currently manually upload a generated API doc to the packages.python.org website. I kind of like that address because it sounds official ;-), but it is manual work. I am currently not looking into expending the efforts I have to do on python notmuch. So setting I tested this recently for alot and it looks quite promising. A simple http get and their build-host checks out the new sources from git and builds them. This could be easily integrated into notmuch the release process. Comments on this? I think that it would be cool to have that automatically been done on notmuchmail.org. But given that it takes some work to set that up and readthedocs.org is already there, I am all for using that for now. Lastly, does anyone have an opinion on how to share a TODO list/issue tracker for the bindings? I'm OK with github, we could move all this to the list and use David's nmbug.. Ohh, there is already notmuch::python in nmbug :-) Sebastian pgpvmNwxDccJY.pgp Description: PGP signature ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 3/3] errors='ignore' when decode to unicode
Just for reference, all three patches went in. Perhaps this warrants a NEWS entry such as: * python: using more unicode throughout and robustify against unicode errors (credits to Patrick Totzke) pgpFR77WcaGxT.pgp Description: PGP signature ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH] python: use wrapped notmuch_*_t types instead of raw pointers
On Tue, 6 Dec 2011 11:03:22 +0100, Thomas Jost schno...@schnouki.net wrote: Now that types are checked correctly, we also need to make sure that all the arguments actually are instances of these types. Otherwise the function calls will fail and raise an exception similar to this one: ctypes.ArgumentError: argument 3: type 'exceptions.TypeError': expected LP_LP_NotmuchMessageS instance instead of pointer to c_void_p Thanks, Pushed. pgp93DlM2WzJn.pgp Description: PGP signature ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v3 1/2] cli: introduce the concept of user defined hooks
Add mechanism for running user defined hooks. Hooks are executables or symlinks to executables stored under the new notmuch hooks directory, database-path/.notmuch/hooks. No hooks are introduced here, but adding support for a hook is now a simple matter of calling the new notmuch_run_hook() function at an appropriate location with the hook name. Signed-off-by: Jani Nikula j...@nikula.org --- Makefile.local |1 + hooks.c | 93 ++ notmuch-client.h |3 ++ 3 files changed, 97 insertions(+), 0 deletions(-) create mode 100644 hooks.c diff --git a/Makefile.local b/Makefile.local index c94402b..60ae9cb 100644 --- a/Makefile.local +++ b/Makefile.local @@ -298,6 +298,7 @@ notmuch_client_srcs = \ debugger.c \ gmime-filter-reply.c\ gmime-filter-headers.c \ + hooks.c \ notmuch.c \ notmuch-config.c\ notmuch-count.c \ diff --git a/hooks.c b/hooks.c new file mode 100644 index 000..c2d59c1 --- /dev/null +++ b/hooks.c @@ -0,0 +1,93 @@ +/* notmuch - Not much of an email program, (just index and search) + * + * This file is part of notmuch. + * + * Copyright © 2011 Jani Nikula + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/ . + * + * Author: Jani Nikula j...@nikula.org + */ + +#include notmuch-client.h +#include sys/wait.h + +int +notmuch_run_hook (const char *db_path, const char *hook) +{ +char *hook_path; +int status = 0; +pid_t pid; + +hook_path = talloc_asprintf (NULL, %s/%s/%s/%s, db_path, .notmuch, +hooks, hook); +if (hook_path == NULL) { + fprintf (stderr, Out of memory\n); + return 1; +} + +/* Check access before fork() for speed and simplicity of error handling. */ +if (access (hook_path, X_OK) == -1) { + /* Ignore ENOENT. It's okay not to have a hook, hook dir, or even +* notmuch dir. Dangling symbolic links also result in ENOENT, but +* we'll ignore that too for simplicity. */ + if (errno != ENOENT) { + fprintf (stderr, Error: %s hook access failed: %s\n, hook, +strerror (errno)); + status = 1; + } + goto DONE; +} + +pid = fork(); +if (pid == -1) { + fprintf (stderr, Error: %s hook fork failed: %s\n, hook, +strerror (errno)); + status = 1; + goto DONE; +} else if (pid == 0) { + execl (hook_path, hook_path, NULL); + /* Same as above for ENOENT, but unlikely now. Indicate all other errors +* to parent through non-zero exit status. */ + if (errno != ENOENT) { + fprintf (stderr, Error: %s hook execution failed: %s\n, hook, +strerror (errno)); + status = 1; + } + exit (status); +} + +if (waitpid (pid, status, 0) == -1) { + fprintf (stderr, Error: %s hook wait failed: %s\n, hook, +strerror (errno)); + status = 1; + goto DONE; +} + +if (!WIFEXITED (status) || WEXITSTATUS (status)) { + if (WEXITSTATUS (status)) { + fprintf (stderr, Error: %s hook failed with status %d\n, +hook, WEXITSTATUS (status)); + } else if (WIFSIGNALED (status)) { + fprintf (stderr, Error: %s hook terminated with signal %d\n, +hook, WTERMSIG (status)); + } + status = 1; +} + + DONE: +talloc_free (hook_path); + +return status; +} diff --git a/notmuch-client.h b/notmuch-client.h index b50cb38..a91ad6c 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -235,6 +235,9 @@ void notmuch_config_set_maildir_synchronize_flags (notmuch_config_t *config, notmuch_bool_t synchronize_flags); +int +notmuch_run_hook (const char *db_path, const char *hook); + notmuch_bool_t debugger_is_active (void); -- 1.7.5.4 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v3 1/2] cli: introduce the concept of user defined hooks
On Tue, 6 Dec 2011 15:22:37 +0200, Jani Nikula j...@nikula.org wrote: +if (!WIFEXITED (status) || WEXITSTATUS (status)) { + if (WEXITSTATUS (status)) { Grrh, the above should be if (WIFEXITED (status)). Please review otherwise. Jani. + fprintf (stderr, Error: %s hook failed with status %d\n, + hook, WEXITSTATUS (status)); + } else if (WIFSIGNALED (status)) { + fprintf (stderr, Error: %s hook terminated with signal %d\n, + hook, WTERMSIG (status)); + } + status = 1; +} ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH] test: add test-binaries target
On Sun, 4 Dec 2011 11:58:49 -0400, David Bremner da...@tethera.net wrote: From: David Bremner brem...@debian.org The goal here is to have a simple way of making sure all of the binaries needed to run tests are available. Pushed to master d ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH] make release: remove LATEST-$(PACKAGE)-*
On Mon, 05 Dec 2011 13:39:32 +0200, Tomi Ollila tomi.oll...@iki.fi wrote: The tar file of particular package (notmuch in this case) is named as $(PACKAGE)-$(VERSION).tar.gz. Therefore the best way to remove previous link to LATEST is to remove all files beginning with LATEST-$(PACKAGE)- and not relying how $(VERSION) string is constructed. --- Applies on top of id:yf6ty5ttfs2@taco2.nixu.fi Both are pushed to master. d ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
fix error introduced in pushed patch
Hi, A friend of mine just complained about an issue he had with upstream notmuch python that is due to my recent reformating of Message.__str__. This patch fixes it. Sorry for the inconveniences, /p ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 1/4] notmuch-opts.[ch]: new argument parsing framework for notmuch.
On Sun, 4 Dec 2011 11:47:52 -0400, David Bremner da...@tethera.net wrote: From: David Bremner brem...@debian.org As we noticed when Jani kindly converted things to getopt_long, much of the work in argument parsing in notmuch is due to the the key-value style arguments like --format=(raw|json|text). Hi David - Apologies for not finding time to do proper review earlier. All in all I think this is good work, and I especially like the simplicity of defining arguments in the commands. Even if it makes me slightly sad to have to reinvent the argument parsing wheel... but this is much better than just using getopt_long() like I did. So the design is good, but there are a few issues and nitpicks; please find my comments below. BR, Jani. In this version I implement Austin Clements' suggestion of basing the main API on taking pointers to output variables. --- Makefile.local |1 + notmuch-opts.c | 136 notmuch-opts.h | 44 ++ 3 files changed, 181 insertions(+), 0 deletions(-) create mode 100644 notmuch-opts.c create mode 100644 notmuch-opts.h diff --git a/Makefile.local b/Makefile.local index c94402b..6606be8 100644 --- a/Makefile.local +++ b/Makefile.local @@ -303,6 +303,7 @@ notmuch_client_srcs = \ notmuch-count.c \ notmuch-dump.c \ notmuch-new.c \ + notmuch-opts.c \ We chatted about reserving notmuch-*.c to notmuch commands, but I guess it was only after you sent these. I think it would make sense though. notmuch-reply.c \ notmuch-restore.c \ notmuch-search.c\ diff --git a/notmuch-opts.c b/notmuch-opts.c new file mode 100644 index 000..62d94bf --- /dev/null +++ b/notmuch-opts.c @@ -0,0 +1,136 @@ +#include assert.h +#include string.h +#include stdio.h +#include error_util.h +#include notmuch-opts.h + +/* + Search the list of keywords for a given argument, assigning the + output variable to the corresponding value. Return FALSE if nothing + matches. +*/ Array of keywords to be really pedantic. + +static notmuch_bool_t +_process_keyword_arg (const notmuch_opt_desc_t *arg_desc, const char *arg_str) { + +if (arg_str[0] != ':' arg_str[0] != '=') { + return FALSE; +} + +/* skip delimiter */ +arg_str++; I think the caller should check and skip the delimiters. See my comments below where this gets called. + +notmuch_keyword_t *keywords = arg_desc-keywords; + +while (keywords-name) { + if (strcmp (arg_str, keywords-name) == 0) { + if (arg_desc-output_var) { + *((int *)arg_desc-output_var) = keywords-value; + } So if -output_var is NULL, the parameter is accepted but silently ignored? I'm not sure if I should consider this a feature or a bug. :) This applies below in similar places; I'll not repeat myself. + return TRUE; + } + keywords++; +} +fprintf (stderr, unknown keyword: %s\n, arg_str); +return FALSE; +} + +/* + Search for the {pos_arg_index}th position argument, return FALSE if + that does not exist. +*/ + +notmuch_bool_t +parse_position_arg (const char *arg_str, int pos_arg_index, const notmuch_opt_desc_t *arg_desc) { + +int pos_arg_counter = 0; +while (arg_desc-name){ + if (arg_desc-opt_type == NOTMUCH_OPT_POSITION) { + if (pos_arg_counter == pos_arg_index) { + if (arg_desc-output_var) { + *((const char **)arg_desc-output_var) = arg_str; + } + return TRUE; + } + pos_arg_counter++; + } + arg_desc++; +} +return FALSE; +} + +notmuch_bool_t +parse_option (const char *arg, + const notmuch_opt_desc_t *options){ Missing space between ) and {. + +assert(arg); +assert(options); + +arg += 2; + +const notmuch_opt_desc_t *try = options; +while (try-name) { + if (strncmp (arg, try-name, strlen(try-name)) == 0) { I think here you should check that arg[strlen(try-name)] is '=' or ':' for NOTMUCH_OPT_KEYWORD and NOTMUCH_OPT_INT, and '\0' otherwise. After the check, you could pass just the value part to _process_keyword_arg(). I can't figure out if and how you handle arguments with arbitrary string values (for example --file=/path/to/file). You do specify --in-file and --out-file in later patches, but those are with NOTMUCH_OPT_POSITION, which, AFAICT, would fall in the internal error path below. They'll *only* be handled as positional arguments, not option args. I'm not sure if much weight should be put to getopt_long() compatibility, but it accepts --parameter value as well as --parameter=value. + + switch (try-opt_type) { + case NOTMUCH_OPT_KEYWORD: + return _process_keyword_arg (try, arg+strlen(try-name)); Two spaces after return. +
Re: [PATCH 2/4] notmuch-dump: convert to notmuch-opts argument handling.
On Sun, 4 Dec 2011 11:47:53 -0400, David Bremner da...@tethera.net wrote: From: David Bremner brem...@debian.org The output file is handled via positional arguments. There are currently no normal options. --- notmuch-dump.c | 32 1 files changed, 20 insertions(+), 12 deletions(-) diff --git a/notmuch-dump.c b/notmuch-dump.c index a490917..6fbdc81 100644 --- a/notmuch-dump.c +++ b/notmuch-dump.c @@ -19,6 +19,7 @@ */ #include notmuch-client.h +#include notmuch-opts.h int notmuch_dump_command (unused (void *ctx), int argc, char *argv[]) @@ -41,27 +42,34 @@ notmuch_dump_command (unused (void *ctx), int argc, char *argv[]) if (notmuch == NULL) return 1; -argc--; argv++; /* skip subcommand argument */ +char *output_file_name = NULL; +int opt_index; -if (argc strcmp (argv[0], --) != 0) { +notmuch_opt_desc_t options[] = { + { out-file, 'o', NOTMUCH_OPT_POSITION, 0, output_file_name }, + { 0, 0, 0, 0, 0 } +}; + +opt_index = notmuch_parse_args (argc, argv, options, 1); + +if (opt_index 0) { + /* diagnostics already printed */ + exit(1); return 1 rather than exit(1)? BR, Jani. +} + +if (output_file_name) { fprintf (stderr, Warning: the output file argument of dump is deprecated.\n); - output = fopen (argv[0], w); + output = fopen (output_file_name, w); if (output == NULL) { fprintf (stderr, Error opening %s for writing: %s\n, - argv[0], strerror (errno)); + output_file_name, strerror (errno)); return 1; } - argc--; - argv++; } -if (argc strcmp (argv[0], --) == 0){ - argc--; - argv++; -} -if (argc) { - query_str = query_string_from_args (notmuch, argc, argv); +if (opt_index argc) { + query_str = query_string_from_args (notmuch, argc-opt_index, argv+opt_index); if (query_str == NULL) { fprintf (stderr, Out of memory.\n); return 1; -- 1.7.7.3 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 3/4] notmuch-restore: convert to notmuch-opts argument handling.
On Sun, 4 Dec 2011 11:47:54 -0400, David Bremner da...@tethera.net wrote: From: David Bremner brem...@debian.org The new argument handling is a bit more concise, and bit more flexible. It allows the input file name to go before the --accumulate option. --- notmuch-restore.c | 38 -- 1 files changed, 16 insertions(+), 22 deletions(-) diff --git a/notmuch-restore.c b/notmuch-restore.c index 13b4325..d0aa7a8 100644 --- a/notmuch-restore.c +++ b/notmuch-restore.c @@ -18,9 +18,8 @@ * Author: Carl Worth cwo...@cworth.org */ -#include getopt.h - #include notmuch-client.h +#include notmuch-opts.h I guess this will eventually be included almost everywhere, so in that sense could be put in notmuch-client.h too. int notmuch_restore_command (unused (void *ctx), int argc, char *argv[]) @@ -29,12 +28,14 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[]) notmuch_database_t *notmuch; notmuch_bool_t synchronize_flags; notmuch_bool_t accumulate = FALSE; +char *input_file_name = NULL; FILE *input = stdin; char *line = NULL; size_t line_size; ssize_t line_len; regex_t regex; int rerr; +int opt_index; config = notmuch_config_open (ctx, NULL, NULL); if (config == NULL) @@ -47,37 +48,30 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[]) synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config); -struct option options[] = { - { accumulate, no_argument, 0, 'a' }, - { 0, 0, 0, 0} +notmuch_opt_desc_t options[] = { + { in-file, 'i', NOTMUCH_OPT_POSITION, 0, input_file_name }, Unless I'm mistaken in review of patch 1, specifying the input file using --in-file=file doesn't work; it only works as a positional argument. + { accumulate, 'a', NOTMUCH_OPT_BOOLEAN, 0, accumulate }, + { 0, 0, 0, 0, 0 } }; -int opt; -do { - opt = getopt_long (argc, argv, , options, NULL); +opt_index = notmuch_parse_args (argc, argv, options, 1); - switch (opt) { - case 'a': - accumulate = 1; - break; - case '?': - return 1; - break; - } - -} while (opt != -1); +if (opt_index 0) { + /* diagnostics already printed */ + exit(1); return 1 rather than exit(1)? BR, Jani. +} -if (optind argc) { - input = fopen (argv[optind], r); +if (input_file_name) { + input = fopen (input_file_name, r); if (input == NULL) { fprintf (stderr, Error opening %s for reading: %s\n, - argv[optind], strerror (errno)); + input_file_name, strerror (errno)); return 1; } optind++; } -if (optind argc) { +if (opt_index argc) { fprintf (stderr, Cannot read dump from more than one file: %s\n, argv[optind]); -- 1.7.7.3 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 1/4] notmuch-opts.[ch]: new argument parsing framework for notmuch.
On Sun, 4 Dec 2011 11:47:52 -0400, David Bremner da...@tethera.net wrote: + case NOTMUCH_OPT_INT: + if (try-output_var) + *((int *)try-output_var) = + atol (arg + strlen (try-name) + 1); Looking at patch 4 and the existing handling of int params, I'd really like this one to check that the string is non-empty and that all of the string is parsed (and doesn't contain garbage at the end). BR, Jani. ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [DRAFT PATCH] emacs: support limiting the number of results shown in search results
On Sun, 04 Dec 2011 13:21:40 +0530, Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com wrote: On Thu, 17 Nov 2011 22:07:38 +0200, Jani Nikula j...@nikula.org wrote: Add support for limiting the maximum number of results initially displayed in search results. When enabled, the search results will contain push buttons to double the number of results displayed or to show unlimited results. The approach is inspired by vc-print-log in Emacs vc.el. Signed-off-by: Jani Nikula j...@nikula.org This break notmuch-search-operate-all, I guess the change should also make sure notmuch-search-operate-all also limit its operation to notmuch-search-limit ? Hi Aneesh, thanks for the report. I'll look into this, but I'm afraid I can't make any promises when it'll be. BR, Jani. ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: ANNOUNCE: nottoomuch-addresses.pl
On Tue, 06 Dec 2011 08:45:49 +1100, Bart Bunting b...@ursys.com.au wrote: Hi, I agree with Jamie on this one. The case sensitivity appears to get in the way of searching. I also think that enabling the regular expressionsearching is a good idea. All in all though this is great. I did version 1.2 of nottoomuch-addresses.sh which does case insensitive searches. Note the renaming to .sh -- it is now shell script wrapper which runs 'exec grep -aiF $* addresses-file -- grep is locale-aware which makes case insensitivity work outside of ASCII range. The perl code to create/update addresses file is exactly the same as in version 1.1 So, the current version (1.2) is available at http://www.iki.fi/too/nottoomuch/nottoomuch-addresses.sh sha1sum is 03aa8bcf4e32d47e453fc081376843ef03a427ad and doc page is at http://www.iki.fi/too/nottoomuch/nottoomuch-addresses/ The only other idea I have, which is only half formed, is that it would be nice to prioritize emails that are more important than others. I'm not sure exactly how this would work but something like: - Addresses I have actualy sent email to rather than jjust received from get a high priority in the result. - Addresses that have sent me email directly rather than just to a list get next priority. - All other emails after that. Also some sort of weighting within the groups to do with frequency of emails sent or something. Does that make sense? Would it be hard to implement? Neat idea. To implement the feature into program is not too hard. Somehow determine weight for each email address, store that into hash (key address, value weight). Then, when writing addresses file, sort first by weight and then ascii order. The hash is also stored to disk (using tie()) and used when address file updated. Now, how to determine good (generic) rules for weights (and maybe some user-defined rules as well) is the question. Cheers Bart Thanks, Tomi ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
notmuch release 0.10.2 now available
Where to obtain notmuch 0.10.2 === http://notmuchmail.org/releases/notmuch-0.10.2.tar.gz Which can be verified with: http://notmuchmail.org/releases/notmuch-0.10.2.tar.gz.sha1 3064c1722d30c71f287e1ab63ac13a5847e20c14 notmuch-0.10.2.tar.gz http://notmuchmail.org/releases/notmuch-0.10.2.tar.gz.sha1.asc (signed by David Bremner) What's new in notmuch 0.10.2 = Bug-fix release. Fix crash in python bindings. The python bindings did not call g_type_init, which caused crashes for some, but not all users. What is notmuch === Notmuch is a system for indexing, searching, reading, and tagging large collections of email messages in maildir or mh format. It uses the Xapian library to provide fast, full-text search with a convenient search syntax. For more about notmuch, see http://notmuchmail.org pgp4yNbkeKmfN.pgp Description: PGP signature ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v3 0/2] notmuch hooks
On Tue, 06 Dec 2011 18:47:01 -0800, Jameson Graef Rollins jroll...@finestructure.net wrote: Also, what if we make it so that the post-new hook script only runs if notmuch new processes new messages? All of my post-new functions don't need to be run at all if there is no new mail. Or would it make sense to pass this information to the hook somehow? I currently run 'git pull notmuch new git commit git push or so ... Tom ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch