diff options
author | Scott Robinson <scott@quadhome.com> | 2009-12-31 11:17:40 -0400 |
---|---|---|
committer | Carl Worth <cworth@cworth.org> | 2010-02-23 12:01:12 -0800 |
commit | 6ce2bf68f53fec4302121763e588c33c7cd86a9c (patch) | |
tree | 97eed1a84956f582cc43efbb16419c43b930c242 /notmuch-search.c | |
parent | 3ca7a4fbcc9cd72330bce1b1670150af1e250006 (diff) |
Add an "--format=(json|text)" command-line option to both notmuch-search and notmuch-show.
In the case of notmuch-show, "--format=json" also implies
"--entire-thread" as the thread structure is implicit in the emitted
document tree.
As a coincidence to the implementation, multipart message ID numbers are
now incremented with each part printed. This changes the previous
semantics, which were unclear and not necessary related to the actual
ordering of the message parts.
Diffstat (limited to 'notmuch-search.c')
-rw-r--r-- | notmuch-search.c | 163 |
1 files changed, 149 insertions, 14 deletions
diff --git a/notmuch-search.c b/notmuch-search.c index dc44eb66..482c6e8e 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -20,8 +20,120 @@ #include "notmuch-client.h" +typedef struct search_format { + const char *results_start; + const char *thread_start; + void (*thread) (const void *ctx, + const char *id, + const time_t date, + const int matched, + const int total, + const char *authors, + const char *subject); + const char *tag_start; + const char *tag; + const char *tag_sep; + const char *tag_end; + const char *thread_sep; + const char *thread_end; + const char *results_end; +} search_format_t; + +static void +format_thread_text (const void *ctx, + const char *id, + const time_t date, + const int matched, + const int total, + const char *authors, + const char *subject); +static const search_format_t format_text = { + "", + "", + format_thread_text, + " (", + "%s", " ", + ")", "", + "\n", + "", +}; + +static void +format_thread_json (const void *ctx, + const char *id, + const time_t date, + const int matched, + const int total, + const char *authors, + const char *subject); +static const search_format_t format_json = { + "[", + "{", + format_thread_json, + "\"tags\": [", + "\"%s\"", ", ", + "]", ",\n", + "}", + "]\n", +}; + +static void +format_thread_text (const void *ctx, + const char *id, + const time_t date, + const int matched, + const int total, + const char *authors, + const char *subject) +{ + printf ("thread:%s %12s [%d/%d] %s; %s", + id, + notmuch_time_relative_date (ctx, date), + matched, + total, + authors, + subject); +} + +static void +format_thread_json (const void *ctx, + const char *id, + const time_t date, + const int matched, + const int total, + const char *authors, + const char *subject) +{ + struct tm *tm; + char timestamp[40]; + void *ctx_quote = talloc_new (ctx); + + tm = gmtime (&date); + if (tm == NULL) + INTERNAL_ERROR ("gmtime failed on thread %s.", id); + + if (strftime (timestamp, sizeof (timestamp), "%s", tm) == 0) + INTERNAL_ERROR ("strftime failed on thread %s.", id); + + printf ("\"id\": %s,\n" + "\"timestamp\": %s,\n" + "\"matched\": %d,\n" + "\"total\": %d,\n" + "\"authors\": %s,\n" + "\"subject\": %s,\n", + json_quote_str (ctx_quote, id), + timestamp, + matched, + total, + json_quote_str (ctx_quote, authors), + json_quote_str (ctx_quote, subject)); + + talloc_free (ctx_quote); +} + static void do_search_threads (const void *ctx, + const search_format_t *format, notmuch_query_t *query, notmuch_sort_t sort) { @@ -29,7 +141,9 @@ do_search_threads (const void *ctx, notmuch_threads_t *threads; notmuch_tags_t *tags; time_t date; - const char *relative_date; + int first_thread = 1; + + fputs (format->results_start, stdout); for (threads = notmuch_query_search_threads (query); notmuch_threads_has_more (threads); @@ -37,6 +151,9 @@ do_search_threads (const void *ctx, { int first_tag = 1; + if (! first_thread) + fputs (format->thread_sep, stdout); + thread = notmuch_threads_get (threads); if (sort == NOTMUCH_SORT_OLDEST_FIRST) @@ -44,30 +161,37 @@ do_search_threads (const void *ctx, else date = notmuch_thread_get_newest_date (thread); - relative_date = notmuch_time_relative_date (ctx, date); + fputs (format->thread_start, stdout); + + format->thread (ctx, + notmuch_thread_get_thread_id (thread), + date, + notmuch_thread_get_matched_messages (thread), + notmuch_thread_get_total_messages (thread), + notmuch_thread_get_authors (thread), + notmuch_thread_get_subject (thread)); - printf ("thread:%s %12s [%d/%d] %s; %s", - notmuch_thread_get_thread_id (thread), - relative_date, - notmuch_thread_get_matched_messages (thread), - notmuch_thread_get_total_messages (thread), - notmuch_thread_get_authors (thread), - notmuch_thread_get_subject (thread)); + fputs (format->tag_start, stdout); - printf (" ("); for (tags = notmuch_thread_get_tags (thread); notmuch_tags_has_more (tags); notmuch_tags_advance (tags)) { if (! first_tag) - printf (" "); - printf ("%s", notmuch_tags_get (tags)); + fputs (format->tag_sep, stdout); + printf (format->tag, notmuch_tags_get (tags)); first_tag = 0; } - printf (")\n"); + + fputs (format->tag_end, stdout); + fputs (format->thread_end, stdout); + + first_thread = 0; notmuch_thread_destroy (thread); } + + fputs (format->results_end, stdout); } int @@ -79,6 +203,7 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) char *query_str; char *opt; notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST; + const search_format_t *format = &format_text; int i; for (i = 0; i < argc && argv[i][0] == '-'; i++) { @@ -96,6 +221,16 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) fprintf (stderr, "Invalid value for --sort: %s\n", opt); return 1; } + } else if (STRNCMP_LITERAL (argv[i], "--format=") == 0) { + opt = argv[i] + sizeof ("--format=") - 1; + if (strcmp (opt, "text") == 0) { + format = &format_text; + } else if (strcmp (opt, "json") == 0) { + format = &format_json; + } else { + fprintf (stderr, "Invalid value for --format: %s\n", opt); + return 1; + } } else { fprintf (stderr, "Unrecognized option: %s\n", argv[i]); return 1; @@ -132,7 +267,7 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) notmuch_query_set_sort (query, sort); - do_search_threads (ctx, query, sort); + do_search_threads (ctx, format, query, sort); notmuch_query_destroy (query); notmuch_database_close (notmuch); |