New contributed modules org-mac-iCal.el by Christopher Suckling
This commit is contained in:
parent
c503e2ce5a
commit
a2f787a643
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue