chiark / gitweb /
Handle modified / deleted recurrences
authorMatthew Vernon <mv3@sanger.ac.uk>
Fri, 19 Oct 2018 16:37:33 +0000 (17:37 +0100)
committerMatthew Vernon <mv3@sanger.ac.uk>
Fri, 19 Oct 2018 16:37:33 +0000 (17:37 +0100)
This has a bug in that adding the modified events to the events cache
causes them to get deleted on the next run (since they don't appear in
the events listing normally).

gooswapper.py

index e18da2f470c0d569ee7426aa6f1fc077c8b82746..f54038cc1e2efa526a7ac31ff134738e4c781456 100644 (file)
@@ -74,6 +74,17 @@ def get_ex_event_by_id_and_changekey(acct,itemid,changekey):
     l=list(acct.fetch([(itemid,changekey)]))
     return list(acct.fetch([(itemid,changekey)]))[0]
 
+def get_gcal_recur_instance(gcal_acct,gcal_master,start,gcal_id="primary"):
+    ans = gcal_acct.events().instances(calendarId=gcal_id,
+                                       eventId=gcal_master,
+                                       originalStart=start.isoformat(),
+                                       showDeleted=True).execute()
+    if len(ans['items']) != 1:
+        logger.error("Searching for recurrance instance returned %d events" % \
+                     len(ans['items']))
+        return None
+    return ans['items'][0]
+
 def get_ex_cred(username="SANGER\mv3",password=None):
     if password is None:
         password = getpass.getpass(prompt="Password for user %s: " % username)
@@ -172,6 +183,41 @@ def rrule_from_ex(event,gcal_tz):
         logger.warning("Modified/Deleted recurrences not supported")
     return [rr]
 
+def modify_recurring(ex_acct,gcal_acct,gcal_tz,
+                     events,master,gcal_id="primary"):
+    if master.modified_occurrences is not None:
+        for mod in master.modified_occurrences:
+            instance = get_gcal_recur_instance(gcal_acct,master.gcal_link,
+                                               mod.original_start,gcal_id)
+            if instance is None: #give up after first failure
+                return events
+            mod_event = get_ex_event_by_itemid(ex_acct.calendar,mod.item_id)
+            gevent = build_gcal_event_from_ex(mod_event,gcal_tz)
+            gevent = gcal_acct.events().update(calendarId=gcal_id,
+                                               eventId=instance.get('id'),
+                                               body=gevent,
+                                               sendUpdates="none").execute()
+            mod_event.gcal_link = gevent.get("id")
+            mod_event.save(update_fields=["gcal_link"])
+            if mod_event.item_id in events:
+                events[mod_event.item_id] = events[mod_event.item_id]._replace(changekey=mod_event.changekey,gcal_link=mod_event.gcal_link)
+            else:
+                events[mod_event.item_id] = CachedExEvent(mod_event.changekey,
+                                                      mod_event.gcal_link)
+    if master.deleted_occurrences is not None:
+        for d in master.deleted_occurrences:
+            instance = get_gcal_recur_instance(gcal_acct,master.gcal_link,
+                                               d.start,gcal_id)
+            if instance is None: #give up after any failure
+                return events
+            if instance["status"] != "cancelled":
+                instance["status"]="cancelled"
+                gcal_acct.events().update(calendarId=gcal_id,
+                                          eventId=instance.get('id'),
+                                          body=instance,
+                                          sendUpdates="none").execute()
+    return events
+
 def build_gcal_event_from_ex(event,gcal_tz):
     gevent={}
     gevent["summary"]=event.subject
@@ -210,7 +256,11 @@ def add_ex_to_gcal(ex_acct,
         event.gcal_link = gevent.get("id")
         event.save(update_fields=["gcal_link"])
         events[event.item_id] = events[event.item_id]._replace(changekey=event.changekey,gcal_link=event.gcal_link)
-
+        if event.type=="RecurringMaster" and (event.deleted_occurrences or \
+                                              event.modified_occurrences):
+            events = modify_recurring(ex_acct,gcal_acct,gcal_tz,
+                                      events,event,gcal_id)
+        
 def del_ex_to_gcal(ex_acct, gcal_acct, events, deleted, gcal_id="primary"):
     for ev_id in deleted:
         if events[ev_id].gcal_link is not None: