chiark / gitweb /
only register gcal_link if necessary
[gooswapper] / gooswapper.py
index 1b9b4aa91fbeffb564de1bf6b5705bf1c866bbaf..75edd3febb2c54bcd77979cfadd513b4268f169e 100644 (file)
@@ -54,7 +54,18 @@ class ex_gcal_link(exchangelib.ExtendedProperty):
     property_name = "google calendar event id"
     property_type = 'String'
 
-exchangelib.CalendarItem.register('gcal_link',ex_gcal_link)
+try:
+    exchangelib.CalendarItem.get_field_by_fieldname('gcal_link')
+except ValueError:
+    exchangelib.CalendarItem.register('gcal_link',ex_gcal_link)
+
+#useful if you want to replay an event
+def drop_from_ex_cache(itemid):
+    with open(cachepath,"rb") as f:
+        cache = pickle.load(f)
+    cache.pop(itemid)
+    with open(cachepath,"wb") as f:
+        pickle.dump(cache,f)
 
 def get_ex_event_by_itemid(calendar,itemid):
     return calendar.get(item_id=itemid)
@@ -125,6 +136,30 @@ def ex_event_changes(old,new):
                                                               len(deleted)))
     return added, deleted, changed
 
+def rrule_from_ex(event,gcal_tz):
+    if event.type != "RecurringMaster":
+        logger.error("Cannot make recurrence from not-recurring event")
+        return None
+    if event.recurrence is None:
+        logger.error("Empty recurrence structure")
+        return None
+    if isinstance(event.recurrence.pattern,
+                  exchangelib.recurrence.DailyPattern):
+        rr = "RRULE:FREQ=DAILY;INTERVAL=%d" % event.recurrence.pattern.interval
+    else:
+        logger.error("Recurrence %s not supported" % event.recurrence)
+        return None
+    if isinstance(event.recurrence.boundary,
+                  exchangelib.recurrence.EndDatePattern):
+        rr += ";UNTIL={0:%Y}{0:%m}{0:%d}".format(event.recurrence.boundary.end)
+    else:
+        logger.error("Recurrence %s not supported" % event.recurrence)
+        return None
+    if event.modified_occurrences is not None or \
+       event.deleted_occurrences is not None:
+        logger.warning("Modified/Deleted recurrences not supported")
+    return [rr]
+
 def build_gcal_event_from_ex(event,gcal_tz):
     gevent={}
     gevent["summary"]=event.subject
@@ -149,15 +184,20 @@ def add_ex_to_gcal(ex_acct,
                    gcal_id="primary"):
     for ev_id in added:
         event = get_ex_event_by_itemid(ex_acct.calendar,ev_id)
-        if not event.is_recurring:
-            gevent = build_gcal_event_from_ex(event,gcal_tz)
-            gevent = gcal_acct.events().insert(calendarId=gcal_id,
-                                               body=gevent).execute()
-            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)
-        else:
-            logger.warning("recurring events not yet supported")
+        gevent = build_gcal_event_from_ex(event,gcal_tz)
+        if event.type=="RecurringMaster":
+            rr = rrule_from_ex(event,gcal_tz)
+            if rr is not None:
+                gevent["recurrence"] = rr
+                print(gevent)
+            else:
+                logger.warning("Unable to set recurrence for %s" % event.item_id)
+                continue #don't make the gcal event
+        gevent = gcal_acct.events().insert(calendarId=gcal_id,
+                                           body=gevent).execute()
+        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)
 
 def del_ex_to_gcal(ex_acct, gcal_acct, events, deleted, gcal_id="primary"):
     for ev_id in deleted: