From f998a0ad1ea8c4ac614a478ff01f5d877a99e58e Mon Sep 17 00:00:00 2001 From: Jun Hao Date: Sat, 16 Apr 2016 22:23:46 +0800 Subject: [PATCH 1/2] mu: expose content id to attachment plist --- lib/mu-msg-part.c | 9 +++++++++ lib/mu-msg-part.h | 11 +++++++++++ lib/mu-msg-sexp.c | 7 +++++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/mu-msg-part.c b/lib/mu-msg-part.c index 08782433..b6bbffc3 100644 --- a/lib/mu-msg-part.c +++ b/lib/mu-msg-part.c @@ -322,6 +322,15 @@ mu_msg_part_get_filename (MuMsgPart *mpart, gboolean construct_if_needed) mpart->index, construct_if_needed); } +const gchar* +mu_msg_part_get_content_id (MuMsgPart *mpart) +{ + g_return_val_if_fail (mpart, NULL); + g_return_val_if_fail (GMIME_IS_OBJECT(mpart->data), NULL); + return g_mime_object_get_content_id((GMimeObject*)mpart->data); +} + + static MuMsgPartType get_disposition (GMimeObject *mobj) diff --git a/lib/mu-msg-part.h b/lib/mu-msg-part.h index 5dd82a16..23bfaac8 100644 --- a/lib/mu-msg-part.h +++ b/lib/mu-msg-part.h @@ -114,6 +114,17 @@ char *mu_msg_part_get_filename (MuMsgPart *mpart, gboolean construct_if_needed) G_GNUC_WARN_UNUSED_RESULT; +/** + * get appropriate content id for the mime-part + * + * @param mpart a MuMsgPart + * + * @return const content id + */ +const gchar* +mu_msg_part_get_content_id (MuMsgPart *mpart) + G_GNUC_WARN_UNUSED_RESULT; + /** * get the text in the MuMsgPart (ie. in its GMimePart) * diff --git a/lib/mu-msg-sexp.c b/lib/mu-msg-sexp.c index a5629c50..a3740cdd 100644 --- a/lib/mu-msg-sexp.c +++ b/lib/mu-msg-sexp.c @@ -354,16 +354,17 @@ static void each_part (MuMsg *msg, MuMsgPart *part, PartInfo *pinfo) { char *name, *tmp, *parttype; - char *tmpfile; + char *tmpfile, *cid; name = mu_msg_part_get_filename (part, TRUE); tmpfile = get_temp_file_maybe (msg, part, pinfo->opts); parttype = get_part_type_string (part->part_type); + cid = mu_str_escape_c_literal(mu_msg_part_get_content_id(part), TRUE); tmp = g_strdup_printf ("%s(:index %d :name \"%s\" :mime-type \"%s/%s\"%s%s " ":type %s " - ":attachment %s :size %i %s %s)", + ":attachment %s %s%s :size %i %s %s)", pinfo->parts ? pinfo->parts: "", part->index, name ? mu_str_escape_c_literal(name, FALSE) : "noname", @@ -372,6 +373,7 @@ each_part (MuMsg *msg, MuMsgPart *part, PartInfo *pinfo) tmpfile ? " :temp" : "", tmpfile ? tmpfile : "", parttype, mu_msg_part_maybe_attachment (part) ? "t" : "nil", + cid ? " :cid" : "", cid ? cid : "", (int)part->size, sig_verdict (part), dec_verdict (part)); @@ -379,6 +381,7 @@ each_part (MuMsg *msg, MuMsgPart *part, PartInfo *pinfo) g_free (name); g_free (tmpfile); g_free (parttype); + g_free (cid); g_free (pinfo->parts); pinfo->parts = tmp; From d16957dc970471c9d46d94a34b94058871465755 Mon Sep 17 00:00:00 2001 From: Jun Hao Date: Sat, 16 Apr 2016 23:13:47 +0800 Subject: [PATCH 2/2] mu4e: handle attached image when write msg body to html --- mu4e/mu4e-actions.el | 19 +++++++++++++++++-- mu4e/mu4e-utils.el | 9 +++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/mu4e/mu4e-actions.el b/mu4e/mu4e-actions.el index d67b6a7e..7f145a14 100644 --- a/mu4e/mu4e-actions.el +++ b/mu4e/mu4e-actions.el @@ -74,14 +74,29 @@ Works for the message view." "Write the body (either html or text) to a temporary file; return the filename." (let* ((html (mu4e-message-field msg :body-html)) - (txt (mu4e-message-field msg :body-txt)) - (tmpfile (mu4e-make-temp-file "html"))) + (txt (mu4e-message-field msg :body-txt)) + (tmpfile (mu4e-make-temp-file "html")) + (attachments (remove-if (lambda (part) + (or (null (plist-get part :attachment)) + (null (plist-get part :cid)))) + (mu4e-message-field msg :parts)))) (unless (or html txt) (mu4e-error "No body part for this message")) (with-temp-buffer (insert "\n") (insert (or html (concat "
" txt "
"))) (write-file tmpfile) + ;; rewrite attachment urls + (mapc (lambda (attachment) + (goto-char (point-min)) + (while (re-search-forward (format "src=\"cid:%s\"" (plist-get attachment :cid)) nil t) + (if (plist-get attachment :temp) + (replace-match (format "src=\"%s\"" (plist-get attachment :temp))) + (replace-match (format "src=\"%s%s\"" temporary-file-directory (plist-get attachment :name))) + (mu4e~proc-extract 'save (mu4e-message-field :docid) (plist-get attachment :index) mu4e-decryption-policy temporary-file-directory) + (mu4e-remove-file-later (format "%s%s" temporary-file-directory (plist-get attachment :name)))))) + attachments) + (save-buffer) tmpfile))) (defun mu4e-action-view-in-browser (msg) diff --git a/mu4e/mu4e-utils.el b/mu4e/mu4e-utils.el index 817b6c95..1f8c9c08 100644 --- a/mu4e/mu4e-utils.el +++ b/mu4e/mu4e-utils.el @@ -139,6 +139,12 @@ return the result." (mu4e~get-folder 'mu4e-trash-folder msg)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun mu4e-remove-file-later (filename) + "Remove FILENAME in a few seconds." + (run-at-time "10 sec" nil + (lambda () (ignore-errors (delete-file filename))))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun mu4e-make-temp-file (ext) @@ -146,8 +152,7 @@ return the result." self-destruct in a few seconds, enough to open it in another program." (let ((tmpfile (make-temp-file "mu4e-" nil (concat "." ext)))) - (run-at-time "10 sec" nil - (lambda (fname) (ignore-errors (delete-file fname))) tmpfile) + (mu4e-remove-file-later tmpfile) tmpfile)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;