chiark / gitweb /
Add LICENSE (AGPLv3)
[gooswapper] / gooswapper.py
index 406b6f8ce57105a0abcfacb75c70398fac24f235..1742b558624120b2972a6b1285b4e34d4edae899 100644 (file)
@@ -6,6 +6,7 @@ import os
 import pickle
 import collections
 import argparse
+import time
 import logging
 logger = logging.getLogger('gooswapper')
 logger.setLevel(logging.INFO)
@@ -79,6 +80,9 @@ def get_gcal_event_by_eventid(gcal_acct,eventId,gcal_id="primary"):
     return gcal_acct.events().get(calendarId=gcal_id,eventId=eventId).execute()
 
 def get_gcal_recur_instance(gcal_acct,gcal_master,start,gcal_id="primary"):
+    if gcal_master is None:
+        logger.warning("Cannot get recurrences from event with null gcal id")
+        return None
     ans = gcal_acct.events().instances(calendarId=gcal_id,
                                        eventId=gcal_master,
                                        originalStart=start.isoformat(),
@@ -307,6 +311,9 @@ def update_ex_to_gcal(ex_acct,
                       gcal_id="primary"):
     for ev_id in changed:
         event = get_ex_event_by_itemid(ex_acct.calendar,ev_id)
+        if event.gcal_link is None:
+            logger.warning("Cannot apply update where event has no gcal link")
+            continue
         gevent = build_gcal_event_from_ex(event,gcal_tz)
         if event.type=="RecurringMaster":
             rr = rrule_from_ex(event,gcal_tz)
@@ -321,10 +328,14 @@ def update_ex_to_gcal(ex_acct,
             else:
                 logger.warning("Unable to set recurrence for %s" % event.item_id)
                 continue #don't make the gcal event
-        gevent = gcal_acct.events().update(calendarId=gcal_id,
+        try: #may fail if we don't own the event
+            gevent = gcal_acct.events().update(calendarId=gcal_id,
                                                eventId=event.gcal_link,
                                                body=gevent,
                                                sendUpdates="none").execute()
+        except googleapiclient.errors.HttpError as err:
+            if err.resp.status == 403:
+                pass
 
 def match_ex_to_gcal(ex_acct,gcal_acct,gcal_tz,events,gcal_id="primary",ignore_link=True):
     recur = 0
@@ -408,34 +419,46 @@ def main():
         gcal_id = "primary"
     else:
         gcal_id = args.gcalid
-    try:
-        with open(cachepath,"rb") as f:
-            cache = pickle.load(f)
-    except FileNotFoundError:
-        cache = None
 
+    #log in to the accounts
     ex_account = ex_login(args.exchuser,args.exchemail,
                           ".gooswapper_exch_conf.dat")
-    current = get_ex_events(ex_account.calendar)
-
     gcal_account = gcal_login(args)
     gcal_tz = get_gcal_timezone(gcal_account,gcal_id)
-    
-    if cache is not None:
-        added,deleted,changed = ex_event_changes(cache,current)
-        add_ex_to_gcal(ex_account,gcal_account,gcal_tz,current,added,gcal_id)
-        #delete op needs the "cache" set, as that has the link ids in
-        #for events that are now deleted
-        del_ex_to_gcal(ex_account,gcal_account,cache,deleted,gcal_id)
-        update_ex_to_gcal(ex_account,gcal_account,gcal_tz,current,
-                          changed,gcal_id)
-    else:
-        toadd = match_ex_to_gcal(ex_account,gcal_account,gcal_tz,current,
-                                 gcal_id)
-        add_ex_to_gcal(ex_account,gcal_account,gcal_tz,current,toadd,gcal_id)
+
+    #Main loop (broken at the end if login is false)
+    while True:
+        try:
+            with open(cachepath,"rb") as f:
+                cache = pickle.load(f)
+        except FileNotFoundError:
+            cache = None
+
+        current = get_ex_events(ex_account.calendar)
+
+        if cache is not None:
+            added,deleted,changed = ex_event_changes(cache,current)
+            add_ex_to_gcal(ex_account,gcal_account,gcal_tz,current,
+                           added,gcal_id)
+            #delete op needs the "cache" set, as that has the link ids in
+            #for events that are now deleted
+            del_ex_to_gcal(ex_account,gcal_account,cache,deleted,gcal_id)
+            update_ex_to_gcal(ex_account,gcal_account,gcal_tz,current,
+                              changed,gcal_id)
+        else:
+            toadd = match_ex_to_gcal(ex_account,gcal_account,gcal_tz,current,
+                                     gcal_id)
+            add_ex_to_gcal(ex_account,gcal_account,gcal_tz,current,
+                           toadd,gcal_id)
         
-    with open(cachepath,"wb") as f:
-        pickle.dump(current,f)
+        with open(cachepath,"wb") as f:
+            pickle.dump(current,f)
+
+        #If not looping, break here (after 1 run)
+        if args.loop==False:
+            break
+        #otherwise, wait 10 minutes, then go round again
+        time.sleep(600)
 
 if __name__ == "__main__":
     main()