From: David Bremner <brem...@unb.ca> ---
Like I said in the apology/introduction, I don't claim this patch is ready for the master branch; hence the complete lack of sensible commit message. But it does give some idea about what would be required. In particular definitely more things will have to be passed around. configure | 2 +- notmuch-client.h | 2 +- notmuch-reply.c | 4 +- notmuch-show.c | 110 ++++++++++++++++++++++++++--------------------------- show-message.c | 12 +++--- 5 files changed, 64 insertions(+), 66 deletions(-) diff --git a/configure b/configure index fa8e142..34587a5 100755 --- a/configure +++ b/configure @@ -291,5 +291,5 @@ CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\ CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\ \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\ \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) -CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) +CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS) -ljansson EOF diff --git a/notmuch-client.h b/notmuch-client.h index 50a30fe..6600ed4 100644 --- a/notmuch-client.h +++ b/notmuch-client.h @@ -141,7 +141,7 @@ query_string_from_args (void *ctx, int argc, char *argv[]); notmuch_status_t show_message_body (const char *filename, - void (*show_part) (GMimeObject *part, int *part_count)); + void (*show_part) (GMimeObject *part, int *part_count, void *arg), void *output); /* notmuch-config.c */ diff --git a/notmuch-reply.c b/notmuch-reply.c index 0cda72d..29a6517 100644 --- a/notmuch-reply.c +++ b/notmuch-reply.c @@ -63,7 +63,7 @@ reply_part_content (GMimeObject *part) } static void -reply_part (GMimeObject *part, int *part_count) +reply_part (GMimeObject *part, int *part_count, unused(void *arg)) { GMimeContentDisposition *disposition; GMimeContentType *content_type; @@ -282,7 +282,7 @@ notmuch_reply_format_default(void *ctx, notmuch_config_t *config, notmuch_query_ notmuch_message_get_header (message, "date"), notmuch_message_get_header (message, "from")); - show_message_body (notmuch_message_get_filename (message), reply_part); + show_message_body (notmuch_message_get_filename (message), reply_part,NULL); notmuch_message_destroy (message); } diff --git a/notmuch-show.c b/notmuch-show.c index 376aacd..4f00675 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -18,8 +18,11 @@ * Author: Carl Worth <cworth at cworth.org> */ +#include <jansson.h> #include "notmuch-client.h" +json_t *show_part_content (GMimeObject *part); + static const char * _get_tags_as_string (void *ctx, notmuch_message_t *message) { @@ -66,19 +69,23 @@ _get_one_line_summary (void *ctx, notmuch_message_t *message) from, relative_date, tags); } -static void +json_t * show_part_content (GMimeObject *part) { - GMimeStream *stream_stdout = g_mime_stream_file_new (stdout); + GMimeStream *stream_out = g_mime_stream_mem_new (); GMimeStream *stream_filter = NULL; GMimeDataWrapper *wrapper; + GByteArray *content_data; + + guint8 terminator[]={0}; const char *charset; + json_t *content; charset = g_mime_object_get_content_type_parameter (part, "charset"); - - if (stream_stdout) { - g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_stdout), FALSE); - stream_filter = g_mime_stream_filter_new(stream_stdout); + + if (stream_out) { + g_mime_stream_file_set_owner (GMIME_STREAM_FILE (stream_out), FALSE); + stream_filter = g_mime_stream_filter_new(stream_out); g_mime_stream_filter_add(GMIME_STREAM_FILTER(stream_filter), g_mime_filter_crlf_new(FALSE, FALSE)); if (charset) { @@ -90,60 +97,50 @@ show_part_content (GMimeObject *part) wrapper = g_mime_part_get_content_object (GMIME_PART (part)); if (wrapper && stream_filter) g_mime_data_wrapper_write_to_stream (wrapper, stream_filter); + + content_data = g_mime_stream_mem_get_byte_array ((GMimeStreamMem *)stream_out); + g_byte_array_append(content_data, terminator,1); + content = json_string (content_data->data); if (stream_filter) g_object_unref(stream_filter); - if (stream_stdout) - g_object_unref(stream_stdout); + if (stream_out) + g_object_unref(stream_out); + + return content; } static void -show_part (GMimeObject *part, int *part_count) +show_part (GMimeObject *part, int *part_count, void *output_arg) { GMimeContentDisposition *disposition; GMimeContentType *content_type; + json_t *output = output_arg; + json_t *part_obj=json_object(); disposition = g_mime_object_get_content_disposition (part); + content_type = g_mime_object_get_content_type (GMIME_OBJECT (part)); + + json_object_set (part_obj, "id", json_integer (*part_count)); + json_object_set (part_obj, "content-type", + json_string(g_mime_content_type_to_string (content_type))); + if (disposition && strcmp (disposition->disposition, GMIME_DISPOSITION_ATTACHMENT) == 0) { - const char *filename = g_mime_part_get_filename (GMIME_PART (part)); - content_type = g_mime_object_get_content_type (GMIME_OBJECT (part)); - - printf ("\fattachment{ ID: %d, Content-type: %s\n", - *part_count, - g_mime_content_type_to_string (content_type)); - printf ("Attachment: %s (%s)\n", filename, - g_mime_content_type_to_string (content_type)); - - if (g_mime_content_type_is_type (content_type, "text", "*") && - !g_mime_content_type_is_type (content_type, "text", "html")) - { - show_part_content (part); - } + const char *filename = g_mime_part_get_filename (GMIME_PART (part)); - printf ("\fattachment}\n"); + json_object_set (part_obj, "filename", + json_string (filename)); - return; - } + }; - content_type = g_mime_object_get_content_type (GMIME_OBJECT (part)); - printf ("\fpart{ ID: %d, Content-type: %s\n", - *part_count, - g_mime_content_type_to_string (content_type)); + if (g_mime_content_type_is_type (content_type, "text", "*")) + json_object_set (part_obj, "text", show_part_content (part)); + - if (g_mime_content_type_is_type (content_type, "text", "*") && - !g_mime_content_type_is_type (content_type, "text", "html")) - { - show_part_content (part); - } - else - { - printf ("Non-text part: %s\n", - g_mime_content_type_to_string (content_type)); - } + json_array_append(output,part_obj); - printf ("\fpart}\n"); } static void @@ -154,32 +151,33 @@ show_message (void *ctx, notmuch_message_t *message, int indent) }; const char *name, *value; unsigned int i; + json_t *message_obj=json_object(); + json_t *header_obj=json_object(); + json_t *parts=json_array(); - printf ("\fmessage{ id:%s depth:%d match:%d filename:%s\n", - notmuch_message_get_message_id (message), - indent, - notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH), - notmuch_message_get_filename (message)); + // all of these calls need return-value checking + json_object_set(message_obj,"id",json_string (notmuch_message_get_message_id (message))); + json_object_set(message_obj,"depth",json_integer (indent)); + json_object_set(message_obj,"match", + notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH) ? json_true() : json_false()); + json_object_set(message_obj,"filename",json_string (notmuch_message_get_filename (message))); - printf ("\fheader{\n"); - - printf ("%s\n", _get_one_line_summary (ctx, message)); + json_object_set(header_obj,"summary", json_string (_get_one_line_summary (ctx, message))); for (i = 0; i < ARRAY_SIZE (headers); i++) { name = headers[i]; value = notmuch_message_get_header (message, name); if (value) - printf ("%s: %s\n", name, value); + json_object_set (header_obj, name, json_string (value)); } - printf ("\fheader}\n"); - printf ("\fbody{\n"); - - show_message_body (notmuch_message_get_filename (message), show_part); + json_object_set (message_obj, "header", header_obj); - printf ("\fbody}\n"); + show_message_body (notmuch_message_get_filename (message), show_part, parts); + + json_object_set (message_obj, "parts", parts); + json_dumpf(message_obj,stdout,JSON_INDENT(4)); - printf ("\fmessage}\n"); } diff --git a/show-message.c b/show-message.c index 784981b..e41f51c 100644 --- a/show-message.c +++ b/show-message.c @@ -24,7 +24,7 @@ static void show_message_part (GMimeObject *part, int *part_count, - void (*show_part) (GMimeObject *part, int *part_count)) + void (*show_part) (GMimeObject *part, int *part_count, void *argument), void *output) { *part_count = *part_count + 1; @@ -34,7 +34,7 @@ show_message_part (GMimeObject *part, int *part_count, for (i = 0; i < g_mime_multipart_get_count (multipart); i++) { show_message_part (g_mime_multipart_get_part (multipart, i), - part_count, show_part); + part_count, show_part, output); } return; } @@ -45,7 +45,7 @@ show_message_part (GMimeObject *part, int *part_count, mime_message = g_mime_message_part_get_message (GMIME_MESSAGE_PART (part)); show_message_part (g_mime_message_get_mime_part (mime_message), - part_count, show_part); + part_count, show_part, output); return; } @@ -56,12 +56,12 @@ show_message_part (GMimeObject *part, int *part_count, return; } - (*show_part) (part, part_count); + (*show_part) (part, part_count, output); } notmuch_status_t show_message_body (const char *filename, - void (*show_part) (GMimeObject *part, int *part_count)) + void (*show_part) (GMimeObject *part, int *part_count, void *argument), void *output) { GMimeStream *stream = NULL; GMimeParser *parser = NULL; @@ -85,7 +85,7 @@ show_message_body (const char *filename, mime_message = g_mime_parser_construct_message (parser); show_message_part (g_mime_message_get_mime_part (mime_message), - &part_count, show_part); + &part_count, show_part, output); DONE: if (mime_message) -- 1.6.5.3