[PATCH] RFC: Add From guessing when forwarding email

Dirk Hohndel hohndel at infradead.org
Fri Apr 23 15:52:15 PDT 2010


This adds a new "guess-from" option to notmuch and modifies the
emacs UI to use this to use the best guess from address when
forwarding email.

Given how little elisp I know I'm quite interested in feedback
and better implementations

Signed-off-by: Dirk Hohndel <hohndel at infradead.org>
---
 emacs/notmuch-show.el |    8 +++-
 notmuch-client.h      |    3 +
 notmuch-reply.c       |  110 +++++++++++++++++++++++++++++++++++++++++++++++++
 notmuch.c             |    8 ++++
 4 files changed, 127 insertions(+), 2 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 53af301..8cec9e8 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -809,8 +809,12 @@ any effects from previous calls to
 (defun notmuch-show-forward-message ()
   "Forward the current message."
   (interactive)
-  (with-current-notmuch-show-message
-   (notmuch-mua-forward-message)))
+  (progn
+    (let ((message-id (notmuch-show-get-message-id)))
+      (with-current-notmuch-show-message
+       (progn
+	 (setq user-mail-address (shell-command-to-string (concat "notmuch guess-from " message-id)))
+	 (notmuch-mua-forward-message))))))
 
 (defun notmuch-show-next-message ()
   "Show the next message."
diff --git a/notmuch-client.h b/notmuch-client.h
index 20be43b..ba5b002 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -93,6 +93,9 @@ int
 notmuch_reply_command (void *ctx, int argc, char *argv[]);
 
 int
+notmuch_guess_from_command (void *ctx, int argc, char *argv[]);
+
+int
 notmuch_restore_command (void *ctx, int argc, char *argv[]);
 
 int
diff --git a/notmuch-reply.c b/notmuch-reply.c
index 230cacc..e9c8449 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -364,6 +364,55 @@ guess_from_received_header (notmuch_config_t *config, notmuch_message_t *message
     return NULL;
 }
 
+/*
+ * simply figure out the best from address to use without creating
+ * a reply buffer or anything else
+ */
+static const char *
+notmuch_guess_from(notmuch_config_t *config, notmuch_query_t *query)
+{
+    notmuch_messages_t *messages;
+    notmuch_message_t *message;
+    InternetAddressList *list;
+    InternetAddressMailbox *mailbox;
+    InternetAddress *address;
+    char *recipients;
+    const char *addr;
+    const char *from_addr = NULL;
+    int i;
+
+    for (messages = notmuch_query_search_messages (query);
+	 notmuch_messages_valid (messages);
+	 notmuch_messages_move_to_next (messages))
+    {
+	message = notmuch_messages_get (messages);
+	if ((asprintf (&recipients, "%s,%s", notmuch_message_get_header (message, "to"),
+		       notmuch_message_get_header (message, "cc")) == -1) || recipients == NULL) {
+	    fprintf (stderr, "Out of memory\n");
+	    return NULL;
+	}
+	list = internet_address_list_parse_string (recipients);
+	for (i = 0; i < internet_address_list_length (list); i++) {
+	    address = internet_address_list_get_address (list, i);
+	    if (! INTERNET_ADDRESS_IS_GROUP (address)) {
+		mailbox = INTERNET_ADDRESS_MAILBOX (address);
+		addr = internet_address_mailbox_get_addr (mailbox);
+		if (address_is_users (addr, config) && !from_addr) {
+		    from_addr = addr;
+		    break;
+		}
+	    }
+	}
+	free (recipients);
+	if (from_addr == NULL)
+	    from_addr = guess_from_received_header (config, message);
+    
+	if (from_addr == NULL)
+	    from_addr = notmuch_config_get_user_primary_email (config);
+    }
+    return from_addr;
+}
+
 static int
 notmuch_reply_format_default(void *ctx, notmuch_config_t *config, notmuch_query_t *query)
 {
@@ -567,3 +616,64 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])
 
     return ret;
 }
+
+int
+notmuch_guess_from_command (void *ctx, int argc, char *argv[])
+{
+    notmuch_config_t *config;
+    notmuch_database_t *notmuch;
+    notmuch_query_t *query;
+    char *query_string;
+    char const *addr;
+    int i, ret = 0;
+
+    for (i = 0; i < argc && argv[i][0] == '-'; i++) {
+	if (strcmp (argv[i], "--") == 0) {
+	    i++;
+	    break;
+	}
+	fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
+	return 1;
+    }
+
+    argc -= i;
+    argv += i;
+
+    config = notmuch_config_open (ctx, NULL, NULL);
+    if (config == NULL)
+	return 1;
+
+    query_string = query_string_from_args (ctx, argc, argv);
+    if (query_string == NULL) {
+	fprintf (stderr, "Out of memory\n");
+	return 1;
+    }
+
+    if (*query_string == '\0') {
+	fprintf (stderr, "Error: notmuch reply requires at least one search term.\n");
+	return 1;
+    }
+
+    notmuch = notmuch_database_open (notmuch_config_get_database_path (config),
+				     NOTMUCH_DATABASE_MODE_READ_ONLY);
+    if (notmuch == NULL)
+	return 1;
+
+    query = notmuch_query_create (notmuch, query_string);
+    if (query == NULL) {
+	fprintf (stderr, "Out of memory\n");
+	return 1;
+    }
+
+    addr = notmuch_guess_from(config, query);
+    if (addr == NULL) {
+	fprintf (stderr, "fatal error\n");
+	return 1;
+    }
+    printf("%s", addr);
+
+    notmuch_query_destroy (query);
+    notmuch_database_close (notmuch);
+
+    return ret;
+}
diff --git a/notmuch.c b/notmuch.c
index 13e2612..2810722 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -252,6 +252,14 @@ command_t commands[] = {
       "\n"
       "\tSee \"notmuch help search-terms\" for details of the search\n"
       "\tterms syntax." },
+    { "guess-from", notmuch_guess_from_command,
+      "[options...] <search-terms> [...]",
+      "Return the best guess for the from address when forwarding.",
+      "\tbased on the headers in the specified message, create the\n"
+      "\tbest guess From header and return it on stdout.\n"
+      "\n"
+      "\tSee \"notmuch help search-terms\" for details of the search\n"
+      "\tterms syntax." },
     { "tag", notmuch_tag_command,
       "+<tag>|-<tag> [...] [--] <search-terms> [...]",
       "Add/remove tags for all messages matching the search terms.",
-- 
1.6.6.1


-- 
Dirk Hohndel
Intel Open Source Technology Center


More information about the notmuch mailing list