unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
From: Adam Wolfe Gordon <awg+notmuch@xvx.ca>
To: notmuch@notmuchmail.org
Subject: [PATCH v8 04/11] reply: Add a JSON reply format.
Date: Sun, 18 Mar 2012 10:32:36 -0600	[thread overview]
Message-ID: <1332088363-22476-5-git-send-email-awg+notmuch@xvx.ca> (raw)
In-Reply-To: <1332088363-22476-1-git-send-email-awg+notmuch@xvx.ca>

This new JSON format for replies includes headers generated for a
reply message as well as the headers of the original message.  Using
this data, a client can intelligently create a reply. For example, the
emacs client will be able to create replies with quoted HTML parts by
parsing the HTML parts.
---
 notmuch-client.h |   12 +++++++++---
 notmuch-reply.c  |   49 +++++++++++++++++++++++++++++++++++++++++++++++++
 notmuch-show.c   |   29 +++++++++++++++++++++--------
 test/multipart   |    1 -
 4 files changed, 79 insertions(+), 12 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index a220fe4..fa04fa2 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -62,7 +62,7 @@
 #define STRINGIFY(s) STRINGIFY_(s)
 #define STRINGIFY_(s) #s
 
-struct mime_node;
+typedef struct mime_node mime_node_t;
 struct notmuch_show_params;
 
 typedef struct notmuch_show_format {
@@ -191,6 +191,12 @@ show_message_body (notmuch_message_t *message,
 notmuch_status_t
 show_one_part (const char *filename, int part);
 
+void
+format_part_json (const void *ctx, mime_node_t *node, notmuch_bool_t first);
+
+void
+format_headers_json (const void *ctx, GMimeMessage *message, notmuch_bool_t reply);
+
 char *
 json_quote_chararray (const void *ctx, const char *str, const size_t len);
 
@@ -288,7 +294,7 @@ debugger_is_active (void);
  * parts.  Message-type parts have one child, multipart-type parts
  * have multiple children, and leaf parts have zero children.
  */
-typedef struct mime_node {
+struct mime_node {
     /* The MIME object of this part.  This will be a GMimeMessage,
      * GMimePart, GMimeMultipart, or a subclass of one of these.
      *
@@ -351,7 +357,7 @@ typedef struct mime_node {
      * number to assign it (or -1 if unknown). */
     int next_child;
     int next_part_num;
-} mime_node_t;
+};
 
 /* Construct a new MIME node pointing to the root message part of
  * message.  If cryptoctx is non-NULL, it will be used to verify
diff --git a/notmuch-reply.c b/notmuch-reply.c
index f1478cc..e2b6c25 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -604,6 +604,51 @@ notmuch_reply_format_default(void *ctx,
     return 0;
 }
 
+static int
+notmuch_reply_format_json(void *ctx,
+			  notmuch_config_t *config,
+			  notmuch_query_t *query,
+			  notmuch_show_params_t *params,
+			  notmuch_bool_t reply_all)
+{
+    GMimeMessage *reply;
+    notmuch_messages_t *messages;
+    notmuch_message_t *message;
+    mime_node_t *node;
+
+    if (notmuch_query_count_messages (query) != 1) {
+	fprintf (stderr, "Error: search term did not match precisely one message.\n");
+	return 1;
+    }
+
+    messages = notmuch_query_search_messages (query);
+    message = notmuch_messages_get (messages);
+    if (mime_node_open (ctx, message, params->cryptoctx, params->decrypt,
+			&node) != NOTMUCH_STATUS_SUCCESS)
+	return 1;
+
+    reply = create_reply_message (ctx, config, message, reply_all);
+    if (!reply)
+	return 1;
+
+    /* The headers of the reply message we've created */
+    printf ("{\"reply-headers\": ");
+    format_headers_json (ctx, reply, TRUE);
+    g_object_unref (G_OBJECT (reply));
+    reply = NULL;
+
+    /* Start the original */
+    printf (", \"original\": ");
+
+    format_part_json (ctx, node, TRUE);
+
+    /* End */
+    printf ("}\n");
+    notmuch_message_destroy (message);
+
+    return 0;
+}
+
 /* This format is currently tuned for a git send-email --notmuch hook */
 static int
 notmuch_reply_format_headers_only(void *ctx,
@@ -666,6 +711,7 @@ notmuch_reply_format_headers_only(void *ctx,
 
 enum {
     FORMAT_DEFAULT,
+    FORMAT_JSON,
     FORMAT_HEADERS_ONLY,
 };
 
@@ -685,6 +731,7 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
     notmuch_opt_desc_t options[] = {
 	{ NOTMUCH_OPT_KEYWORD, &format, "format", 'f',
 	  (notmuch_keyword_t []){ { "default", FORMAT_DEFAULT },
+				  { "json", FORMAT_JSON },
 				  { "headers-only", FORMAT_HEADERS_ONLY },
 				  { 0, 0 } } },
 	{ NOTMUCH_OPT_KEYWORD, &reply_all, "reply-to", 'r',
@@ -703,6 +750,8 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 
     if (format == FORMAT_HEADERS_ONLY)
 	reply_format_func = notmuch_reply_format_headers_only;
+    else if (format == FORMAT_JSON)
+	reply_format_func = notmuch_reply_format_json;
     else
 	reply_format_func = notmuch_reply_format_default;
 
diff --git a/notmuch-show.c b/notmuch-show.c
index a7463dc..ff9d427 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -200,8 +200,8 @@ _is_from_line (const char *line)
 	return 0;
 }
 
-static void
-format_headers_json (const void *ctx, GMimeMessage *message)
+void
+format_headers_json (const void *ctx, GMimeMessage *message, notmuch_bool_t reply)
 {
     void *local = talloc_new (ctx);
     InternetAddressList *recipients;
@@ -225,9 +225,22 @@ format_headers_json (const void *ctx, GMimeMessage *message)
 	printf (", %s: %s",
 		json_quote_str (local, "Cc"),
 		json_quote_str (local, recipients_string));
-    printf (", %s: %s}",
-	    json_quote_str (local, "Date"),
-	    json_quote_str (local, g_mime_message_get_date_as_string (message)));
+
+    if (reply) {
+	printf (", %s: %s",
+		json_quote_str (local, "In-reply-to"),
+		json_quote_str (local, g_mime_object_get_header (GMIME_OBJECT (message), "In-reply-to")));
+
+	printf (", %s: %s",
+		json_quote_str (local, "References"),
+		json_quote_str (local, g_mime_object_get_header (GMIME_OBJECT (message), "References")));
+    } else {
+	printf (", %s: %s",
+		json_quote_str (local, "Date"),
+		json_quote_str (local, g_mime_message_get_date_as_string (message)));
+    }
+
+    printf ("}");
 
     talloc_free (local);
 }
@@ -538,7 +551,7 @@ format_part_text (const void *ctx, mime_node_t *node,
     return NOTMUCH_STATUS_SUCCESS;
 }
 
-static void
+void
 format_part_json (const void *ctx, mime_node_t *node, notmuch_bool_t first)
 {
     /* Any changes to the JSON format should be reflected in the file
@@ -549,7 +562,7 @@ format_part_json (const void *ctx, mime_node_t *node, notmuch_bool_t first)
 	format_message_json (ctx, node->envelope_file);
 
 	printf ("\"headers\": ");
-	format_headers_json (ctx, GMIME_MESSAGE (node->part));
+	format_headers_json (ctx, GMIME_MESSAGE (node->part), FALSE);
 
 	printf (", \"body\": [");
 	format_part_json (ctx, mime_node_child (node, 0), first);
@@ -623,7 +636,7 @@ format_part_json (const void *ctx, mime_node_t *node, notmuch_bool_t first)
     } else if (GMIME_IS_MESSAGE (node->part)) {
 	printf (", \"content\": [{");
 	printf ("\"headers\": ");
-	format_headers_json (local, GMIME_MESSAGE (node->part));
+	format_headers_json (local, GMIME_MESSAGE (node->part), FALSE);
 
 	printf (", \"body\": [");
 	terminator = "]}]";
diff --git a/test/multipart b/test/multipart
index e5de5d3..72d3927 100755
--- a/test/multipart
+++ b/test/multipart
@@ -613,7 +613,6 @@ EOF
 test_expect_equal_file OUTPUT EXPECTED
 
 test_begin_subtest "'notmuch reply' to a multipart message with json format"
-test_subtest_known_broken
 notmuch reply --format=json 'id:87liy5ap00.fsf@yoom.home.cworth.org' | notmuch_json_show_sanitize >OUTPUT
 cat <<EOF >EXPECTED
 {"reply-headers": {"Subject": "Re: Multipart message",
-- 
1.7.5.4

  parent reply	other threads:[~2012-03-18 16:33 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-12  4:05 [PATCH v7 00/10] Reply enhancements Adam Wolfe Gordon
2012-03-12  4:05 ` [PATCH v7 01/10] test: Add broken test for the new JSON reply format Adam Wolfe Gordon
2012-03-13 16:49   ` Austin Clements
2012-03-13 16:51     ` Adam Wolfe Gordon
2012-03-12  4:05 ` [PATCH v7 02/10] reply: Factor out reply creation Adam Wolfe Gordon
2012-03-12  4:05 ` [PATCH v7 03/10] TODO: Add replying to multiple messages Adam Wolfe Gordon
2012-03-12  4:05 ` [PATCH v7 04/10] reply: Add a JSON reply format Adam Wolfe Gordon
2012-03-12  4:05 ` [PATCH v7 05/10] schemata: Add documentation for " Adam Wolfe Gordon
2012-03-12  4:05 ` [PATCH v7 06/10] man: Update notmuch-reply man page for JSON format Adam Wolfe Gordon
2012-03-12  4:05 ` [PATCH v7 07/10] man: Add --decrypt to reply flags Adam Wolfe Gordon
2012-03-12  4:05 ` [PATCH v7 08/10] emacs: Factor out useful functions into notmuch-lib Adam Wolfe Gordon
2012-03-12  4:05 ` [PATCH v7 09/10] test: Add broken tests for new emacs reply functionality Adam Wolfe Gordon
2012-03-12  4:05 ` [PATCH v7 10/10] emacs: Use the new JSON reply format and message-cite-original Adam Wolfe Gordon
2012-03-13 17:02   ` Austin Clements
2012-03-13 17:47     ` Adam Wolfe Gordon
2012-03-14  4:30 ` [PATCH v7.1 00/11] Reply enhancements, second attempt Adam Wolfe Gordon
2012-03-14  4:30   ` [PATCH v7.1 01/11] test: Add broken test for the new JSON reply format Adam Wolfe Gordon
2012-03-14  4:30   ` [PATCH v7.1 02/11] reply: Factor out reply creation Adam Wolfe Gordon
2012-03-14  4:30   ` [PATCH v7.1 03/11] TODO: Add replying to multiple messages Adam Wolfe Gordon
2012-03-14  4:30   ` [PATCH v7.1 04/11] reply: Add a JSON reply format Adam Wolfe Gordon
2012-03-14  4:30   ` [PATCH v7.1 05/11] schemata: Add documentation for " Adam Wolfe Gordon
2012-03-14  4:30   ` [PATCH v7.1 06/11] man: Update notmuch-reply man page for JSON format Adam Wolfe Gordon
2012-03-14  4:30   ` [PATCH v7.1 07/11] man: Add --decrypt to reply flags Adam Wolfe Gordon
2012-03-14  4:30   ` [PATCH v7.1 08/11] emacs: Factor out useful functions into notmuch-lib Adam Wolfe Gordon
2012-03-14  4:30   ` [PATCH v7.1 09/11] test: Add broken tests for new emacs reply functionality Adam Wolfe Gordon
2012-03-14  4:30   ` [PATCH v7.1 10/11] emacs: Use the new JSON reply format and message-cite-original Adam Wolfe Gordon
2012-03-14  4:30   ` [PATCH v7.1 11/11] NEWS: news for reply enhancements Adam Wolfe Gordon
2012-03-18 13:22     ` David Bremner
2012-03-14 22:26   ` [PATCH v7.1 00/11] Reply enhancements, second attempt Austin Clements
2012-03-18 12:59   ` David Bremner
2012-03-18 16:32     ` [PATCH v8 00/11] Reply enhancements (rebased) Adam Wolfe Gordon
2012-03-18 16:32       ` [PATCH v8 01/11] test: Add broken test for the new JSON reply format Adam Wolfe Gordon
2012-03-18 16:32       ` [PATCH v8 02/11] reply: Factor out reply creation Adam Wolfe Gordon
2012-03-18 16:32       ` [PATCH v8 03/11] TODO: Add replying to multiple messages Adam Wolfe Gordon
2012-03-18 16:32       ` Adam Wolfe Gordon [this message]
2012-03-18 16:32       ` [PATCH v8 05/11] schemata: Add documentation for JSON reply format Adam Wolfe Gordon
2012-03-18 16:32       ` [PATCH v8 06/11] man: Update notmuch-reply man page for JSON format Adam Wolfe Gordon
2012-03-18 16:32       ` [PATCH v8 07/11] man: Add --decrypt to reply flags Adam Wolfe Gordon
2012-03-18 16:32       ` [PATCH v8 08/11] emacs: Factor out useful functions into notmuch-lib Adam Wolfe Gordon
2012-03-18 16:32       ` [PATCH v8 09/11] test: Add broken tests for new emacs reply functionality Adam Wolfe Gordon
2012-03-18 16:32       ` [PATCH v8 10/11] emacs: Use the new JSON reply format and message-cite-original Adam Wolfe Gordon
2012-03-18 16:32       ` [PATCH v8 11/11] NEWS: news for reply enhancements Adam Wolfe Gordon
2012-03-20  1:11       ` [PATCH v8 00/11] Reply enhancements (rebased) David Bremner
2012-03-17 19:13 ` [PATCH v7 00/10] Reply enhancements Jameson Graef Rollins
2012-03-17 19:33   ` Adam Wolfe Gordon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://notmuchmail.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1332088363-22476-5-git-send-email-awg+notmuch@xvx.ca \
    --to=awg+notmuch@xvx.ca \
    --cc=notmuch@notmuchmail.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).