;;; org-import-icalender.el --- Copy snippet to kill-ring for text/calendar part ;; Copyright (C) 2010 Vagn Johansen ;; Author: Vagn Johansen ;; Keywords: gnus, org ;; URL: http://ozymandias.dk/emacs/emacs.html ;; This file is NOT part of Emacs. ;; ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License ;; as published by the Free Software Foundation; either version 2 ;; of the License, or (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program; if not, write to the Free Software ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, ;; MA 02110-1301, USA. ;;; Commentary: ;; ;; Installation: ;; ;; (require 'org-import-icalender) ;; ;; Probably requires Emacs 23 ;; ;; NOTE! Sets gnus-article-mime-part-function. Make sure it not set to ;; something you use first. ;;; Code: (require 'icalendar) (defun org-import-icalender-iso (datetime) "Convert a date retrieved via `icalendar--get-event-property' to ISO format." (if datetime (format "%04d-%02d-%02d" (nth 5 datetime) ; Year (nth 4 datetime) ; Month (nth 3 datetime)))) ; Day (defun org-import-icalender-get-org-timestring (ical-element) "" (let* ((dtstart (icalendar--get-event-property e 'DTSTART)) (dtstart-zone (icalendar--find-time-zone (icalendar--get-event-property-attributes e 'DTSTART) zone-map)) (dtstart-dec (icalendar--decode-isodatetime dtstart nil dtstart-zone)) (start-d (org-import-icalender-iso dtstart-dec)) (start-t (icalendar--datetime-to-colontime dtstart-dec)) (dtend (icalendar--get-event-property e 'DTEND)) (dtend-zone (icalendar--find-time-zone (icalendar--get-event-property-attributes e 'DTEND) zone-map)) (dtend-dec (icalendar--decode-isodatetime dtend nil dtend-zone)) end-d end-t (rrule (icalendar--get-event-property e 'RRULE)) (rdate (icalendar--get-event-property e 'RDATE)) (duration (icalendar--get-event-property e 'DURATION))) (setq end-d (if dtend-dec (org-import-icalender-iso dtend-dec) start-d)) (setq end-t (if (and dtend-dec (not (string= (cadr (icalendar--get-event-property-attributes e 'DTEND)) "DATE"))) (icalendar--datetime-to-colontime dtend-dec) start-t)) ;; Store in kill-ring (if (equal start-d end-d) (format "<%s %s-%s>" start-d start-t end-t) ;; else (format "<%s %s>--<%s %s>" start-d start-t end-d end-t)))) (defun org-import-icalender-import-element (ical-element) (let* ((location (icalendar--get-event-property e 'LOCATION)) (organizer (icalendar--get-event-property e 'ORGANIZER)) (summary (icalendar--convert-string-for-import (or (icalendar--get-event-property e 'SUMMARY) "No summary"))) (org-timestr (org-import-icalender-get-org-timestring ical-element)) ;; (msg (format "%s (%s)\n%s\nOrganizer: %s" summary location org-timestr "organizer"))) (message "Added to kill-ring:\n %s" msg) ;; Store in kill-ring (kill-new msg))) (defun org-import-icalender-import-elements (ical-list) (let* ((ev (icalendar--all-events ical-list)) (error-string "") (event-ok t) found-error e) (while ev (setq e (car ev)) (setq ev (cdr ev)) (setq event-ok nil) (condition-case error-val (org-import-icalender-import-element e) (error (message "Ignoring event \"%s\"" e) (setq found-error t) (setq error-string (format "%s\n%s\nCannot handle this event: %s" error-val error-string e)) (message "%s" error-string)))) found-error)) (defun org-icalendar-import-buffer () "Import icalendar to org file fro mcurent buffer." (interactive) (save-current-buffer ;; prepare ical (message "Preparing icalendar...") (set-buffer (icalendar--get-unfolded-buffer (current-buffer))) (goto-char (point-min)) (message "Preparing icalendar...done") (if (re-search-forward "^BEGIN:VCALENDAR\\s-*$" nil t) (let (ical-contents ical-errors) ;; read ical (message "Reading icalendar...") (beginning-of-line) (setq ical-contents (icalendar--read-element nil nil)) (message "Reading icalendar...done") ;; convert ical (message "Converting icalendar...") (setq ical-errors (org-import-icalender-import-elements ical-contents)) ;; return t if no error occurred (not ical-errors)) (message "Current buffer does not contain icalendar contents!")))) (defun org-import-icalender-gnus-part (handle) "Import icalendar event given an mm handle." (interactive) (let ((fn (make-temp-file "gnus-org-" nil ".ics"))) (when (equal (car (mm-handle-type handle)) "text/calendar") ;; Save part to file (mm-save-part-to-file handle fn) (with-temp-buffer ;; Load part again! (insert-file-contents fn) (goto-char (point-min)) (org-icalendar-import-buffer))) ;; Does not work: ;; (with-temp-buffer ;; (insert (mm-get-part handle)) ;; (org-icalendar-import-buffer)) )) (defun org-import-icalender-gnus () "Import ics part stored as second part of alternative. Bind this to a key in gnus summary mode: (define-key gnus-summary-mode-map [?K ?I] 'org-import-icalender-gnus) " (interactive) (save-current-buffer (gnus-summary-show-article) (set-buffer gnus-article-buffer) (let ((handle (nth 3 (assq 1 gnus-article-mime-handle-alist)))) (if (equal (car (mm-handle-type handle)) "text/calendar") (org-import-icalender-gnus handle) (message "Third element not a text/calendar"))))) (eval-after-load "gnus" '(progn (setq gnus-article-mime-part-function 'org-import-icalender-gnus-part) )) (provide 'org-import-icalendar)