From 6c0621962a7990d15da50d38300ad9fd07e97592 Mon Sep 17 00:00:00 2001 From: David Edmondson Date: Tue, 23 Mar 2010 11:54:05 +0000 Subject: [PATCH] emacs: Use mailcap.el to guess the type of application/octet-stream parts Use the mailcap functionality to guess a MIME type for attachments of type application/octet-stream and, presuming successful, feed the attachment back into the display code with the determine type. This is mostly useless at the moment, as the JSON output from notmuch does not include the content of application/octet-stream parts, so they cannot be displayed even if the guess is a good one. --- emacs/notmuch-show.el | 54 +++++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 7d25dd57..57a52151 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -25,6 +25,7 @@ (require 'mm-view) (require 'message) (require 'mm-decode) +(require 'mailcap) (require 'notmuch-lib) (require 'notmuch-query) @@ -203,14 +204,17 @@ message at DEPTH in the current thread." (narrow-to-region start (point-max)) (run-hooks 'notmuch-show-markup-headers-hook))))) -(defun notmuch-show-insert-part-header (content-type &optional name) +(defun notmuch-show-insert-part-header (content-type declared-type &optional name) (let ((start (point))) ;; XXX dme: Make this a more useful button (save the part, display ;; external, etc.) - (insert "[ Part of type " - content-type - (if name (concat " named " name) "") - ". ]\n") + (insert "[ " + (if name (concat name ": ") "") + declared-type + (if (not (string-equal declared-type content-type)) + (concat " (as " content-type ")") + "") + " ]\n") (overlay-put (make-overlay start (point)) 'face 'bold))) ;; Functions handling particular MIME parts. @@ -233,12 +237,12 @@ message at DEPTH in the current thread." t))) nil) -(defun notmuch-show-insert-part-text/plain (part content-type nth depth) +(defun notmuch-show-insert-part-text/plain (part content-type nth depth declared-type) (let ((start (point))) ;; If this text/plain part is not the first part in the message, ;; insert a header to make this clear. (if (> nth 1) - (notmuch-show-insert-part-header content-type (plist-get part :filename))) + (notmuch-show-insert-part-header declared-type content-type (plist-get part :filename))) (insert (plist-get part :content)) (save-excursion (save-restriction @@ -246,8 +250,24 @@ message at DEPTH in the current thread." (run-hook-with-args 'notmuch-show-insert-text/plain-hook depth)))) t) -(defun notmuch-show-insert-part-*/* (part content-type nth depth) - (notmuch-show-insert-part-header content-type (plist-get part :filename)) +(defun notmuch-show-insert-part-application/octet-stream (part content-type nth depth declared-type) + ;; If we can deduce a MIME type from the filename of the attachment, + ;; do so and pass it on to the handler for that type. + (if (plist-get part :filename) + (let ((extension (file-name-extension (plist-get part :filename))) + mime-type) + (if extension + (progn + (mailcap-parse-mimetypes) + (setq mime-type (mailcap-extension-to-mime extension)) + (if (and mime-type + (not (string-equal mime-type "application/octet-stream"))) + (notmuch-show-insert-bodypart-internal msg part mime-type nth depth content-type) + nil)) + nil)))) + +(defun notmuch-show-insert-part-*/* (part content-type nth depth declared-type) + (notmuch-show-insert-part-header content-type declared-type (plist-get part :filename)) ;; If we have the content for the part, attempt to inline it. (if (plist-get part :content) (notmuch-show-mm-display-part-inline part content-type)) @@ -275,16 +295,20 @@ message at DEPTH in the current thread." ;; -(defun notmuch-show-insert-bodypart (part depth) - "Insert the body part PART at depth DEPTH in the current thread." - (let* ((content-type (downcase (plist-get part :content-type))) - (handlers (notmuch-show-handlers-for content-type)) - (nth (plist-get part :id))) +(defun notmuch-show-insert-bodypart-internal (part content-type nth depth declared-type) + (let ((handlers (notmuch-show-handlers-for content-type))) ;; Run the content handlers until one of them returns a non-nil ;; value. (while (and handlers - (not (funcall (car handlers) part content-type nth depth))) + (not (funcall (car handlers) part content-type nth depth declared-type))) (setq handlers (cdr handlers)))) + t) + +(defun notmuch-show-insert-bodypart (part depth) + "Insert the body part PART at depth DEPTH in the current thread." + (let ((content-type (downcase (plist-get part :content-type))) + (nth (plist-get part :id))) + (notmuch-show-insert-bodypart-internal part content-type nth depth content-type)) ;; Ensure that the part ends with a carriage return. (if (not (bolp)) (insert "\n")) -- 2.26.2