diff options
author | Carsten Dominik <carsten.dominik@gmail.com> | 2009-06-06 07:59:19 +0200 |
---|---|---|
committer | Carsten Dominik <carsten.dominik@gmail.com> | 2009-06-06 07:59:19 +0200 |
commit | a2f787a64329d0f71deefeb930bc96b8b2806518 (patch) | |
tree | f8d5978de992370d0f791f8440093740ce0a3a85 | |
parent | c503e2ce5ad44cbbbddb99fd28beeaef620743e6 (diff) | |
download | org-mode-a2f787a64329d0f71deefeb930bc96b8b2806518.tar.gz |
New contributed modules org-mac-iCal.el by Christopher Suckling
-rw-r--r-- | contrib/README | 2 | ||||
-rw-r--r-- | contrib/lisp/org-jira.el | 2 | ||||
-rw-r--r-- | contrib/lisp/org-mac-iCal.el | 246 | ||||
-rw-r--r-- | lisp/org.el | 2 |
4 files changed, 251 insertions, 1 deletions
diff --git a/contrib/README b/contrib/README index 8ab8f07..a9fca06 100644 --- a/contrib/README +++ b/contrib/README @@ -26,7 +26,9 @@ org-exp-bibtex.el --- Export citations to LaTeX and HTML org-exp-blocks.el --- Pre-process blocks when exporting org files org-indent.el --- Dynamic outline indentation (does not really work) org-interactive-query.el --- Interactive modification of tags query +org-jira.el --- Add a jira:ticket protocol to Org org-mairix.el --- Hook mairix search into Org for different MUAs +org-mac-iCal.el --- Imports events from iCal.app to the Emacs diary org-man.el --- Support for links to manpages in Org-mode org-mtags.el --- Support for some Muse-like tags in Org-mode org-panel.el --- Simple routines for us with bad memory diff --git a/contrib/lisp/org-jira.el b/contrib/lisp/org-jira.el index 0803199..d224c8f 100644 --- a/contrib/lisp/org-jira.el +++ b/contrib/lisp/org-jira.el @@ -1,4 +1,4 @@ -;;; org-jira.el --- add a jira:ticket protocol to org. +;;; org-jira.el --- add a jira:ticket protocol to Org (defconst org-jira-version "0.1") ;; Copyright (c)2008 Jonathan Arkell. (by)(nc)(sa) Some rights reserved. ;; Author: Jonathan Arkell <jonnay@jonnay.net> diff --git a/contrib/lisp/org-mac-iCal.el b/contrib/lisp/org-mac-iCal.el new file mode 100644 index 0000000..056d73d --- /dev/null +++ b/contrib/lisp/org-mac-iCal.el @@ -0,0 +1,246 @@ +;;; org-mac-iCal.el --- Imports events from iCal.app to the Emacs diary + +;; Copyright (C) 2009 Christopher Suckling + +;; Author: Christopher Suckling <suckling at gmail dot com> + +;; This file 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 3, or (at your option) +;; any later version. + +;; It 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 GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;; Version: 0.1057.104 +;; Keywords: outlines, calendar + +;;; Commentary: +;; +;; This file provides the import of events from Mac OS X 10.5 iCal.app +;; into the Emacs diary (it is not compatible with OS X < 10.5). The +;; function org-mac-iCal will import events in all checked iCal.app +;; calendars for the date range org-mac-iCal-range months, centered +;; around the current date. +;; +;; CAVEAT: This function is destructive; it will overwrite the current +;; contents of the Emacs diary. +;; +;; Installation: add (require 'org-mac-iCal) to your .emacs. +;; +;; If you view Emacs diary entries in org-agenda, the following hook +;; will ensure that all-day events are not orphaned below TODO items +;; and that any supplementary fields to events (e.g. Location) are +;; grouped with their parent event +;; +;; (add-hook 'org-agenda-cleanup-fancy-diary-hook +;; (lambda () +;; (goto-char (point-min)) +;; (save-excursion +;; (while (re-search-forward "^[a-z]" nil t) +;; (goto-char (match-beginning 0)) +;; (insert "0:00-24:00 "))) +;; (while (re-search-forward "^ [a-z]" nil t) +;; (goto-char (match-beginning 0)) +;; (save-excursion +;; (re-search-backward "^[0-9]+:[0-9]+-[0-9]+:[0-9]+ " nil t)) +;; (insert (match-string 0))))) + +;;; Code: + +(defcustom org-mac-iCal-range 2 + "The range in months to import iCal.app entries into the Emacs +diary. The import is centered around today's date; thus a value +of 2 imports entries for one month before and one month after +today's date" + :group 'org-time + :type 'integer) + +(defun org-mac-iCal () + "Selects checked calendars in iCal.app and imports them into +the the Emacs diary" + (interactive) + + ;; kill diary buffers then empty diary files to avoid duplicates + (setq currentBuffer (buffer-name)) + (setq openBuffers (mapcar (function buffer-name) (buffer-list))) + (omi-kill-diary-buffer openBuffers) + (with-temp-buffer + (insert-file-contents diary-file) + (delete-region (point-min) (point-max)) + (write-region (point-min) (point-max) diary-file)) + + ;; determine available calendars + (setq caldav-folders (directory-files "~/Library/Calendars" 1 ".*caldav$")) + (setq caldav-calendars nil) + (mapc + (lambda (x) + (setq caldav-calendars (nconc caldav-calendars (directory-files x 1 ".*calendar$")))) + caldav-folders) + + (setq local-calendars nil) + (setq local-calendars (directory-files "~/Library/Calendars" 1 ".*calendar$")) + + (setq all-calendars (append caldav-calendars local-calendars)) + + ;; parse each calendar's Info.plist to see if calendar is checked in iCal + (setq all-calendars (delq 'nil (mapcar + (lambda (x) + (omi-checked x)) + all-calendars))) + + ;; for each caledar, concatenate individual events into a single ics file + (with-temp-buffer + (shell-command "sw_vers" " *temp*") + (when (re-search-backward "10.5" nil t) + (omi-concat-leopard-ics all-calendars))) + + ;; move any caldav ics files to the same place as local ics files + (mapc + (lambda (x) + (when (directory-files x 1 ".*ics$") + (rename-file (car (directory-files x 1 ".*ics$")) (concat "~/Library/Calendars/" (car (directory-files x nil ".*ics$")))))) + caldav-folders) + + ;; check calendar has contents and import + (setq import-calendars (directory-files "~/Library/Calendars" 1 ".*ics$")) + (mapc + (lambda (x) + (when (/= (nth 7 (file-attributes x 'string)) 0) + (omi-import-ics x))) + import-calendars) + + ;; tidy up intermediate files and buffers + (setq usedCalendarsBuffers (mapcar (function buffer-name) (buffer-list))) + (omi-kill-ics-buffer usedCalendarsBuffers) + (setq usedCalendarsFiles (directory-files "~/Library/Calendars" 1 ".*ics$")) + (omi-delete-ics-file usedCalendarsFiles) + + (switch-to-buffer currentBuffer)) + +(defun omi-concat-leopard-ics (list) + "Leopard stores each iCal.app event in a separate ics file. +Whilst useful for Spotlight indexing, this is less helpful for +icalendar-import-file. omi-concat-leopard-ics concatenates these +individual event files into a single ics file" + (mapc + (lambda (x) + (setq omi-leopard-events (directory-files (concat x "/Events") 1 ".*ics$")) + (with-temp-buffer + (mapc + (lambda (y) + (insert-file-contents (expand-file-name y))) + omi-leopard-events) + (write-region (point-min) (point-max) (concat (expand-file-name x) ".ics")))) + list)) + +(defun omi-import-ics (string) + "Imports an ics file into the Emacs diary. First tidies up the +ics file so that it is suitable for import and selects a sensible +date range so that Emacs calendar view doesn't grind to a halt" + (with-temp-buffer + (insert-file-contents string) + (goto-char (point-min)) + (while + (re-search-forward "^BEGIN:VCALENDAR$" nil t) + (setq startEntry (match-beginning 0)) + (re-search-forward "^END:VCALENDAR$" nil t) + (setq endEntry (match-end 0)) + (save-restriction + (narrow-to-region startEntry endEntry) + (goto-char (point-min)) + (re-search-forward "\\(^DTSTART;.*:\\)\\([0-9][0-9][0-9][0-9]\\)\\([0-9][0-9]\\)" nil t) + (if (or (eq (match-string 2) nil) (eq (match-string 3) nil)) + (progn + (setq yearEntry 0) + (setq monthEntry 0)) + (setq yearEntry (string-to-number (match-string 2))) + (setq monthEntry (string-to-number (match-string 3)))) + (setq year (string-to-number (format-time-string "%Y"))) + (setq month (string-to-number (format-time-string "%m"))) + (when (or + (and + (= yearEntry year) + (or (< monthEntry (- month (/ org-mac-iCal-range 2))) (> monthEntry (+ month (/ org-mac-iCal-range 2))))) + (< yearEntry (- year 1)) + (> yearEntry (+ year 1)) + (and + (= yearEntry (- year 1)) (/= monthEntry 12)) + (and + (= yearEntry (+ year 1)) (/= monthEntry 1))) + (delete-region startEntry endEntry)))) + (while + (re-search-forward "^END:VEVENT$" nil t) + (delete-blank-lines)) + (goto-line 1) + (insert "BEGIN:VCALENDAR\n\n") + (goto-line 2) + (while + (re-search-forward "^BEGIN:VCALENDAR$" nil t) + (replace-match "\n")) + (goto-line 2) + (while + (re-search-forward "^END:VCALENDAR$" nil t) + (replace-match "\n")) + (insert "END:VCALENDAR") + (goto-line 1) + (delete-blank-lines) + (while + (re-search-forward "^END:VEVENT$" nil t) + (delete-blank-lines)) + (goto-line 1) + (while + (re-search-forward "^ORG.*" nil t) + (replace-match "\n")) + (goto-line 1) + (write-region (point-min) (point-max) string)) + + (icalendar-import-file string (expand-file-name "~/.emacs.d/diary"))) + +(defun omi-kill-diary-buffer (list) + (mapc + (lambda (x) + (if (string-match "^diary" x) + (kill-buffer x))) + list)) + +(defun omi-kill-ics-buffer (list) + (mapc + (lambda (x) + (if (string-match "ics$" x) + (kill-buffer x))) + list)) + +(defun omi-delete-ics-file (list) + (mapc + (lambda (x) + (delete-file x)) + list)) + +(defun omi-checked (directory) + "Parse Info.plist in iCal.app calendar folder and determine +whether Checked key is 1. If Checked key is not 1, remove +calendar from list of calendars for import" + (let* ((root (xml-parse-file (car (directory-files directory 1 "Info.plist")))) + (plist (car root)) + (dict (car (xml-get-children plist 'dict))) + (keys (cdr (xml-node-children dict))) + (keys (mapcar + (lambda (x) + (cond ((listp x) + x))) + keys)) + (keys (delq 'nil keys))) + (when (equal "1" (car (cddr (lax-plist-get keys '(key nil "Checked"))))) + directory))) + +(provide 'org-mac-iCal) + +;;; org-mac-iCal.el ends here diff --git a/lisp/org.el b/lisp/org.el index 594cdc2..1eb5e74 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -193,7 +193,9 @@ to add the symbol `xyz', and the package must have a call to (const :tag "C exp-bibtex: Export citations using BibTeX" org-exp-bibtex) (const :tag "C exp-blocks: Pre-process blocks for export" org-exp-blocks) (const :tag "C interactive-query: Interactive modification of tags query (PARTIALLY OBSOLETE, see secondary filtering)" org-interactive-query) + (const :tag "C jira Add a jira:ticket protocol to Org" org-jira) (const :tag "C mairix: Hook mairix search into Org for different MUAs" org-mairix) + (const :tag "C mac-iCal Imports events from iCal.app to the Emacs diary" org-mac-iCal) (const :tag "C man: Support for links to manpages in Org-mode" org-man) (const :tag "C mtags: Support for muse-like tags" org-mtags) (const :tag "C panel: Simple routines for us with bad memory" org-panel) |