Source

gcal2org / gcal2org.py

Diff from to

gcal2org.py

 
 import gdata.calendar.client
 from datetime import date, datetime, timedelta
-from time import strftime, strptime, mktime, localtime
+from time import strftime, strptime, mktime, localtime, sleep
 import sys, re, os, getopt
 
-preamble = """#+STARTUP: overview
+EVENT_URI_PREFIX = 'http://www.google.com/calendar/feeds/default/private/full/'
+
+PREAMBLE = """#+STARTUP: overview
 #+DESCRIPTION: Converted on %s
 * Events
 """
 
-item = """** %s
+ITEM = """** %s
    :PROPERTIES:
    :Id:       %s
    :When:     %s
   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, event_id, when, where, who, description)])
-  org_file.write(item % itemdata)
+  org_file.write(ITEM % itemdata)
 
 def authinfo_pw(login):
   p = re.compile('login %s password ([^ ]+)' % login)
   client.ClientLogin(login, authinfo_pw(login), client.source)
   return client
 
-def create_org_file(login, filename):
+def create_org_file(client, filename):
   org_file = open(filename, 'w')
-  org_file.write(preamble % datetime.now())
-  client = create_calendar_client(login)
+  org_file.write(PREAMBLE % datetime.now())
   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])
+def update_event(client, event_id, fields):
+  uri = EVENT_URI_PREFIX + event_id
+  event = client.GetEventEntry(uri, auth_token=client.auth_token)
+  for k,v in fields.items():
+    if k == 'title.text': event.title.text = v
+  client.Update(event)
+
+class Usage(Exception):
+    def __init__(self, msg):
+        self.msg = msg
+
+def restructure_field_args(fs):
+  if len(fs) % 2 != 0:
+    raise Usage("Please supply key/value pairs, rather than: %s." % fs)
+  fields = {}
+  for i in range(len(fs)):
+    if i % 2 == 0:
+      fields[fs[i]] = fs[i+1]
+  return fields
+
+def print_usage(msg):
+  print >>sys.stderr, msg
+  print >>sys.stderr, 'Please invoke script w/o args for general usage info.'
+
+def main(retry_count=5):
+  try:
+    if 4 > len(sys.argv): raise Usage('Please supply at least 3 args')
+    else:
+      client = create_calendar_client(sys.argv[1])
+      op = sys.argv[2]
+      if op == 'update':
+        event_id = sys.argv[3]
+        fields = restructure_field_args(sys.argv[4:])
+        return update_event(client, event_id, fields)
+      elif op == 'download':
+        filename = sys.argv[3]
+        return create_org_file(client, filename)
+      else: raise Usage('Operation "%s" not supported.' % op)
+
+  except Usage, err:
+     return print_usage(err.msg)
+  except gdata.client.RedirectError, err:
+    if retry_count > 0:
+      print >>sys.stderr, ("gcal2org: Retry #%s" % (5 - retry_count))
+      sleep(1)
+      main(retry_count=(retry_count - 1))
+    else:
+      raise err
 
 if __name__ == '__main__':
   sys.exit(main())