[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[emacs-wiki-discuss] planner appointments exported to icalendar events
From: |
Edgar Gonçalves |
Subject: |
[emacs-wiki-discuss] planner appointments exported to icalendar events |
Date: |
Sun, 26 Mar 2006 21:19:24 +0100 |
User-agent: |
Gnus/5.110004 (No Gnus v0.4) |
Hi,
after managing to keep all my personal information in Emacs (hooray to
planner, muse, gnus, and bbdb!), I came to the conclusion that the outside
world still uses other tools, and they often ask me for some portions of
information. One of such is my schedule. So I promised to give them an
iCalendar .ics file, and dug into Emacs to code some elisp to make it
work. First, I found icalendar.el, and then planner-ical. Both wouldn't work
for me:
1) icalendar.el provides a simple API, directed to diary<->icalendar
migration. It doesn't merge information :(
2) planner-ical.el is a work in progress, I suppose. It only converts tasks
into VTODO, and only from one page at a time.
So I thought about what I needed:
o export all my future appointments into VEVENTs. This includes cyclic events,
and tasks with time informations (both handled with planner-appt).
o import a full icalendar into planner. deal with VEVENT, VTODO, VJOURNAL, and
create, respectively, schedule entries, tasks and notes. add the appointments
retrieved from the VALARMS.
The code I made today fulfills, although not wonderfully, my first
requirement. I'm using it specially to communicate my availability to my
co-workers. So I added a regexp argument to filter each entry by its planner
category! The only thing I can't seem to manage is to get planner-appt to tell
me the category of a task-appointment. So right now I export all of the tasks!
Anyone knows how I can get this behavior?
Here's the code to export to a ics file:
;; iCalendar export of appointments:
(require 'icalendar)
;; TODO: Each VEVENT and VTODO will have a VALARM if it has an associated
;; appointment."
(defun planner-export-ical (category-regexp n ical-output-file)
"Write ICAL-OUTPUT-FILE with iCalendar format. CATEGORY_REGEXP will
limit category marked entries, enabling filtering of the exported
data (up until N days from now).
The iCalendar exported data are all the planner task appointments and
all the cyclic diary entries (in `planner-cyclic-diary-file').
They are exported as VEVENTs."
(interactive)
;; Get the appointments until end-date:
(let ((appts (planner-appt-forthcoming-get-appts n (planner-today))))
;; And now add the cyclic appointments from the appropriate file:
(with-temp-buffer
(let ((cyclic-appts nil))
(with-temp-buffer
(find-file planner-cyclic-diary-file)
(dolist (line (split-string (buffer-string) "[\n\r]"))
(unless (or (string= line "")
(string-match "^!" line))
(push line cyclic-appts)))
(kill-buffer (current-buffer)))
(dolist (appt-desc cyclic-appts)
(let ((appt-category (when (string-match "\\(.*\\)[ \t]*(\\(.*\\))$"
appt-desc)
(match-string 2 appt-desc)))
(appt-text (match-string 1 appt-desc)))
;; Now filter by categories regexp:
(when (string-match category-regexp appt-category)
(when (string-match "\\(.*\\) @\\([0-2]?[0-9]:[0-5]?[0-9]\\)[
\t]*[-|][ \t]*\\([0-2]?[0-9]:[0-5]?[0-9]\\)[ \t]*|?[ \t]*\\(.*\\)$" appt-text)
(let ((day (match-string 1 appt-text))
(start-time (match-string 2 appt-text))
(end-time (match-string 3 appt-text))
(text (match-string 4 appt-text)))
(setq appt-text (format "%s %s-%s %s\n" day start-time
end-time text))
(message "Adding cyclic appt to temp diary:::: %s" appt-text)
(insert appt-text)))))))
(dolist (appt appts)
(let* ((appt-date (first appt))
(appt-desc (second appt))
(appt-category (when (string-match "\\(.*\\)(\\(.*\\))$"
appt-desc)
(match-string 2 appt-desc)))
(appt-text (when (string-match "\\(.*\\)\\((.*)\\)?$" appt-desc)
(match-string 1 appt-desc))))
;; Filter task appointments only:
(when (and appt-text
(string-match "address@hidden(.*\\)[ ]*|?[ ]#[
]*[-|]?\\(.*\\)$" appt-text))
;; Now filter by categories regexp:
(if (or (null appt-category)
(string-match category-regexp appt-category))
;; Extract time and text strings:
(let ((appt-time (match-string 1 appt-text))
(appt-text (match-string 2 appt-text)))
(setq appt-time (replace-in-string appt-time "|" ""))
(setq appt-time (replace-in-string appt-time " [ ]*" " "))
(setq appt-time (replace-in-string appt-time " $" ""))
(setq appt-time (replace-in-string appt-time " " "-"))
(setq appt-date (apply #'format "%s/%s/%s"
(planner-filename-to-calendar-date appt-date)))
(message "Adding task to temp diary:::: %s %s %s" appt-date
appt-time appt-text)
(insert (format "%s %s %s\n" appt-date appt-time appt-text)))
(message "NOT adding task to temp diary:::: %s" appt-desc)))))
(icalendar-export-region (point-min)
(point-max)
ical-output-file))))
;; icalendar fix (this function wouldn't work properly under my Windows + GNU
;; Emacs configuration, so I just removed a silly comparison:
(defalias 'icalendar--rris 'replace-regexp-in-string)
;; Usage example (export ical for the next 31 days):
;; (planner-export-ical "." 31 "~/exported-planner-appts.ics")
--
Edgar Gonçalves
Software Engineering Group @ INESC-ID
IST/Technical University of Lisbon
Rua Alves Redol, 9, Room 635
1000-029 Lisboa, Portugal
mailto:edgar[DOT]goncalves[AT]inesc[DASH]id[DOT]pt
http://www.esw.inesc-id.pt/~eemg
- [emacs-wiki-discuss] planner appointments exported to icalendar events,
Edgar Gonçalves <=