Re: [PATCH v3 2/5] reply: Add a JSON reply format.
On Sun, Feb 5, 2012 at 20:44, Austin Clements wrote: > Sorry for coming late to the party. I really like this idea, but it > seems like your implementation is duplicating a lot of the work of > notmuch show. This makes me wonder if it would be better to return > reply header information in the JSON (which is definitely the way to > go) but to fetch the part body from the UI via show (and maybe reuse > some of the show-mode logic, if it makes sense to do so). If this has > already been discussed, just point me at the thread and I'll catch > myself up. Thanks for taking a look. Dmitry noted on IRC that inlining the HTML in JSON could cause issues with non-UTF8 character sets. Right now I'm working on essentially what you've suggested - having the CLI produce only headers, and then using show to get the quotable body. Something else that was mentioned on IRC is using some of the notmuch show logic to produce the show JSON format as part of reply. I looked into this, but it would take some serious refactoring (to make the show JSON stuff accessible to reply), and since emacs will need to end up calling show anyway, I'm not sure it's worth it. I do like the idea of different CLI commands being able to produce standardized formats through some shared interface, I'm just not sure it's necessary here, and not sure what the interface should look like. ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v3 2/5] reply: Add a JSON reply format.
Quoth Adam Wolfe Gordon on Jan 19 at 10:46 am: > This new JSON format for replies includes headers generated for a reply > message as well as the headers and all text parts 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 using w3m. Sorry for coming late to the party. I really like this idea, but it seems like your implementation is duplicating a lot of the work of notmuch show. This makes me wonder if it would be better to return reply header information in the JSON (which is definitely the way to go) but to fetch the part body from the UI via show (and maybe reuse some of the show-mode logic, if it makes sense to do so). If this has already been discussed, just point me at the thread and I'll catch myself up. ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v3 2/5] reply: Add a JSON reply format.
On Sun, 5 Feb 2012 12:42:12 -0700, Adam Wolfe Gordon wrote: > Thanks for the review. The style nits are things I missed in my > previous cleanup, so thanks for pointing them out. I should probably > run uncrustify and see if it complains about anything else. > > The other points are definitely up for discussion, and some are areas > where I was unsure to start with. Discussion inline: > > On Sun, Feb 5, 2012 at 04:50, Mark Walters wrote: > >> + /* We only care about inline text parts for reply purposes */ > >> + if (reply_check_part_type (part, "text", "*", > >> GMIME_DISPOSITION_INLINE)) { > > > > This seems to be different from the logic in the text output: I think > > that inlines all text/* regardless of disposition. I think the JSON > > output should include at least as much as the text output as it is easy > > for the caller to discard parts. > > Indeed, the text output includes all text/* parts except for > text/html, regardless of disposition. My thought was that it doesn't > really make sense to quote an attachment, or at least it's not the > behavior I would expect. But, perhaps it makes more sense to include > all the text parts, with their dispositions, and let the MUA decide > what it wants to quote. If anyone has thoughts on this I'm happy to > hear them. > > > Does wrapper need to a free/unref somewhere? > > The text format doesn't free or unref wrapper, so I followed its > example. But, I'm not a gmime expert, and I agree intuitively that it > should be freed somehow. Can anyone enlighten me? > > > If replying to multiple messages (such as a whole thread) you get > > multiple sets of "new headers". I think that probably is not what is > > wanted but its still better than the weird things the text version > > does. Might be worth putting a comment. [What I think should happen is > > that a union of all the headers from all these is taken throwing away > > duplicate addresses but that is obviously not part of this patch set] > > I've never been sure about what the intended behavior is when replying > to multiple messages in the CLI. My thought was that it should create > a reply to each message, so an MUA could iterate over them allowing > you to compose replies to multiple messages. But, I've never wanted or > used such a feature, so I'm agnostic on whether it's right. The emacs > MUA (at least with my patch) ignores all but the first reply object in > the array, my assumption being that reply only operates on multiple > messages by accident. > In some cases, notmuch CLI insists that the search query matches exactly one message (e.g. notmuch show for parts). IMO the same behavior makes sense for notmuch reply. Regards, Dmitry > Does anyone use reply with multiple messages? If so, what semantics do > you expect? > ___ > 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 v3 2/5] reply: Add a JSON reply format.
Thanks for the review. The style nits are things I missed in my previous cleanup, so thanks for pointing them out. I should probably run uncrustify and see if it complains about anything else. The other points are definitely up for discussion, and some are areas where I was unsure to start with. Discussion inline: On Sun, Feb 5, 2012 at 04:50, Mark Walters wrote: >> + /* We only care about inline text parts for reply purposes */ >> + if (reply_check_part_type (part, "text", "*", >> GMIME_DISPOSITION_INLINE)) { > > This seems to be different from the logic in the text output: I think > that inlines all text/* regardless of disposition. I think the JSON > output should include at least as much as the text output as it is easy > for the caller to discard parts. Indeed, the text output includes all text/* parts except for text/html, regardless of disposition. My thought was that it doesn't really make sense to quote an attachment, or at least it's not the behavior I would expect. But, perhaps it makes more sense to include all the text parts, with their dispositions, and let the MUA decide what it wants to quote. If anyone has thoughts on this I'm happy to hear them. > Does wrapper need to a free/unref somewhere? The text format doesn't free or unref wrapper, so I followed its example. But, I'm not a gmime expert, and I agree intuitively that it should be freed somehow. Can anyone enlighten me? > If replying to multiple messages (such as a whole thread) you get > multiple sets of "new headers". I think that probably is not what is > wanted but its still better than the weird things the text version > does. Might be worth putting a comment. [What I think should happen is > that a union of all the headers from all these is taken throwing away > duplicate addresses but that is obviously not part of this patch set] I've never been sure about what the intended behavior is when replying to multiple messages in the CLI. My thought was that it should create a reply to each message, so an MUA could iterate over them allowing you to compose replies to multiple messages. But, I've never wanted or used such a feature, so I'm agnostic on whether it's right. The emacs MUA (at least with my patch) ignores all but the first reply object in the array, my assumption being that reply only operates on multiple messages by accident. Does anyone use reply with multiple messages? If so, what semantics do you expect? ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v3 2/5] reply: Add a JSON reply format.
On Sun, 05 Feb 2012 11:50:12 +, Mark Walters wrote: > On Thu, 19 Jan 2012 10:46:54 -0700, Adam Wolfe Gordon > wrote: > > This new JSON format for replies includes headers generated for a reply > > message as well as the headers and all text parts 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 using w3m. > > Hi this is only a preliminary look so far as I read the code. Note this > is the first time I have tried reviewing a substantial chunk of code so > sorry for any stupidities on my part! After Austin's show modifications (commit 7430a42) I needed the following patch which is probably trivial but I was only guessing based on the other change to notmuch-reply Austin made at the time. Best wishes Mark diff --git a/notmuch-reply.c b/notmuch-reply.c index 9aefce8..1c62b54 100644 --- a/notmuch-reply.c +++ b/notmuch-reply.c @@ -56,7 +56,7 @@ static const notmuch_show_format_t format_reply = { }; static const notmuch_show_format_t format_json = { -"", +"", NULL, "", NULL, "", NULL, NULL, "", "", ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v3 2/5] reply: Add a JSON reply format.
On Thu, 19 Jan 2012 10:46:54 -0700, Adam Wolfe Gordon wrote: > This new JSON format for replies includes headers generated for a reply > message as well as the headers and all text parts 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 using w3m. Hi this is only a preliminary look so far as I read the code. Note this is the first time I have tried reviewing a substantial chunk of code so sorry for any stupidities on my part! Best wishes Mark > notmuch-reply.c | 271 > +++ > 1 files changed, 231 insertions(+), 40 deletions(-) > > diff --git a/notmuch-reply.c b/notmuch-reply.c > index 0f682db..b4c2426 100644 > --- a/notmuch-reply.c > +++ b/notmuch-reply.c > @@ -30,6 +30,15 @@ reply_headers_message_part (GMimeMessage *message); > static void > reply_part_content (GMimeObject *part); > > +static void > +reply_part_start_json (GMimeObject *part, int *part_count); > + > +static void > +reply_part_content_json (GMimeObject *part); > + > +static void > +reply_part_end_json (GMimeObject *part); > + > static const notmuch_show_format_t format_reply = { > "", > "", NULL, > @@ -46,6 +55,22 @@ static const notmuch_show_format_t format_reply = { > "" > }; > > +static const notmuch_show_format_t format_json = { > +"", > + "", NULL, > + "", NULL, NULL, "", > + "", > + reply_part_start_json, > + NULL, > + NULL, > + reply_part_content_json, > + reply_part_end_json, > + "", > + "", > + "", "", > +"" > +}; > + > static void > show_reply_headers (GMimeMessage *message) > { > @@ -86,6 +111,17 @@ reply_headers_message_part (GMimeMessage *message) > printf ("> Date: %s\n", g_mime_message_get_date_as_string (message)); > } > > +static notmuch_bool_t > +reply_check_part_type (GMimeObject *part, const char *type, const char > *subtype, > +const char *disposition) > +{ > +GMimeContentType *content_type = g_mime_object_get_content_type > (GMIME_OBJECT (part)); > +GMimeContentDisposition *part_disposition = > g_mime_object_get_content_disposition (part); > + > +return (g_mime_content_type_is_type (content_type, type, subtype) && > + (!part_disposition || > + strcmp (part_disposition->disposition, disposition) == 0)); > +} > > static void > reply_part_content (GMimeObject *part) > @@ -147,6 +183,63 @@ reply_part_content (GMimeObject *part) > } > } > > +static void > +reply_part_start_json (GMimeObject *part, unused (int *part_count)) > +{ > +if (reply_check_part_type (part, "text", "*", GMIME_DISPOSITION_INLINE)) > + printf ("{ "); > +} > + > +static void > +reply_part_end_json (GMimeObject *part) > +{ > +if (reply_check_part_type (part, "text", "*", GMIME_DISPOSITION_INLINE)) > + printf ("}, "); > +} > + > +static void > +reply_part_content_json (GMimeObject *part) > +{ > +GMimeContentType *content_type = g_mime_object_get_content_type > (GMIME_OBJECT (part)); > +void *ctx = talloc_new (NULL); > + > +/* We only care about inline text parts for reply purposes */ > +if (reply_check_part_type (part, "text", "*", GMIME_DISPOSITION_INLINE)) > { This seems to be different from the logic in the text output: I think that inlines all text/* regardless of disposition. I think the JSON output should include at least as much as the text output as it is easy for the caller to discard parts. > + GMimeDataWrapper *wrapper; > + GByteArray *part_content; > + > + printf ("\"content-type\": %s, \"content\": ", > +json_quote_str (ctx, g_mime_content_type_to_string > (content_type))); > + > + wrapper = g_mime_part_get_content_object (GMIME_PART (part)); > + if (wrapper) { > + const char *charset = g_mime_object_get_content_type_parameter > (part, "charset"); > + GMimeStream *stream_memory = g_mime_stream_mem_new (); > + if (stream_memory) { > + GMimeStream *stream_filter = NULL; > + stream_filter = g_mime_stream_filter_new (stream_memory); > + if (charset) { > + g_mime_stream_filter_add (GMIME_STREAM_FILTER > (stream_filter), > + g_mime_filter_charset_new > (charset, "UTF-8")); > + } > + > + if (stream_filter) { should the if (charset) block be inside the if (stream_filter) block? > + g_mime_data_wrapper_write_to_stream (wrapper, > stream_filter); > + part_content = g_mime_stream_mem_get_byte_array > (GMIME_STREAM_MEM (stream_memory)); > + > + printf ("%s", json_quote_chararray (ctx, (char *) > part_content->data, part_content->len)); > + g_object_unref (stream