From: Matthew Vernon Date: Fri, 19 Oct 2018 16:37:33 +0000 (+0100) Subject: Handle modified / deleted recurrences X-Git-Tag: v0.1~14 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~matthewv/git?a=commitdiff_plain;h=250d83e08b277f4126201a13b05ce6424b18684d;p=gooswapper Handle modified / deleted recurrences 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). --- diff --git a/gooswapper.py b/gooswapper.py index e18da2f..f54038c 100644 --- a/gooswapper.py +++ b/gooswapper.py @@ -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: