From: Keith Amidon <ke...@nicira.com> With this commit notmuch-show-mode supports saving a single attachment from a message (bound to 'w') and saving all attachments to the message (bound to 'W'). The new variable notmuch-default-save-dir allows the user to specify a directory within which attachments should be saved by default. The user can modify this default path, even specifying a non-existent directory path, in which case he or she will be prompted to create the path. Reporting of the actions taken is also improved. --- notmuch.el | 93 ++++++++++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 72 insertions(+), 21 deletions(-)
diff --git a/notmuch.el b/notmuch.el index 97914f2..b72548d 100644 --- a/notmuch.el +++ b/notmuch.el @@ -64,7 +64,8 @@ (define-key map "f" 'notmuch-show-forward-current) (define-key map "r" 'notmuch-show-reply) (define-key map "|" 'notmuch-show-pipe-message) - (define-key map "w" 'notmuch-show-save-attachments) + (define-key map "w" 'notmuch-show-save-attachment) + (define-key map "W" 'notmuch-show-save-all-attachments) (define-key map "V" 'notmuch-show-view-raw-message) (define-key map "v" 'notmuch-show-view-all-mime-parts) (define-key map "-" 'notmuch-show-remove-tag) @@ -98,6 +99,9 @@ pattern can still test against the entire line).") (defvar notmuch-command "notmuch" "Command to run the notmuch binary.") +(defvar notmuch-default-save-dir (file-name-as-directory (getenv "HOME" )) + "Default directory in which attachments are saved.") + (defvar notmuch-show-message-begin-regexp "\fmessage{") (defvar notmuch-show-message-end-regexp "\fmessage}") (defvar notmuch-show-header-begin-regexp "\fheader{") @@ -329,28 +333,75 @@ buffer." mm-handle) count)) -(defun notmuch-save-attachments (mm-handle &optional queryp) - (notmuch-foreach-mime-part - (lambda (p) - (let ((disposition (mm-handle-disposition p))) - (and (listp disposition) - (or (equal (car disposition) "attachment") - (and (equal (car disposition) "inline") - (assq 'filename disposition))) - (or (not queryp) - (y-or-n-p - (concat "Save '" (cdr (assq 'filename disposition)) "' "))) - (mm-save-part p)))) - mm-handle)) - -(defun notmuch-show-save-attachments () - "Save all attachments from the current message." - (interactive) +(defun notmuch-attachment-q (mm-handle) + (let ((disposition (mm-handle-disposition p))) + (and (listp disposition) + (assq 'filename disposition)))) + +(defun notmuch-get-save-path (filename default-dir) + (let ((savepath nil)) + (while (not savepath) + (let* ((ddir (file-name-as-directory default-dir)) + (fn (read-file-name "Save to: " ddir nil nil filename)) + (efn (expand-file-name fn)) + (dir (file-name-directory efn))) + (when (not (file-accessible-directory-p dir)) + (when (y-or-n-p (concat "Create directory " dir " ")) + (make-directory dir t))) + (if (file-accessible-directory-p dir) + (setq savepath fn) + (setq default-dir (file-name-directory fn))))) + savepath)) + +(defun notmuch-save-attachment (mm-handle default-dir) + "Save the current attachment part to a file." + (cond ((not (notmuch-attachment-q mm-handle)) + (message "Current part is not an attachment.") + nil) + (t + (let* ((fn (cdr (assq 'filename (mm-handle-disposition mm-handle)))) + (savepath (notmuch-get-save-path fn default-dir))) + (mm-save-part-to-file mm-handle savepath) + savepath)))) + +(defun notmuch-save-attachment-num (mm-handle part-num) + "Save the nth part number" + (let ((nfound 0) + (nsaved 0)) + (notmuch-foreach-mime-part + (lambda (p) + (when (notmuch-attachment-q p) + (cond ((equal (+ 1 nfound) part-num) + (when (notmuch-save-attachment p notmuch-default-save-dir) + (incf nsaved)))) + (incf nfound))) mm-handle) + (equal nsaved 1))) + +(defun notmuch-show-save-attachment (num) + "Save a single attachment." + (interactive "p") (with-current-notmuch-show-message (let ((mm-handle (mm-dissect-buffer))) - (notmuch-save-attachments - mm-handle (> (notmuch-count-attachments mm-handle) 1)))) - (message "Done")) + (if (notmuch-save-attachment-num mm-handle num) + (message "Attachment %d saved." num) + (message "Failed to save attachment."))))) + +(defun notmuch-show-save-all-attachments () + "Save all attachments of a message to a directory." + (interactive) + (with-current-notmuch-show-message + (let ((nfound 0) + (nsaved 0) + (default-dir notmuch-default-save-dir) + (mm-handle (mm-dissect-buffer))) + (notmuch-foreach-mime-part + (lambda (p) + (when (notmuch-attachment-q p) + (incf nfound) + (let ((savepath (notmuch-save-attachment p default-dir))) + (when savepath + (setq default-dir (file-name-directory savepath)))))) mm-handle) + (message "Saved %d attachments" nfound)))) (defun notmuch-reply (query-string) (switch-to-buffer (generate-new-buffer "notmuch-draft")) -- 1.6.5.6