Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by arlo.cworth.org (Postfix) with ESMTP id 0E2B86DE0243 for ; Fri, 15 Jul 2016 14:32:26 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at cworth.org X-Spam-Flag: NO X-Spam-Score: -0.345 X-Spam-Level: X-Spam-Status: No, score=-0.345 tagged_above=-999 required=5 tests=[AWL=0.225, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_PASS=-0.001] autolearn=disabled Received: from arlo.cworth.org ([127.0.0.1]) by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id v6KF798Q7n9t for ; Fri, 15 Jul 2016 14:32:18 -0700 (PDT) Received: from mail-wm0-f68.google.com (mail-wm0-f68.google.com [74.125.82.68]) by arlo.cworth.org (Postfix) with ESMTPS id F1E5B6DE012F for ; Fri, 15 Jul 2016 14:32:17 -0700 (PDT) Received: by mail-wm0-f68.google.com with SMTP id i5so3718106wmg.2 for ; Fri, 15 Jul 2016 14:32:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=caNvDDT2CBgb52KzLly9+pFXV6sY0Cj3Xk+5EL4ug3k=; b=ybnOU66Y4jLGeOFXSIFciV/qrYkr7nCV8Xgvbt9g+sm5lqnEs6/h8RUmCSnAm4kN3M 5ItzO9jb8a9OfP3Rp74xMnrxGFAXIC2G37Rdm2AnCEh2abXgnk/H8dzctRomKhe3zjhM 2k4W542+3LfNro8e5Nk01YRbYqsmFqUZz3tmQQIJc0FIboV22BnB2Qh+Tt3wa1lSr45W DJt1gGY4n8s+VjMCaBgVZ8xODJWsYlCllLQD56K+/RTixYu0/8TUi8h8NmVwI8NqpeI2 TMI+CCwI6bBur2eb/CxxhucZnGvh0lCjdjmSfwoDyswpL8K9Mwuw8PFJzVgpjyG4qn3a 2erA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=caNvDDT2CBgb52KzLly9+pFXV6sY0Cj3Xk+5EL4ug3k=; b=fD31e/EK8gg6Go3z9wPzipiJwYLyShpDELsZrzTS38HzA6QOzLU0p4ET1b/3rtmdoh ANl3J6iuGxS8oDtI/OIG26b1UAt4zW2/5nRS4rOs4wP2h9RUWWT7PX++i12wAoVTn5qJ Ozqde96NF9Rj9uyhnId510IkSP+5YKQR6eGgxPHYybp+O1Q7WY71v+jUyCZBVB3QLLjo QkGeAT5hTe45o7pNvA23ewYPXMTG9Hf0ACgZgB9c3qFiXtmHUC/NcPinMsvlpvg2fcmM 7n35uUdHNset8PaH+ycZljKVI1jsbJ++L3QCV0LIXWYV4GoVVIfIVZ2PZMh//RCk/Olm 518A== X-Gm-Message-State: ALyK8tKNFgQbGS17DeNmFcZHaF5Flvm4P9cHjVaC67NdWzkojR70Cd6oAURW+ALI/kaXJw== X-Received: by 10.194.63.103 with SMTP id f7mr2489501wjs.56.1468618332790; Fri, 15 Jul 2016 14:32:12 -0700 (PDT) Received: from localhost (5751dfa2.skybroadband.com. [87.81.223.162]) by smtp.gmail.com with ESMTPSA id d62sm7825457wmd.7.2016.07.15.14.32.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 15 Jul 2016 14:32:07 -0700 (PDT) From: Mark Walters To: notmuch@notmuchmail.org Subject: [WIP PATCH] emacs: show: reply to calendar parts Date: Fri, 15 Jul 2016 22:31:58 +0100 Message-Id: <1468618318-19476-1-git-send-email-markwalters1009@gmail.com> X-Mailer: git-send-email 2.1.4 X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.20 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: Fri, 15 Jul 2016 21:32:26 -0000 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