Add link to Org Babel section from Worg main page
[Worg.git] / org-tutorials / org-google-sync.org
blob76f6bc66dce1385d64c1be144151c990133524cf
1 #+TITLE:   Google Calendar Synchronization
2 #+AUTHOR:    Arun Persaud
3 #+EMAIL:     arun@nubati.net
4 #+DATE:      <2011-02-28 Mon>
5 #+DESCRIPTION: 
6 #+KEYWORDS: 
7 #+LANGUAGE:  en
8 #+OPTIONS:   H:3 num:t toc:t \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t
9 #+OPTIONS:   TeX:t LaTeX:nil skip:nil d:nil todo:t pri:nil tags:not-in-toc
10 #+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js
11 #+EXPORT_SELECT_TAGS: export
12 #+EXPORT_EXCLUDE_TAGS: noexport
13 #+LINK_UP:   
14 #+LINK_HOME: 
16 * Overview
17   To get a real synchronization between org-mode and Google Calendar
18   you need to sync two ways. We cover one way of handling the
19   synchronization in the next two sections and also mention some other
20   ways of synchronization at the end.
21 * From Google Calendar into org using .ics files
22   Google Calendar offers access to each calendar via a hidden/secret
23   url. That is, a url that only you know about and is very hard to
24   guess for other people. You can use this to download your calendar
25   in an iCalendar (.ics) format, which we then can rewrite into
26   something usable for org-mode. For this conversion there luckily
27   already exists a script written by Eric S. Fraga[fn:1]. This is the latest version:
29 #+INCLUDE: "../code/awk/ical2org.awk" src sh
31 With this you can test your Google Calendar to org-mode
32 synchronization by following these steps:
34 1. Download the above script and save it as 'ical2org'.
35    Make sure that the script is in your PATH and don't forget to set
36    the executable flag (chmod u+x ical2org). You can also customize the 
37    script a bit by changing the variables in the config section of the script.
38 2. Find your private URL for your calendar
39   + Log into Google Calendar
40   + Goto Settings
41   + Click on the calendar you want to export to org-mode
42   + At the bottom of the page find the 'private address' section and your ical link 
43     Use the 'reset private urls' if you need to, that is if you don't
44     see a unique url.
45 3. Download the url
46    This can be done for example using 'wget <url>'
47 4. Transform into org-file
48    Use the downloaded script via 'ical2org < icsfile > orgfile'. Where
49    icsfile is the path to the file you downloaded from Google and
50    orgfile is the org-mode file you want to create.
51 5. Add the orgfile to your agenda and test
53 If this all works you can automate the task via cron. Create a script
54 such as the following that will automatically download and convert
55 your calendar. Make sure that this file is only readable by you (chmod
56 700 <file>), since it will contain the url to your Google calendar.
58 #+begin_src sh
59 #!/bin/bash
61 # customize these
62 WGET=<path to wget>
63 ICS2ORG=<path to ical2org>
64 ICSFILE=<path for icsfile>
65 ORGFILE=<path to orgfile>
66 URL=<url to your private Google calendar>
68 # no customization needed below
70 $WGET -O $ICSFILE $URL
71 $ICS2ORG < $ICSFILE > $ORGFILE
72 #+end_src
74 automate this via cron by adding something like the following to your
75 crontab:
77 #+begin_example
78 5,20,35,50 * * * * <path to above script> &> /dev/null #sync my org files
79 #+end_example
81 This will sync every 15 minutes starting at 5 minutes past the hour.
83 * From org to Google Calendar
85   There are at least two possible paths to get the information into Google:
87   1. export from org mode to .ics; upload .ics to a public web server
88      giving it a hidden/secret name; tell Google to import this .ics
89      file
90   2. use googlecl to import event when you create them into Google
91      calendar (update entries won't be reflected in Google). See [fn:2]
93   The first one has the disadvantage that the item won't show up in
94   your "main" calendar and therefore you can't easily share them with
95   others. Nevertheless, this route is relatively easy and therefore
96   we'll discuss it below.  The second option (as described in the link)
97   should work well, if you don't need to change things. 
99   Also keep in mind that your mileage will vary, since everything
100   described on this page works for some people, but perhaps not for
101   you... if this is the case, feel free to ask on the org-email list
102   and perhaps we can add missing features.
104   Back to the topic. To implement 1., we need org to export an .ics
105   file, which can be achieved using the function:
106   org-export-icalendar-combine-agenda-files.
107   This will export all entries in you agenda. If you only want to
108   export certain ones, you can set up a filter. For this we will
109   define a filter function and then tell Emacs to use this filter.
110   The filter shown here, will exclude items with a category "google"
111   (for example from the ical2org script) and "private" and also only
112   export entries that have a date and a time range set (that is, a
113   start and a end time stamp). You can modify the function though to
114   do anything you want!
116 #+begin_src emacs-lisp
118   ;;; define categories that should be excluded
119   (setq org-export-exclude-category (list "google" "private"))
121   ;;; define filter. The filter is called on each entry in the agenda.
122   ;;; It defines a regexp to search for two timestamps, gets the start
123   ;;; and end point of the entry and does a regexp search. It also
124   ;;; checks if the category of the entry is in an exclude list and
125   ;;; returns either t or nil to skip or include the entry.
127   (defun org-mycal-export-limit ()
128     "Limit the export to items that have a date, time and a range. Also exclude certain categories."
129     (setq org-tst-regexp "<\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} ... [0-9]\\{2\\}:[0-9]\\{2\\}[^\r\n>]*?\
130   \)>")
131     (setq org-tstr-regexp (concat org-tst-regexp "--?-?" org-tst-regexp))
132     (save-excursion
133       ; get categories
134       (setq mycategory (org-get-category))
135       ; get start and end of tree
136       (org-back-to-heading t)
137       (setq mystart    (point))
138       (org-end-of-subtree)
139       (setq myend      (point))
140       (goto-char mystart)
141       ; search for timerange
142       (setq myresult (re-search-forward org-tstr-regexp myend t))
143       ; search for categories to exclude
144       (setq mycatp (member mycategory org-export-exclude-category))
145       ; return t if ok, nil when not ok
146       (if (and myresult (not mycatp)) t nil)))
147   
148   ;;; activate filter and call export function
149   (defun org-mycal-export () 
150     (let ((org-icalendar-verify-function 'org-mycal-export-limit))
151       (org-export-icalendar-combine-agenda-files)))
152 #+end_src
154   To use these function you can include the above code in your .emacs
155   file and then in case you run Emacs server call
157 #+begin_src sh
158   emacsclient -e "(save-excursion (org-mycal-export))"
159 #+end_src 
161   in your shell to generate the .ics file.
162   
163   If you want to export also TODO items that have a SCHEDULED timestamp, you can set
165 #+begin_src sh
166   (setq org-icalendar-use-scheduled '(todo-start event-if-todo))
167 #+end_src
168   
169   in your .emacs.
171   Another Emacs variable that you might want to look into is:
172   org-icalendar-honor-noexport-tag.
174   You can now automate this via a cron job to generate updated .ics
175   files.
177   The next step is to give the file a cryptic name (so that other
178   people have a hard time accessing your file, also make sure that
179   your web server doesn't show an index for your directory, etc.) and
180   copy it to a public accessible web server. Then log into your Google
181   calendar and in the left column under "Other calendars" use
182   "Add"->"Add by url" to point Google at your freshly generated .ics
183   file and you should be all set up. Once you done this Google will
184   every now and then (every few hours?) look for a newer version of your .ics file and
185   include this in your calendar.
187 * Footnotes
188 [fn:1] http://article.gmane.org/gmane.emacs.orgmode/26848
189 [fn:2] http://article.gmane.org/gmane.emacs.orgmode/27214