Re: [PATCH v3 2/5] reply: Add a JSON reply format.

2012-02-05 Thread Adam Wolfe Gordon
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.

2012-02-05 Thread Austin Clements
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.

2012-02-05 Thread Dmitry Kurochkin
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.

2012-02-05 Thread Adam Wolfe Gordon
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.

2012-02-05 Thread Mark Walters

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.

2012-02-05 Thread Mark Walters
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