Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id 02A89431FC0 for ; Mon, 14 Dec 2009 10:14:38 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ZsGj8P7E22uE for ; Mon, 14 Dec 2009 10:14:37 -0800 (PST) Received: from mout.perfora.net (mout.perfora.net [74.208.4.195]) by olra.theworths.org (Postfix) with ESMTP id 3C562431FAE for ; Mon, 14 Dec 2009 10:14:37 -0800 (PST) Received: from vps.nicira.com (66.7.219.28.static.dimenoc.com [66.7.219.28]) by mx.perfora.net (node=mxus1) with ESMTP (Nemesis) id 0LvCiQ-1O1fA62TIY-00znvX for notmuch@notmuchmail.org; Mon, 14 Dec 2009 13:14:36 -0500 Received: from hq.nicira.com ([209.172.104.10]:55884 helo=kea-nicira-lt) by vps.nicira.com with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.69) (envelope-from ) id 1NKFRE-00046m-Ay; Mon, 14 Dec 2009 13:14:30 -0500 Received: by kea-nicira-lt (sSMTP sendmail emulation); Mon, 14 Dec 2009 10:14:25 -0800 From: camalot@picnicpark.org To: notmuch@notmuchmail.org Date: Mon, 14 Dec 2009 10:13:58 -0800 Message-Id: <1260814438-4195-2-git-send-email-camalot@picnicpark.org> X-Mailer: git-send-email 1.6.5.6 In-Reply-To: <1260814438-4195-1-git-send-email-camalot@picnicpark.org> References: <87my1m323m.fsf@yoom.home.cworth.org> <1260814438-4195-1-git-send-email-camalot@picnicpark.org> X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - vps.nicira.com X-AntiAbuse: Original Domain - notmuchmail.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - picnicpark.org X-Source: X-Source-Args: X-Source-Dir: Cc: Keith Amidon Subject: [notmuch] [PATCH] Rework saving of attachments. X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 14 Dec 2009 18:14:38 -0000 From: Keith Amidon 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