* mu4e: get information about all mime parts, not just attachments

This commit is contained in:
djcb
2012-05-13 13:10:56 +03:00
parent 5dbc2fbcd7
commit 0834dd5974
2 changed files with 56 additions and 33 deletions

View File

@ -112,12 +112,26 @@ where:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; some buffer-local variables ;; some buffer-local variables / constants
(defvar mu4e~view-headers-buffer nil (defvar mu4e~view-headers-buffer nil
"*internal* Headers buffer connected to this view.") "The headers buffer connected to this view.")
(defvar mu4e~view-lines-wrapped nil "Whether lines are wrapped.")
(defvar mu4e~view-cited-hidden nil "Whether cited lines are hidden.")
(defvar mu4e~view-link-map nil
"A map of some number->url so we can jump to url by number.")
(defconst mu4e~view-url-regexp
"\\(https?://[-+a-zA-Z0-9.?_$%/+&#@!~,:;=/()]+\\)"
"Regexp that matches URLs; match-string 1 will contain
the matched URL, if any.")
(defvar mu4e~view-attach-map nil
"A mapping of user-visible attachment number to the actual part index.")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar mu4e~view-lines-wrapped nil "*internal* Whether lines are wrapped.")
(defvar mu4e~view-cited-hidden nil "*internal* Whether cited lines are hidden.")
(defun mu4e-view-message-with-msgid (msgid) (defun mu4e-view-message-with-msgid (msgid)
@ -261,21 +275,32 @@ is nil, and otherwise open it."
(mu4e-view-open-attachment msg attachnum) (mu4e-view-open-attachment msg attachnum)
(mu4e-view-save-attachment msg attachnum))))) (mu4e-view-save-attachment msg attachnum)))))
;; note -- attachments have an index which is needed for the backend, which does
;; not necessarily follow 1,2,3,4 etc.
(defun mu4e~view-construct-attachments (msg) (defun mu4e~view-construct-attachments (msg)
"Display attachment information; the field looks like something like: "Display attachment information; the field looks like something like:
:attachments ((:index 4 :name \"test123.doc\" :parts ((:index 1 :name \"test123.doc\"
:mime-type \"application/msword\" :size 1234))." :mime-type \"application/msword\" :attachment t :size 1234)
(:index 2 :name \"test456.pdf\"
:mime-type \"application/pdf\" :attachment t :size 12234))."
(setq mu4e~view-attach-map ;; buffer local
(make-hash-table :size 16 :rehash-size 2 :weakness nil))
(let* ((id 0) (let* ((id 0)
(attachments
;; we only list parts that look like attachments, ie. that have a
;; non-nil :attachment property; we record a mapping between user-visible
;; numbers and the part indices
(remove-if-not
(lambda (part)
(plist-get part :attachment))
(plist-get msg :parts)))
(attstr (attstr
(mapconcat (mapconcat
(lambda (att) (lambda (part)
(let ( (index (plist-get att :index)) (let ((index (plist-get part :index))
(name (plist-get att :name)) (name (plist-get part :name))
(size (plist-get att :size)) (size (plist-get part :size))
(map (make-sparse-keymap))) (map (make-sparse-keymap)))
(incf id) (incf id)
(puthash id index mu4e~view-attach-map)
(define-key map [mouse-2] (define-key map [mouse-2]
(mu4e~view-open-save-attach-func msg id nil)) (mu4e~view-open-save-attach-func msg id nil))
(define-key map [?\r] (define-key map [?\r]
@ -292,7 +317,7 @@ is nil, and otherwise open it."
(concat (format "(%s)" (concat (format "(%s)"
(propertize (mu4e-display-size size) (propertize (mu4e-display-size size)
'face 'mu4e-view-header-key-face))))))) 'face 'mu4e-view-header-key-face)))))))
(plist-get msg :attachments) ", "))) attachments ", ")))
(unless (zerop id) (unless (zerop id)
(mu4e~view-construct-header (format "Attachments(%d)" id) attstr t)))) (mu4e~view-construct-header (format "Attachments(%d)" id) attstr t))))
@ -457,6 +482,7 @@ is nil, and otherwise open it."
(make-local-variable 'mu4e~view-headers-buffer) (make-local-variable 'mu4e~view-headers-buffer)
(make-local-variable 'mu4e~view-msg) (make-local-variable 'mu4e~view-msg)
(make-local-variable 'mu4e~view-link-map) (make-local-variable 'mu4e~view-link-map)
(make-local-variable 'mu4e~view-attach-map)
(make-local-variable 'mu4e~view-lines-wrapped) (make-local-variable 'mu4e~view-lines-wrapped)
(make-local-variable 'mu4e~view-cited-hidden) (make-local-variable 'mu4e~view-cited-hidden)
@ -528,14 +554,6 @@ Seen; if the message is not New/Unread, do nothing."
(when p (when p
(add-text-properties p (point-max) '(face mu4e-footer-face))))))) (add-text-properties p (point-max) '(face mu4e-footer-face)))))))
(defvar mu4e~view-link-map nil
"*internal* A map of some number->url so we can jump to url by number.")
(defconst mu4e~view-url-regexp
"\\(https?://[-+a-zA-Z0-9.?_$%/+&#@!~,:;=/()]+\\)"
"*internal* regexp that matches URLs; match-string 1 will contain
the matched URL, if any.")
(defun mu4e~view-browse-url-func (url) (defun mu4e~view-browse-url-func (url)
"Return a function that executes `browse-url' with URL." "Return a function that executes `browse-url' with URL."
(lexical-let ((url url)) (lexical-let ((url url))
@ -705,8 +723,7 @@ all messages in the thread at point in the headers view."
"Ask the user with PROMPT for an attachment number for MSG, and "Ask the user with PROMPT for an attachment number for MSG, and
ensure it is valid. The number is [1..n] for attachments ensure it is valid. The number is [1..n] for attachments
[0..(n-1)] in the message." [0..(n-1)] in the message."
(let* ((attlist (plist-get msg :attachments)) (let* ((count (hash-table-count mu4e~view-attach-map)))
(count (length attlist)))
(when (zerop count) (error "No attachments for this message")) (when (zerop count) (error "No attachments for this message"))
(if (= count 1) (if (= count 1)
(read-number (mu4e-format "%s: " prompt) 1) (read-number (mu4e-format "%s: " prompt) 1)
@ -715,8 +732,12 @@ all messages in the thread at point in the headers view."
(defun mu4e~view-get-attach (msg attnum) (defun mu4e~view-get-attach (msg attnum)
"Return the attachment plist in MSG corresponding to attachment "Return the attachment plist in MSG corresponding to attachment
number ATTNUM." number ATTNUM."
(let ((attlist (plist-get msg :attachments))) (let ((partid (gethash attnum mu4e~view-attach-map)))
(nth (- attnum 1) attlist))) (find-if
(lambda (part)
(eq (plist-get part :index) partid))
(plist-get msg :parts))))
(defun mu4e-view-save-attachment (&optional msg attnum) (defun mu4e-view-save-attachment (&optional msg attnum)
"Save attachment number ATTNUM (or ask if nil) from MSG (or "Save attachment number ATTNUM (or ask if nil) from MSG (or

View File

@ -208,9 +208,6 @@ each_part (MuMsg *msg, MuMsgPart *part, gchar **parts)
const char *fname; const char *fname;
char *name, *tmp; char *name, *tmp;
if (!mu_msg_part_looks_like_attachment (part, TRUE))
return;
fname = mu_msg_part_file_name (part); fname = mu_msg_part_file_name (part);
if (!fname) if (!fname)
fname = mu_msg_part_description (part); fname = mu_msg_part_description (part);
@ -218,13 +215,18 @@ each_part (MuMsg *msg, MuMsgPart *part, gchar **parts)
if (fname) if (fname)
name = mu_str_escape_c_literal (fname, TRUE); name = mu_str_escape_c_literal (fname, TRUE);
else else
name = g_strdup_printf ("\"part-%d\"", part->index); name = g_strdup_printf
("\"%s-%s-%d\"",
part->type ? part->type : "application",
part->subtype ? part->subtype : "octet-stream",
part->index);
tmp = g_strdup_printf tmp = g_strdup_printf
("%s(:index %d :name %s :mime-type \"%s/%s\" :size %i)", ("%s(:index %d :name %s :mime-type \"%s/%s\" :attachment %s :size %i)",
*parts ? *parts : "", part->index, name, *parts ? *parts : "", part->index, name,
part->type ? part->type : "application", part->type ? part->type : "application",
part->subtype ? part->subtype : "octet-stream", part->subtype ? part->subtype : "octet-stream",
mu_msg_part_looks_like_attachment (part, TRUE) ? "t" : "nil",
(int)part->size); (int)part->size);
g_free (*parts); g_free (*parts);
@ -233,7 +235,7 @@ each_part (MuMsg *msg, MuMsgPart *part, gchar **parts)
static void static void
append_sexp_attachments (GString *gstr, MuMsg *msg) append_sexp_parts (GString *gstr, MuMsg *msg)
{ {
char *parts; char *parts;
@ -242,7 +244,7 @@ append_sexp_attachments (GString *gstr, MuMsg *msg)
(MuMsgPartForeachFunc)each_part, &parts); (MuMsgPartForeachFunc)each_part, &parts);
if (parts) { if (parts) {
g_string_append_printf (gstr, "\t:attachments (%s)\n", parts); g_string_append_printf (gstr, "\t:parts (%s)\n", parts);
g_free (parts); g_free (parts);
} }
} }
@ -252,7 +254,7 @@ append_sexp_attachments (GString *gstr, MuMsg *msg)
static void static void
append_sexp_message_file_attr (GString *gstr, MuMsg *msg) append_sexp_message_file_attr (GString *gstr, MuMsg *msg)
{ {
append_sexp_attachments (gstr, msg); append_sexp_parts (gstr, msg);
append_sexp_attr_list (gstr, "references", mu_msg_get_references (msg)); append_sexp_attr_list (gstr, "references", mu_msg_get_references (msg));
append_sexp_attr (gstr, "in-reply-to", append_sexp_attr (gstr, "in-reply-to",