unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* using the List-Post header to reply to mailing lists
@ 2012-12-04  9:42 Kushal Kumaran
  0 siblings, 0 replies; only message in thread
From: Kushal Kumaran @ 2012-12-04  9:42 UTC (permalink / raw)
  To: notmuch

Hi,

I've been using notmuch with emacs for a while now.  I subscribe to a
few mailing lists where Reply-To-All is severely frowned upon, so I
wanted to be able to use the List-Post header (RFC2369) when replying to
mailing list posts.  I've hacked notmuch-reply.c for my purposes, but I
was wondering how other people manage.

As it stands, this patch is entirely unsuitable for merging.  At least
the following issues will need to be resolved first:

- should an additional command-line option be added to invoke this
  behaviour?  My personal preference is to just use the List-Post header
  whenever possible, if --reply-to=all is not given.

- should anything be done if the List-Post header has a URL which is not
  a mailto: URL (start a web browser?).  None of the mailing lists I'm
  subscribed to puts anything other than mailto.  The patch ignores the
  header if the URL is not a mailto.

- needs tests

- needs documentation

If anyone has alternatives to doing this kind of URL parsing, I'm
interested.  Comments regarding my pathetic knowledge of gmime are also
welcome.  If no one things notmuch needs this functionality, I will just
hold on to it for my personal use.

---
 notmuch-reply.c |   68 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 60 insertions(+), 8 deletions(-)

diff --git a/notmuch-reply.c b/notmuch-reply.c
index e60a264..82f5a35 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -172,6 +172,11 @@ address_is_users (const char *address, notmuch_config_t *config)
     return address_match (address, config, STRING_IS_USER_ADDRESS) != NULL;
 }

+typedef enum {
+    rfc822,
+    url
+} address_format_t;
+
 /* Scan addresses in 'list'.
  *
  * If 'message' is non-NULL, then for each address in 'list' that is
@@ -231,6 +236,37 @@ scan_address_list (InternetAddressList *list,
     return n;
 }

+InternetAddressList *list_post_url_to_address_list(const char *header_value) {
+    size_t recipients_len = strlen(header_value);
+    size_t list_post_prefix_len = strlen("<mailto:");
+    char *list_post_url;
+    InternetAddressList *list;
+    InternetAddress *list_post_addr;
+
+    recipients_len = strlen(header_value);
+
+    if (strncmp(header_value, "<mailto:", list_post_prefix_len) != 0) {
+	return NULL;
+    }
+
+    if (header_value[recipients_len - 1] != '>') {
+	return NULL;
+    }
+
+    list_post_url = xstrdup(header_value);
+    list_post_url[recipients_len - 1] = '\0';
+    list_post_addr = internet_address_mailbox_new(NULL, list_post_url +
+						  list_post_prefix_len);
+    list = internet_address_list_new();
+    if (list == NULL) {
+	return NULL;
+    }
+    internet_address_list_add(list, list_post_addr);
+    free(list_post_url);
+
+    return list;
+}
+
 /* Scan addresses in 'recipients'.
  *
  * See the documentation of scan_address_list() above. This function
@@ -242,6 +278,7 @@ scan_address_string (const char *recipients,
		     notmuch_config_t *config,
		     GMimeMessage *message,
		     GMimeRecipientType type,
+		     address_format_t format,
		     const char **user_from)
 {
     InternetAddressList *list;
@@ -249,9 +286,21 @@ scan_address_string (const char *recipients,
     if (recipients == NULL)
	return 0;

-    list = internet_address_list_parse_string (recipients);
-    if (list == NULL)
-	return 0;
+    switch (format) {
+    case rfc822:
+	list = internet_address_list_parse_string (recipients);
+	if (list == NULL)
+	    return 0;
+
+	break;
+
+    case url:
+	list = list_post_url_to_address_list (recipients);
+	if (list == NULL)
+	    return 0;
+
+	break;
+    }

     return scan_address_list (list, config, message, type, user_from);
 }
@@ -317,11 +366,13 @@ add_recipients_from_message (GMimeMessage *reply,
	const char *header;
	const char *fallback;
	GMimeRecipientType recipient_type;
+	address_format_t format;
     } reply_to_map[] = {
-	{ "reply-to", "from", GMIME_RECIPIENT_TYPE_TO  },
-	{ "to",         NULL, GMIME_RECIPIENT_TYPE_TO  },
-	{ "cc",         NULL, GMIME_RECIPIENT_TYPE_CC  },
-	{ "bcc",        NULL, GMIME_RECIPIENT_TYPE_BCC }
+	{ "list-post",  NULL, GMIME_RECIPIENT_TYPE_TO,  url },
+	{ "reply-to", "from", GMIME_RECIPIENT_TYPE_TO,  rfc822  },
+	{ "to",         NULL, GMIME_RECIPIENT_TYPE_TO,  rfc822  },
+	{ "cc",         NULL, GMIME_RECIPIENT_TYPE_CC,  rfc822  },
+	{ "bcc",        NULL, GMIME_RECIPIENT_TYPE_BCC, rfc822  }
     };
     const char *from_addr = NULL;
     unsigned int i;
@@ -353,7 +404,8 @@ add_recipients_from_message (GMimeMessage *reply,
						     reply_to_map[i].fallback);

	n += scan_address_string (recipients, config, reply,
-				  reply_to_map[i].recipient_type, &from_addr);
+				  reply_to_map[i].recipient_type,
+				  reply_to_map[i].format, &from_addr);

	if (!reply_all && n) {
	    /* Stop adding new recipients in reply-to-sender mode if
[ 2-line signature. Click/Enter to show. ]
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2012-12-04  9:42 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-04  9:42 using the List-Post header to reply to mailing lists Kushal Kumaran

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).