1 Return-Path: <camalot@picnicpark.org>
\r
2 X-Original-To: notmuch@notmuchmail.org
\r
3 Delivered-To: notmuch@notmuchmail.org
\r
4 Received: from localhost (localhost [127.0.0.1])
\r
5 by olra.theworths.org (Postfix) with ESMTP id 02A89431FC0
\r
6 for <notmuch@notmuchmail.org>; Mon, 14 Dec 2009 10:14:38 -0800 (PST)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\r
8 Received: from olra.theworths.org ([127.0.0.1])
\r
9 by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)
\r
10 with ESMTP id ZsGj8P7E22uE for <notmuch@notmuchmail.org>;
\r
11 Mon, 14 Dec 2009 10:14:37 -0800 (PST)
\r
12 Received: from mout.perfora.net (mout.perfora.net [74.208.4.195])
\r
13 by olra.theworths.org (Postfix) with ESMTP id 3C562431FAE
\r
14 for <notmuch@notmuchmail.org>; Mon, 14 Dec 2009 10:14:37 -0800 (PST)
\r
15 Received: from vps.nicira.com (66.7.219.28.static.dimenoc.com [66.7.219.28])
\r
16 by mx.perfora.net (node=mxus1) with ESMTP (Nemesis)
\r
17 id 0LvCiQ-1O1fA62TIY-00znvX for notmuch@notmuchmail.org;
\r
18 Mon, 14 Dec 2009 13:14:36 -0500
\r
19 Received: from hq.nicira.com ([209.172.104.10]:55884 helo=kea-nicira-lt)
\r
20 by vps.nicira.com with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.69)
\r
21 (envelope-from <camalot@picnicpark.org>)
\r
22 id 1NKFRE-00046m-Ay; Mon, 14 Dec 2009 13:14:30 -0500
\r
23 Received: by kea-nicira-lt (sSMTP sendmail emulation);
\r
24 Mon, 14 Dec 2009 10:14:25 -0800
\r
25 From: camalot@picnicpark.org
\r
26 To: notmuch@notmuchmail.org
\r
27 Date: Mon, 14 Dec 2009 10:13:58 -0800
\r
28 Message-Id: <1260814438-4195-2-git-send-email-camalot@picnicpark.org>
\r
29 X-Mailer: git-send-email 1.6.5.6
\r
30 In-Reply-To: <1260814438-4195-1-git-send-email-camalot@picnicpark.org>
\r
31 References: <87my1m323m.fsf@yoom.home.cworth.org>
\r
32 <1260814438-4195-1-git-send-email-camalot@picnicpark.org>
\r
33 X-AntiAbuse: This header was added to track abuse,
\r
34 please include it with any abuse report
\r
35 X-AntiAbuse: Primary Hostname - vps.nicira.com
\r
36 X-AntiAbuse: Original Domain - notmuchmail.org
\r
37 X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
\r
38 X-AntiAbuse: Sender Address Domain - picnicpark.org
\r
42 Cc: Keith Amidon <keith@nicira.com>
\r
43 Subject: [notmuch] [PATCH] Rework saving of attachments.
\r
44 X-BeenThere: notmuch@notmuchmail.org
\r
45 X-Mailman-Version: 2.1.12
\r
47 List-Id: "Use and development of the notmuch mail system."
\r
48 <notmuch.notmuchmail.org>
\r
49 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
50 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
51 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
52 List-Post: <mailto:notmuch@notmuchmail.org>
\r
53 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
54 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
55 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
56 X-List-Received-Date: Mon, 14 Dec 2009 18:14:38 -0000
\r
58 From: Keith Amidon <keith@nicira.com>
\r
60 With this commit notmuch-show-mode supports saving a single attachment
\r
61 from a message (bound to 'w') and saving all attachments to the
\r
62 message (bound to 'W'). The new variable notmuch-default-save-dir
\r
63 allows the user to specify a directory within which attachments should
\r
64 be saved by default. The user can modify this default path, even
\r
65 specifying a non-existent directory path, in which case he or she will
\r
66 be prompted to create the path. Reporting of the actions taken is
\r
69 notmuch.el | 93 ++++++++++++++++++++++++++++++++++++++++++++++-------------
\r
70 1 files changed, 72 insertions(+), 21 deletions(-)
\r
72 diff --git a/notmuch.el b/notmuch.el
\r
73 index 97914f2..b72548d 100644
\r
77 (define-key map "f" 'notmuch-show-forward-current)
\r
78 (define-key map "r" 'notmuch-show-reply)
\r
79 (define-key map "|" 'notmuch-show-pipe-message)
\r
80 - (define-key map "w" 'notmuch-show-save-attachments)
\r
81 + (define-key map "w" 'notmuch-show-save-attachment)
\r
82 + (define-key map "W" 'notmuch-show-save-all-attachments)
\r
83 (define-key map "V" 'notmuch-show-view-raw-message)
\r
84 (define-key map "v" 'notmuch-show-view-all-mime-parts)
\r
85 (define-key map "-" 'notmuch-show-remove-tag)
\r
86 @@ -98,6 +99,9 @@ pattern can still test against the entire line).")
\r
87 (defvar notmuch-command "notmuch"
\r
88 "Command to run the notmuch binary.")
\r
90 +(defvar notmuch-default-save-dir (file-name-as-directory (getenv "HOME" ))
\r
91 + "Default directory in which attachments are saved.")
\r
93 (defvar notmuch-show-message-begin-regexp "\fmessage{")
\r
94 (defvar notmuch-show-message-end-regexp "\fmessage}")
\r
95 (defvar notmuch-show-header-begin-regexp "\fheader{")
\r
96 @@ -329,28 +333,75 @@ buffer."
\r
100 -(defun notmuch-save-attachments (mm-handle &optional queryp)
\r
101 - (notmuch-foreach-mime-part
\r
103 - (let ((disposition (mm-handle-disposition p)))
\r
104 - (and (listp disposition)
\r
105 - (or (equal (car disposition) "attachment")
\r
106 - (and (equal (car disposition) "inline")
\r
107 - (assq 'filename disposition)))
\r
110 - (concat "Save '" (cdr (assq 'filename disposition)) "' ")))
\r
111 - (mm-save-part p))))
\r
114 -(defun notmuch-show-save-attachments ()
\r
115 - "Save all attachments from the current message."
\r
117 +(defun notmuch-attachment-q (mm-handle)
\r
118 + (let ((disposition (mm-handle-disposition p)))
\r
119 + (and (listp disposition)
\r
120 + (assq 'filename disposition))))
\r
122 +(defun notmuch-get-save-path (filename default-dir)
\r
123 + (let ((savepath nil))
\r
124 + (while (not savepath)
\r
125 + (let* ((ddir (file-name-as-directory default-dir))
\r
126 + (fn (read-file-name "Save to: " ddir nil nil filename))
\r
127 + (efn (expand-file-name fn))
\r
128 + (dir (file-name-directory efn)))
\r
129 + (when (not (file-accessible-directory-p dir))
\r
130 + (when (y-or-n-p (concat "Create directory " dir " "))
\r
131 + (make-directory dir t)))
\r
132 + (if (file-accessible-directory-p dir)
\r
133 + (setq savepath fn)
\r
134 + (setq default-dir (file-name-directory fn)))))
\r
137 +(defun notmuch-save-attachment (mm-handle default-dir)
\r
138 + "Save the current attachment part to a file."
\r
139 + (cond ((not (notmuch-attachment-q mm-handle))
\r
140 + (message "Current part is not an attachment.")
\r
143 + (let* ((fn (cdr (assq 'filename (mm-handle-disposition mm-handle))))
\r
144 + (savepath (notmuch-get-save-path fn default-dir)))
\r
145 + (mm-save-part-to-file mm-handle savepath)
\r
148 +(defun notmuch-save-attachment-num (mm-handle part-num)
\r
149 + "Save the nth part number"
\r
152 + (notmuch-foreach-mime-part
\r
154 + (when (notmuch-attachment-q p)
\r
155 + (cond ((equal (+ 1 nfound) part-num)
\r
156 + (when (notmuch-save-attachment p notmuch-default-save-dir)
\r
158 + (incf nfound))) mm-handle)
\r
159 + (equal nsaved 1)))
\r
161 +(defun notmuch-show-save-attachment (num)
\r
162 + "Save a single attachment."
\r
163 + (interactive "p")
\r
164 (with-current-notmuch-show-message
\r
165 (let ((mm-handle (mm-dissect-buffer)))
\r
166 - (notmuch-save-attachments
\r
167 - mm-handle (> (notmuch-count-attachments mm-handle) 1))))
\r
168 - (message "Done"))
\r
169 + (if (notmuch-save-attachment-num mm-handle num)
\r
170 + (message "Attachment %d saved." num)
\r
171 + (message "Failed to save attachment.")))))
\r
173 +(defun notmuch-show-save-all-attachments ()
\r
174 + "Save all attachments of a message to a directory."
\r
176 + (with-current-notmuch-show-message
\r
179 + (default-dir notmuch-default-save-dir)
\r
180 + (mm-handle (mm-dissect-buffer)))
\r
181 + (notmuch-foreach-mime-part
\r
183 + (when (notmuch-attachment-q p)
\r
185 + (let ((savepath (notmuch-save-attachment p default-dir)))
\r
187 + (setq default-dir (file-name-directory savepath)))))) mm-handle)
\r
188 + (message "Saved %d attachments" nfound))))
\r
190 (defun notmuch-reply (query-string)
\r
191 (switch-to-buffer (generate-new-buffer "notmuch-draft"))
\r