diff options
| -rw-r--r-- | TODO.org | 145 | ||||
| -rw-r--r-- | modules/mail-config.el | 121 |
2 files changed, 159 insertions, 107 deletions
@@ -786,76 +786,7 @@ This is the result of overriding that function in cj/invincible-buffers in syste *** DONE [#C] Bookmark-save-flag Replaces Bookmark-set-and-save CLOSED: [2024-04-03 Wed 15:00] remove cj/bookmark-set-and-save if setting bookmark-save-flat to 1 saves when adding/modifying a bookmark -** DOING Open v0.7 Fit and Finish (ends 2024.04.20) [0/2] -*** DOING [#B] Save All Attachments Working in Mu4e -**** 2024-04-18 Thu @ 05:55:32 -0500 The Documentation Suggests A Path Forward -This suggests that if I'm writing another function, I should -- first query the user to select/create the directory -- make sure mu4e-view-completion-minor-mode is on -- call mu4e-view-complete-all to get all the files -- within the context of mu4e-view-save-attachments - -#+BEGIN_QUOTE -E-mail messages can be though as a series of “MIME-parts”, which are sections of the message. The most prominent is the ’body’, that is the main message your are reading. Many e-mail messages also contains attachments, which MIME-parts that contain files10. - -To save such attachments as files on your file systems, the mu4e message-view offers the command mu4e-view-save-attachments; default keybinding is e (think extract). After invoking the command, you can enter the file names to save, comma-separated, and using the completion support. Press RET to save the chosen files to your file-system. - -With a prefix argument, you get to choose the target-directory, otherwise, mu4e determines it following the variable mu4e-attachment-dir (which can be file-system path or a function; see its docstring for details. - -While completing, mu4e-view-completion-minor-mode is active, which offers mu4e-view-complete-all (bound to C-c C-a to complete all files11. -#+END_QUOTE -[[https://www.djcbsoftware.nl/code/mu/mu4e/MSGV-Attachments-and-MIME_002dparts.html][MSGV Attachments and MIME-parts (Mu4e 1.12.3 user manual)]] - -**** 2024-04-18 Thu @ 05:05:03 -0500 Etienne's config failed -It relies on this line to find all the mime-parts: - -(let ((parts (mu4e--view-gather-mime-parts)) - -and that doesn't exist any longer. -**** Test Etienne's Configuration -https://etienne.depar.is/emacs.d/mu4e.html -(defun ed/mu4e-view-save-all-attachments (&optional arg) - "Save all attachments of a given message. - -If ARG is nil, all attachments will be saved in -`mu4e-attachment-dir'. When non-nil, user will be prompted to -choose a specific directory where to save all the files." - (interactive "P") - (when (and (eq major-mode 'mu4e-view-mode) - (derived-mode-p 'gnus-article-mode)) - (let ((parts (mu4e--view-gather-mime-parts)) - (handles '()) - (files '()) - (directory (if arg - (read-directory-name "Save to directory: ") - mu4e-attachment-dir))) - (dolist (part parts) - (let ((fname (or (cdr (assoc 'filename (assoc "attachment" (cdr part)))) - (cl-loop for item in part - for name = (and (listp item) (assoc-default 'name item)) - thereis (and (stringp name) name))))) - (when fname - (push `(,fname . ,(cdr part)) handles) - (push fname files)))) - (if files - (cl-loop for (f . h) in handles - when (member f files) - do (mm-save-part-to-file - h (let ((file (expand-file-name f directory))) - (if (file-exists-p file) - (let (newname (count 1)) - (while (and - (setq newname - (format "%s-%s%s" - (file-name-sans-extension file) - count - (file-name-extension file t))) - (file-exists-p newname)) - (cl-incf count)) - newname) - file)))) - (mu4e-message "No attached files found"))))) -(define-key mu4e-view-mode-map "X" #'ed/mu4e-view-save-all-attachments) +** DOING Open v0.7 Fit and Finish (ends 2024.04.20) [0/1] *** TODO [#B] Get queued email working for both mail accounts **** using sendmail for gmail #+BEGIN_QUOTE @@ -1269,6 +1200,80 @@ This involves changing webclipper. Webclipper as it is now doesn't return the co What I want is something to return the content in the way that a template would expect it. This way, I can create templates that would work with org-roam as well, such as creating a separate org-roam node just by clicking an org-protocol bookmarklet. This might be too large to fit as a bug fix for v0.7. I began doing some research (below) yesterday to help me size the work. +**** DONE [#B] Save All Attachments Working in Mu4e +CLOSED: [2024-04-26 Fri 17:04] +:LOGBOOK: +- State "DONE" from "DOING" [2024-04-26 Fri 17:04] +:END: + +***** 2024-04-18 Thu @ 05:55:32 -0500 The Documentation Suggests A Path Forward +This suggests that if I'm writing another function, I should +- first query the user to select/create the directory +- make sure mu4e-view-completion-minor-mode is on +- call mu4e-view-complete-all to get all the files +- within the context of mu4e-view-save-attachments + +#+BEGIN_QUOTE +E-mail messages can be though as a series of “MIME-parts”, which are sections of the message. The most prominent is the ’body’, that is the main message your are reading. Many e-mail messages also contains attachments, which MIME-parts that contain files10. + +To save such attachments as files on your file systems, the mu4e message-view offers the command mu4e-view-save-attachments; default keybinding is e (think extract). After invoking the command, you can enter the file names to save, comma-separated, and using the completion support. Press RET to save the chosen files to your file-system. + +With a prefix argument, you get to choose the target-directory, otherwise, mu4e determines it following the variable mu4e-attachment-dir (which can be file-system path or a function; see its docstring for details. + +While completing, mu4e-view-completion-minor-mode is active, which offers mu4e-view-complete-all (bound to C-c C-a to complete all files11. +#+END_QUOTE +[[https://www.djcbsoftware.nl/code/mu/mu4e/MSGV-Attachments-and-MIME_002dparts.html][MSGV Attachments and MIME-parts (Mu4e 1.12.3 user manual)]] + +***** 2024-04-18 Thu @ 05:05:03 -0500 Etienne's config failed +It relies on this line to find all the mime-parts: + +(let ((parts (mu4e--view-gather-mime-parts)) + +and that doesn't exist any longer. +***** Test Etienne's Configuration +https://etienne.depar.is/emacs.d/mu4e.html +(defun ed/mu4e-view-save-all-attachments (&optional arg) + "Save all attachments of a given message. + +If ARG is nil, all attachments will be saved in +`mu4e-attachment-dir'. When non-nil, user will be prompted to +choose a specific directory where to save all the files." + (interactive "P") + (when (and (eq major-mode 'mu4e-view-mode) + (derived-mode-p 'gnus-article-mode)) + (let ((parts (mu4e--view-gather-mime-parts)) + (handles '()) + (files '()) + (directory (if arg + (read-directory-name "Save to directory: ") + mu4e-attachment-dir))) + (dolist (part parts) + (let ((fname (or (cdr (assoc 'filename (assoc "attachment" (cdr part)))) + (cl-loop for item in part + for name = (and (listp item) (assoc-default 'name item)) + thereis (and (stringp name) name))))) + (when fname + (push `(,fname . ,(cdr part)) handles) + (push fname files)))) + (if files + (cl-loop for (f . h) in handles + when (member f files) + do (mm-save-part-to-file + h (let ((file (expand-file-name f directory))) + (if (file-exists-p file) + (let (newname (count 1)) + (while (and + (setq newname + (format "%s-%s%s" + (file-name-sans-extension file) + count + (file-name-extension file t))) + (file-exists-p newname)) + (cl-incf count)) + newname) + file)))) + (mu4e-message "No attached files found"))))) +(define-key mu4e-view-mode-map "X" #'ed/mu4e-view-save-all-attachments) ** DOING Complete v0.7 Release Checklist [8/11] *** DOING Fit and Finish Period *** TODO Clean Launch from Archsetup diff --git a/modules/mail-config.el b/modules/mail-config.el index 2d9288ac..64437155 100644 --- a/modules/mail-config.el +++ b/modules/mail-config.el @@ -9,6 +9,73 @@ ;;; Code: +;; ----------------------- Mu4e View Save All Attachments ---------------------- +;; replacement for the extract function which saves all attachments + +(defun cj/mu4e-view-save-all-attachments (&optional msg) + "Save all attachments from the current email. +Prompt user for directory, creating if necessary, select all attachments in the +email, and save them in the specified directory. The optional MSG is only +provided when calling this function from mu4e's action context. This function is +intended to be used as a `mu4e-view-action' and/or bound to a key in +mu4e-view-mode-map." + (interactive) + (let ((msg (or msg (mu4e-message-at-point)))) + (let* ((parts (mu4e-view-mime-parts)) + ;; build cons list of candidate mime parts + (candidates (seq-map + (lambda (attachment-part) + (cons ;; (filename . annotation) + (plist-get attachment-part :filename) + attachment-part)) + ;; scope to parts with a filename + (seq-filter + (lambda (part) (plist-get part :attachment-like)) + parts))) + (candidates (or candidates (mu4e-warn "No attachments for this message"))) + (files (mapcar 'car candidates)) ;; Select all attachments + (custom-dir (read-directory-name "Save to directory: "))) + (unless (file-exists-p custom-dir) + (make-directory custom-dir t)) ;; t creates parent dirs if needed + ;; iterate over each file + (seq-do + (lambda (fname) + (let* ((part (cdr (assoc fname candidates))) + ;; build unique full file path + (path (mu4e--uniqify-file-name + (mu4e-join-paths + custom-dir + (plist-get part :filename))))) + ;; save the file + (mm-save-part-to-file (plist-get part :handle) path))) + files)))) + +;; ------------------------- Mark All Headers ------------------------ +;; convenience function to mark all headers for an action + +(defun cj/mu4e-mark-all-headers () + "Mark all headers for a later action. +Prompts user for the action when executing." + (interactive) + (mu4e-headers-mark-for-each-if + (cons 'something nil) + (lambda (_msg _param) t))) + +;;; ------------------ Smtpmail & Easy PG Assistant ----------------- +;; send mail to smtp host from smtpmail temp buffer. +(use-package smtpmail + :ensure nil ;; built-in + :defer .5 + :config + (setq message-kill-buffer-on-exit t) ;; don't keep compose buffers after sending + (setq sendmail-program (executable-find "msmtp")) + (setq send-mail-function 'message-send-mail-with-sendmail + message-send-mail-function 'message-send-mail-with-sendmail) + (setq message-sendmail-envelope-from 'header) + (setq smtpmail-debug-info t)) + +;; --------------------------------- Mu4e Email -------------------------------- + (use-package mu4e :ensure nil ;; mu4e gets installed by installing 'mu' via the system package manager :load-path "/usr/share/emacs/site-lisp/mu4e/" @@ -18,10 +85,11 @@ (:map mu4e-headers-mode-map ("M" . cj/mu4e-mark-all-headers) ("D" . mu4e-headers-mark-for-trash) - ("d" . mu4e-headers-mark-for-delete)) + ("d" . mu4e-headers-mark-for-delete)) (:map mu4e-view-mode-map - ("r" . mu4e-compose-wide-reply) - ("R" . mu4e-compose-reply)) + ("r" . mu4e-compose-wide-reply) + ("R" . mu4e-compose-reply) + ("e" . cj/mu4e-view-save-all-attachments)) :hook (mu4e-view-mode . turn-on-visual-line-mode) :config @@ -52,7 +120,6 @@ (setq mu4e-contexts (list - (make-mu4e-context :name "gmail.com" :match-func @@ -115,6 +182,10 @@ "My settings for message composition." (set-fill-column 72))) + ;; add save-all-attachments to view actions list + (add-to-list 'mu4e-view-actions + '("save all attachments" . cj/mu4e-view-save-all-attachments)) + ;; Always BCC myself ;; http://www.djcbsoftware.nl/code/mu/mu4e/Compose-hooks.html (defun cj/add-header () @@ -133,21 +204,22 @@ ;; use imagemagick to render images, if available (when (fboundp 'imagemagick-register-types) - (imagemagick-register-types))) + (imagemagick-register-types)) + + ;; xwidgets not able to be built into emacs on linux + ;; ;; view in xwidget html rendererer + ;; (add-to-list 'mu4e-headers-actions + ;; '("xWidget" . mu4e-action-view-with-xwidget) t) + ;; (add-to-list 'mu4e-view-actions + ;; '("xWidget" . mu4e-action-view-with-xwidget) t)) -;; xwidgets not able to be built into emacs on linux -;; ;; view in xwidget html rendererer -;; (add-to-list 'mu4e-headers-actions -;; '("xWidget" . mu4e-action-view-with-xwidget) t) -;; (add-to-list 'mu4e-view-actions -;; '("xWidget" . mu4e-action-view-with-xwidget) t)) + ) ;; end use-package mu4e (defun no-auto-fill () "Turn off \'auto-fill-mode\'." (auto-fill-mode -1)) (add-hook 'mu4e-compose-mode-hook #'no-auto-fill) - ;; ----------------------------- Compose Mode Hydra ---------------------------- ;; WIP: menu available in compose mode @@ -163,30 +235,5 @@ (local-set-key (kbd "C-c ?") 'hydra-mu4e-compose/body)) (add-hook 'mu4e-compose-mode-hook 'mu4e-compose-mode-hook-hydra-setup) -;; ------------------------- Mark All Headers ------------------------ -;; convenience function to mark all headers for an action - -(defun cj/mu4e-mark-all-headers () - "Mark all headers for a later action. -Prompts user for the action when executing." - (interactive) - (mu4e-headers-mark-for-each-if - (cons 'something nil) - (lambda (_msg _param) t))) - -;;; ------------------ Smtpmail & Easy PG Assistant ----------------- - -;; send mail to smtp host from smtpmail temp buffer. -(use-package smtpmail - :ensure nil ;; built-in - :defer .5 - :config - (setq message-kill-buffer-on-exit t) ;; don't keep compose buffers after sending - (setq sendmail-program (executable-find "msmtp")) - (setq send-mail-function 'message-send-mail-with-sendmail - message-send-mail-function 'message-send-mail-with-sendmail) - (setq message-sendmail-envelope-from 'header) - (setq smtpmail-debug-info t)) - (provide 'mail-config) ;;; mail-config.el ends here |
