[WIP PATCH] emacs: show: reply to calendar parts

Subject: [WIP PATCH] emacs: show: reply to calendar parts

Date: Fri, 15 Jul 2016 22:31:58 +0100

To: notmuch@notmuchmail.org

Cc:

From: Mark Walters


This allows the user to reply to calendar parts. To reply go to the
text/calendar part and use ". c", then select accept, decline, or
tentative. Notmuch gives a reply buffer ready to send as the response.
For the moment this must be sent manually (C-c C-c as normal).
---

This is a first pass at allowing the user to reply to calendar
invites. Emacs (at least emacs 24) has gnus-icalendar which contains
all the things necessary for gnus to reply to calendar parts. This
wraps some of the functions for gnus-icalendar so they work from notmuch.

This version does not send the reply automatically, so it is possible
to review the reply before sending.

It appears to work with google calendar and outlook invites, but is
not heavily tested. Please do not use for "important" things!

If people find it works then I will think about how to polish
it. Feedback of any sort very gratefully received!

Best wishes

Mark



 emacs/notmuch-show.el | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 6d3149b..1de4ca8 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -30,6 +30,7 @@
 (require 'mailcap)
 (require 'icalendar)
 (require 'goto-addr)
+(eval-when-compile (require 'gnus-icalendar))
 
 (require 'notmuch-lib)
 (require 'notmuch-tag)
@@ -1403,6 +1404,7 @@ reset based on the original query."
     (define-key map "v" 'notmuch-show-view-part)
     (define-key map "o" 'notmuch-show-interactively-view-part)
     (define-key map "|" 'notmuch-show-pipe-part)
+    (define-key map "c" 'notmuch-show-calendar-reply-part)
     (define-key map "?" 'notmuch-subkeymap-help)
     map)
   "Submap for part commands")
@@ -2399,6 +2401,62 @@ is destroyed when FN returns."
   (interactive)
   (notmuch-show-apply-to-current-part-handle #'mm-pipe-part))
 
+;; The following are modelled on the corresponding functions in
+;; gnus-icalendar.el
+(defun notmuch-show-icalendar-send-buffer-by-mail (calendar-reply status)
+  (let ((message-signature nil))
+    (notmuch-show-reply-sender)
+    (message-goto-body)
+    (delete-region (point) (point-max))
+    (mml-insert-multipart "alternative")
+    (mml-insert-empty-tag 'part 'type "text/plain")
+    (mml-insert-part "text/calendar; method=REPLY; charset=UTF-8")
+    (insert calendar-reply "\n")
+
+    (let* ((re-subject
+	    (save-restriction
+	      (message-narrow-to-headers-or-head)
+	      (message-fetch-field "subject")))
+	   (subject (concat (capitalize (symbol-name status))
+			    (substring re-subject 2))))
+      (message-goto-subject)
+      (delete-region (line-beginning-position) (line-end-position))
+      (insert "Subject: " subject)
+      (message-goto-body))))
+
+(defun notmuch-show-icalendar-reply (status handle)
+  (let* ((reply (gnus-icalendar-with-decoded-handle handle
+                  (gnus-icalendar-event-reply-from-buffer
+                   (current-buffer) status (notmuch-user-emails)))))
+    (when reply
+      (with-temp-buffer
+	(insert reply)
+	(goto-char (point-min))
+	(while (re-search-forward "^\\(.\\{72\\}\\)\\(.+\\)$" nil t)
+	  (replace-match "\\1\n \\2")
+	  (goto-char (line-beginning-position)))
+	(buffer-substring-no-properties (point-min) (point-max))))))
+
+(defun notmuch-show-calendar-reply-part ()
+  "Reply to calendar invite."
+  (interactive)
+  (let* ((part (notmuch-show-get-part-properties))
+	 (computed-type (plist-get part :computed-type)))
+    (unless (notmuch-match-content-type computed-type "text/calendar")
+      (error "Not a calendar part!"))
+    (require 'gnus-icalendar)
+    (let* ((str-status (completing-read "Accept, decline or tentative? "
+					(list "accept" "decline" "tentative") nil 't))
+	   (status (pcase str-status
+		     ("accept" 'accepted)
+		     ("decline" 'declined)
+		     ("tentative" 'tentative))))
+      (when status
+	(let ((calendar-part
+	       (notmuch-show-apply-to-current-part-handle
+		(apply-partially #'notmuch-show-icalendar-reply status))))
+	  ;; Back in show buffer
+	  (notmuch-show-icalendar-send-buffer-by-mail calendar-part status))))))
 
 (provide 'notmuch-show)
 
-- 
2.1.4


Thread: