[WIP PATCH] emacs: show: reply to calendar parts
authorMark Walters <markwalters1009@gmail.com>
Fri, 15 Jul 2016 21:31:58 +0000 (22:31 +0100)
committerW. Trevor King <wking@tremily.us>
Sat, 20 Aug 2016 23:22:13 +0000 (16:22 -0700)
d3/0435196d73c24f09753b0d68f7e63d1c441dc0 [new file with mode: 0644]

diff --git a/d3/0435196d73c24f09753b0d68f7e63d1c441dc0 b/d3/0435196d73c24f09753b0d68f7e63d1c441dc0
new file mode 100644 (file)
index 0000000..ada9119
--- /dev/null
@@ -0,0 +1,186 @@
+Return-Path: <markwalters1009@gmail.com>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by arlo.cworth.org (Postfix) with ESMTP id 0E2B86DE0243\r
+ for <notmuch@notmuchmail.org>; Fri, 15 Jul 2016 14:32:26 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at cworth.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.345\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.345 tagged_above=-999 required=5 tests=[AWL=0.225,\r
+  DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1,\r
+ FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7,\r
+ RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_PASS=-0.001]\r
+ autolearn=disabled\r
+Received: from arlo.cworth.org ([127.0.0.1])\r
+ by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id v6KF798Q7n9t for <notmuch@notmuchmail.org>;\r
+ Fri, 15 Jul 2016 14:32:18 -0700 (PDT)\r
+Received: from mail-wm0-f68.google.com (mail-wm0-f68.google.com\r
+ [74.125.82.68]) by arlo.cworth.org (Postfix) with ESMTPS id F1E5B6DE012F for\r
+ <notmuch@notmuchmail.org>; Fri, 15 Jul 2016 14:32:17 -0700 (PDT)\r
+Received: by mail-wm0-f68.google.com with SMTP id i5so3718106wmg.2\r
+ for <notmuch@notmuchmail.org>; Fri, 15 Jul 2016 14:32:17 -0700 (PDT)\r
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113;\r
+ h=from:to:cc:subject:date:message-id;\r
+ bh=caNvDDT2CBgb52KzLly9+pFXV6sY0Cj3Xk+5EL4ug3k=;\r
+ b=ybnOU66Y4jLGeOFXSIFciV/qrYkr7nCV8Xgvbt9g+sm5lqnEs6/h8RUmCSnAm4kN3M\r
+ 5ItzO9jb8a9OfP3Rp74xMnrxGFAXIC2G37Rdm2AnCEh2abXgnk/H8dzctRomKhe3zjhM\r
+ 2k4W542+3LfNro8e5Nk01YRbYqsmFqUZz3tmQQIJc0FIboV22BnB2Qh+Tt3wa1lSr45W\r
+ DJt1gGY4n8s+VjMCaBgVZ8xODJWsYlCllLQD56K+/RTixYu0/8TUi8h8NmVwI8NqpeI2\r
+ TMI+CCwI6bBur2eb/CxxhucZnGvh0lCjdjmSfwoDyswpL8K9Mwuw8PFJzVgpjyG4qn3a\r
+ 2erA==\r
+X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;\r
+ d=1e100.net; s=20130820;\r
+ h=x-gm-message-state:from:to:cc:subject:date:message-id;\r
+ bh=caNvDDT2CBgb52KzLly9+pFXV6sY0Cj3Xk+5EL4ug3k=;\r
+ b=fD31e/EK8gg6Go3z9wPzipiJwYLyShpDELsZrzTS38HzA6QOzLU0p4ET1b/3rtmdoh\r
+ ANl3J6iuGxS8oDtI/OIG26b1UAt4zW2/5nRS4rOs4wP2h9RUWWT7PX++i12wAoVTn5qJ\r
+ Ozqde96NF9Rj9uyhnId510IkSP+5YKQR6eGgxPHYybp+O1Q7WY71v+jUyCZBVB3QLLjo\r
+ QkGeAT5hTe45o7pNvA23ewYPXMTG9Hf0ACgZgB9c3qFiXtmHUC/NcPinMsvlpvg2fcmM\r
+ 7n35uUdHNset8PaH+ycZljKVI1jsbJ++L3QCV0LIXWYV4GoVVIfIVZ2PZMh//RCk/Olm\r
+ 518A==\r
+X-Gm-Message-State:\r
+ ALyK8tKNFgQbGS17DeNmFcZHaF5Flvm4P9cHjVaC67NdWzkojR70Cd6oAURW+ALI/kaXJw==\r
+X-Received: by 10.194.63.103 with SMTP id f7mr2489501wjs.56.1468618332790;\r
+ Fri, 15 Jul 2016 14:32:12 -0700 (PDT)\r
+Received: from localhost (5751dfa2.skybroadband.com. [87.81.223.162])\r
+ by smtp.gmail.com with ESMTPSA id d62sm7825457wmd.7.2016.07.15.14.32.07\r
+ (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\r
+ Fri, 15 Jul 2016 14:32:07 -0700 (PDT)\r
+From: Mark Walters <markwalters1009@gmail.com>\r
+To: notmuch@notmuchmail.org\r
+Subject: [WIP PATCH] emacs: show: reply to calendar parts\r
+Date: Fri, 15 Jul 2016 22:31:58 +0100\r
+Message-Id: <1468618318-19476-1-git-send-email-markwalters1009@gmail.com>\r
+X-Mailer: git-send-email 2.1.4\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.20\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <https://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch/>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <https://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Fri, 15 Jul 2016 21:32:26 -0000\r
+\r
+This allows the user to reply to calendar parts. To reply go to the\r
+text/calendar part and use ". c", then select accept, decline, or\r
+tentative. Notmuch gives a reply buffer ready to send as the response.\r
+For the moment this must be sent manually (C-c C-c as normal).\r
+---\r
+\r
+This is a first pass at allowing the user to reply to calendar\r
+invites. Emacs (at least emacs 24) has gnus-icalendar which contains\r
+all the things necessary for gnus to reply to calendar parts. This\r
+wraps some of the functions for gnus-icalendar so they work from notmuch.\r
+\r
+This version does not send the reply automatically, so it is possible\r
+to review the reply before sending.\r
+\r
+It appears to work with google calendar and outlook invites, but is\r
+not heavily tested. Please do not use for "important" things!\r
+\r
+If people find it works then I will think about how to polish\r
+it. Feedback of any sort very gratefully received!\r
+\r
+Best wishes\r
+\r
+Mark\r
+\r
+\r
+\r
+ emacs/notmuch-show.el | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++\r
+ 1 file changed, 58 insertions(+)\r
+\r
+diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el\r
+index 6d3149b..1de4ca8 100644\r
+--- a/emacs/notmuch-show.el\r
++++ b/emacs/notmuch-show.el\r
+@@ -30,6 +30,7 @@\r
+ (require 'mailcap)\r
+ (require 'icalendar)\r
+ (require 'goto-addr)\r
++(eval-when-compile (require 'gnus-icalendar))\r
\r
+ (require 'notmuch-lib)\r
+ (require 'notmuch-tag)\r
+@@ -1403,6 +1404,7 @@ reset based on the original query."\r
+     (define-key map "v" 'notmuch-show-view-part)\r
+     (define-key map "o" 'notmuch-show-interactively-view-part)\r
+     (define-key map "|" 'notmuch-show-pipe-part)\r
++    (define-key map "c" 'notmuch-show-calendar-reply-part)\r
+     (define-key map "?" 'notmuch-subkeymap-help)\r
+     map)\r
+   "Submap for part commands")\r
+@@ -2399,6 +2401,62 @@ is destroyed when FN returns."\r
+   (interactive)\r
+   (notmuch-show-apply-to-current-part-handle #'mm-pipe-part))\r
\r
++;; The following are modelled on the corresponding functions in\r
++;; gnus-icalendar.el\r
++(defun notmuch-show-icalendar-send-buffer-by-mail (calendar-reply status)\r
++  (let ((message-signature nil))\r
++    (notmuch-show-reply-sender)\r
++    (message-goto-body)\r
++    (delete-region (point) (point-max))\r
++    (mml-insert-multipart "alternative")\r
++    (mml-insert-empty-tag 'part 'type "text/plain")\r
++    (mml-insert-part "text/calendar; method=REPLY; charset=UTF-8")\r
++    (insert calendar-reply "\n")\r
++\r
++    (let* ((re-subject\r
++          (save-restriction\r
++            (message-narrow-to-headers-or-head)\r
++            (message-fetch-field "subject")))\r
++         (subject (concat (capitalize (symbol-name status))\r
++                          (substring re-subject 2))))\r
++      (message-goto-subject)\r
++      (delete-region (line-beginning-position) (line-end-position))\r
++      (insert "Subject: " subject)\r
++      (message-goto-body))))\r
++\r
++(defun notmuch-show-icalendar-reply (status handle)\r
++  (let* ((reply (gnus-icalendar-with-decoded-handle handle\r
++                  (gnus-icalendar-event-reply-from-buffer\r
++                   (current-buffer) status (notmuch-user-emails)))))\r
++    (when reply\r
++      (with-temp-buffer\r
++      (insert reply)\r
++      (goto-char (point-min))\r
++      (while (re-search-forward "^\\(.\\{72\\}\\)\\(.+\\)$" nil t)\r
++        (replace-match "\\1\n \\2")\r
++        (goto-char (line-beginning-position)))\r
++      (buffer-substring-no-properties (point-min) (point-max))))))\r
++\r
++(defun notmuch-show-calendar-reply-part ()\r
++  "Reply to calendar invite."\r
++  (interactive)\r
++  (let* ((part (notmuch-show-get-part-properties))\r
++       (computed-type (plist-get part :computed-type)))\r
++    (unless (notmuch-match-content-type computed-type "text/calendar")\r
++      (error "Not a calendar part!"))\r
++    (require 'gnus-icalendar)\r
++    (let* ((str-status (completing-read "Accept, decline or tentative? "\r
++                                      (list "accept" "decline" "tentative") nil 't))\r
++         (status (pcase str-status\r
++                   ("accept" 'accepted)\r
++                   ("decline" 'declined)\r
++                   ("tentative" 'tentative))))\r
++      (when status\r
++      (let ((calendar-part\r
++             (notmuch-show-apply-to-current-part-handle\r
++              (apply-partially #'notmuch-show-icalendar-reply status))))\r
++        ;; Back in show buffer\r
++        (notmuch-show-icalendar-send-buffer-by-mail calendar-part status))))))\r
\r
+ (provide 'notmuch-show)\r
\r
+-- \r
+2.1.4\r
+\r