Felix Geller avatar Felix Geller committed 99741ab

Initial commit. Known issue: Broken end date for all-day events that span more than a single day.

Comments (0)

Files changed (1)

+#!/usr/bin/env python
+# Copyright (C) 2011 by Felix Geller
+# 
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation files
+# (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+# 
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+# 
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import gdata.calendar.client
+from datetime import date, datetime, timedelta
+import time, sys, re, os, getopt
+
+preamble = """#+STARTUP: overview
+#+DESCRIPTION: Converted on %s
+* Events
+"""
+
+item = """** %s
+   :PROPERTIES:
+   :When:     %s
+   :Where:    %s
+   :Who:      %s
+   :END:
+ - Description:
+%s
+"""
+
+def date_range_query(cal_client, 
+                     max_results = 333, 
+                     start_date = str(date.today() - timedelta(30)), 
+                     end_date = str(date.today() + timedelta(30))):
+  query = gdata.calendar.client.CalendarEventQuery()
+  query.start_min = start_date
+  query.start_max = end_date
+  query.max_results = max_results
+  feed = cal_client.GetCalendarEventFeed(q=query)
+  return feed.entry
+
+def timestamp(date):
+  if 'T' in date:
+    t = time.strptime(date[:16], '%Y-%m-%dT%H:%M')
+    return time.strftime('<%Y-%m-%d %a %H:%M>', t)
+  else:
+    t = time.strptime(date, '%Y-%m-%d')
+    return time.strftime('<%Y-%m-%d %a>', t)
+
+def singleday(start_time, end_time):
+  if 'T' in start_time:
+    return False
+  else:
+    st = time.mktime(time.strptime(start_time, '%Y-%m-%d'))
+    et = time.mktime(time.strptime(end_time, '%Y-%m-%d'))
+    if et - st <= 86400.0:
+      return True
+    else:
+      return False
+
+def write_item(event, org_file):
+  s = event.when[0].start
+  e = event.when[0].end
+  title = event.title.text
+  when = timestamp(s) if singleday(s, e) else '%s--%s' % tuple([timestamp(d) for d in (s, e)])
+  where = event.where[0].text or 'N/A'
+  who = ', '.join([x.value for x in event.who])
+  description = event.content.text or 'N/A'
+  itemdata =  tuple([s.encode('UTF-8') for s in (title, when, where, who, description)])
+  org_file.write(item % itemdata)
+
+def authinfo_pw(login):
+  p = re.compile('login %s password ([^ ]+)' % login)
+  authinfo = os.popen('gpg -q --no-tty -d ~/.gcal.gpg').read()
+  return p.search(authinfo).group(1)
+
+def create_calendar_client(login):
+  client = gdata.calendar.client.CalendarClient(source='acme-gcal2org-v1')
+  client.ssl = True
+  client.ClientLogin(login, authinfo_pw(login), client.source)
+  return client
+
+def create_org_file(login, filename):
+  org_file = open(filename, 'w')
+  org_file.write(preamble % datetime.now())
+  client = create_calendar_client(login)
+  for event in date_range_query(client):
+    write_item(event, org_file)
+  org_file.close()
+
+def main():
+  if 3 > len(sys.argv):
+    print >>sys.stderr, 'Please provide login and filename for output as arguments'
+    return 2
+  else:
+    return create_org_file(sys.argv[1], sys.argv[2])
+
+if __name__ == '__main__':
+  sys.exit(main())
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.