;;; gnus-icalendar.el --- reply to iCalendar meeting requests
-;; Copyright (C) 2013 Free Software Foundation, Inc.
+;; Copyright (C) 2013-2014 Free Software Foundation, Inc.
;; Author: Jan Tatarik <Jan.Tatarik@gmail.com>
;; Keywords: mail, icalendar, org
:accessor gnus-icalendar-event:rsvp
:initform nil
:type (or null boolean))
- (participation-required :initarg :participation-required
- :accessor gnus-icalendar-event:participation-required
- :initform t
- :type (or null boolean))
+ (participation-type :initarg :participation-type
+ :accessor gnus-icalendar-event:participation-type
+ :initform 'non-participant
+ :type (or null t))
(req-participants :initarg :req-participants
:accessor gnus-icalendar-event:req-participants
:initform nil
(attendee (when attendee-name-or-email
(gnus-icalendar-event--find-attendee ical attendee-name-or-email)))
(attendee-names (gnus-icalendar-event--get-attendee-names ical))
+ (role (plist-get (cadr attendee) 'ROLE))
+ (participation-type (pcase role
+ ("REQ-PARTICIPANT" 'required)
+ ("OPT-PARTICIPANT" 'optional)
+ (_ 'non-participant)))
(args (list :method method
:organizer organizer
:start-time (gnus-icalendar-event--decode-datefield event 'DTSTART)
:end-time (gnus-icalendar-event--decode-datefield event 'DTEND)
- :rsvp (string= (plist-get (cadr attendee) 'RSVP)
- "TRUE")
- :participation-required (string= (plist-get (cadr attendee) 'ROLE)
- "REQ-PARTICIPANT")
- :req-participants (cdar attendee-names)
+ :rsvp (string= (plist-get (cadr attendee) 'RSVP) "TRUE")
+ :participation-type participation-type
+ :req-participants (car attendee-names)
:opt-participants (cadr attendee-names)))
(event-class (cond
((string= method "REQUEST") 'gnus-icalendar-event-request)
(defgroup gnus-icalendar-org nil
"Settings for Calendar Event gnus/org integration."
+ :version "24.4"
:group 'gnus-icalendar
:prefix "gnus-icalendar-org-")
("DT" . ,(gnus-icalendar-event:org-timestamp event))
("ORGANIZER" . ,(gnus-icalendar-event:organizer event))
("LOCATION" . ,(gnus-icalendar-event:location event))
- ("PARTICIPATION_REQUIRED" . ,(when (gnus-icalendar-event:participation-required event) "t"))
+ ("PARTICIPATION_TYPE" . ,(symbol-name (gnus-icalendar-event:participation-type event)))
("REQ_PARTICIPANTS" . ,(gnus-icalendar--format-participant-list (gnus-icalendar-event:req-participants event)))
("OPT_PARTICIPANTS" . ,(gnus-icalendar--format-participant-list (gnus-icalendar-event:opt-participants event)))
("RRULE" . ,(gnus-icalendar-event:recur event))
(when file
(with-current-buffer (find-file-noselect file)
(with-slots (uid summary description organizer location recur
- participation-required req-participants opt-participants) event
+ participation-type req-participants opt-participants) event
(let ((event-pos (org-find-entry-with-id uid)))
(when event-pos
(goto-char event-pos)
(org-entry-put event-pos "DT" (gnus-icalendar-event:org-timestamp event))
(org-entry-put event-pos "ORGANIZER" organizer)
(org-entry-put event-pos "LOCATION" location)
- (org-entry-put event-pos "PARTICIPATION_REQUIRED" (when participation-required "t"))
+ (org-entry-put event-pos "PARTICIPATION_TYPE" (symbol-name participation-type))
(org-entry-put event-pos "REQ_PARTICIPANTS" (gnus-icalendar--format-participant-list req-participants))
(org-entry-put event-pos "OPT_PARTICIPANTS" (gnus-icalendar--format-participant-list opt-participants))
(org-entry-put event-pos "RRULE" recur)
(defgroup gnus-icalendar nil
"Settings for inline display of iCalendar invitations."
+ :version "24.4"
:group 'gnus-article
:prefix "gnus-icalendar-")
:type '(string)
:group 'gnus-icalendar)
+(defcustom gnus-icalendar-additional-identities nil
+ "We need to know your identity to make replies to calendar requests work.
+
+Gnus will only offer you the Accept/Tentative/Decline buttons for
+calendar events if any of your identities matches at least one
+RSVP participant.
+
+Your identity is guessed automatically from the variables `user-full-name',
+`user-mail-address', and `gnus-ignored-from-addresses'.
+
+If you need even more aliases you can define them here. It really
+only makes sense to define names or email addresses."
+
+ :type '(repeat string)
+ :group 'gnus-icalendar)
+
(make-variable-buffer-local
(defvar gnus-icalendar-reply-status nil))
(make-variable-buffer-local
(defvar gnus-icalendar-handle nil))
-(defvar gnus-icalendar-identities
+(defun gnus-icalendar-identities ()
+ "Return list of regexp-quoted names and email addresses belonging to the user.
+
+These will be used to retrieve the RSVP information from ical events."
(apply #'append
(mapcar (lambda (x) (if (listp x) x (list x)))
(list user-full-name (regexp-quote user-mail-address)
- ; NOTE: this one can be a list
- gnus-ignored-from-addresses))))
+ ; NOTE: these can be lists
+ gnus-ignored-from-addresses ; already regexp-quoted
+ (mapcar #'regexp-quote gnus-icalendar-additional-identities)))))
;; TODO: make the template customizable
(defmethod gnus-icalendar-event->gnus-calendar ((event gnus-icalendar-event) &optional reply-status)
(cadr x))))
(with-slots (organizer summary description location recur uid
- method rsvp participation-required) event
+ method rsvp participation-type) event
(let ((headers `(("Summary" ,summary)
("Location" ,(or location ""))
("Time" ,(gnus-icalendar-event:org-timestamp event))
("Organizer" ,organizer)
- ("Attendance" ,(if participation-required "Required" "Optional"))
+ ("Attendance" ,(if (eq participation-type 'non-participant)
+ "You are not listed as an attendee"
+ (capitalize (symbol-name participation-type))))
("Method" ,method))))
(when (and (not (gnus-icalendar-event-reply-p event)) rsvp)
(event (caddr data))
(reply (gnus-icalendar-with-decoded-handle handle
(gnus-icalendar-event-reply-from-buffer
- (current-buffer) status gnus-icalendar-identities))))
+ (current-buffer) status (gnus-icalendar-identities)))))
(when reply
(gmm-labels ((fold-icalendar-buffer ()
(defun gnus-icalendar-mm-inline (handle)
- (let ((event (gnus-icalendar-event-from-handle handle gnus-icalendar-identities)))
+ (let ((event (gnus-icalendar-event-from-handle handle (gnus-icalendar-identities))))
(setq gnus-icalendar-reply-status nil)
(defun gnus-icalendar-save-part (handle)
(let (event)
(when (and (equal (car (mm-handle-type handle)) "text/calendar")
- (setq event (gnus-icalendar-event-from-handle handle gnus-icalendar-identities)))
+ (setq event (gnus-icalendar-event-from-handle handle (gnus-icalendar-identities))))
(gnus-icalendar-event:sync-to-org event))))