#!/usr/bin/env python3
+# Copyright (C) 2018 Genome Research Limited
+#
+# Author: Matthew Vernon <mv3@sanger.ac.uk>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
import sys
import getpass
import os
+import os.path
import pickle
import collections
import argparse
gcal_client_secret,
scope)
+gsdir = os.path.expanduser("~/.gooswapper")
+gcal_authpath = gsdir + "/.gooswap_gcal_creds.dat"
-gcal_authpath=".gooswap_gcal_creds.dat"
-
-cachepath=".gooswapcache"
+cachepath=None
exchange_credential = None
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"):
+def get_gcal_recur_instance(gcal_acct,gcal_master,start,is_all_day,stz,
+ gcal_id="primary"):
if gcal_master is None:
logger.warning("Cannot get recurrences from event with null gcal id")
return None
+ if is_all_day:
+ os = str(start.astimezone(stz).date())
+ else:
+ os = start.astimezone(stz).isoformat()
ans = gcal_acct.events().instances(calendarId=gcal_id,
eventId=gcal_master,
- originalStart=start.isoformat(),
+ originalStart=os,
showDeleted=True).execute()
if len(ans['items']) != 1:
logger.error("Searching for recurrance instance returned %d events" % \
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)
+ mod.original_start,
+ master.is_all_day,
+ master._start_timezone,
+ gcal_id)
if instance is None: #give up after first failure
return
mod_event = get_ex_event_by_itemid(ex_acct.calendar,mod.item_id)
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)
+ d.start,
+ master.is_all_day,
+ master._start_timezone,
+ gcal_id)
if instance is None: #give up after any failure
return
if instance["status"] != "cancelled":
def build_gcal_event_from_ex(event,gcal_tz):
gevent={}
gevent["summary"]=event.subject
+ #Use the event's timezones if possible, otherwise fall back to the
+ #target calendar timezone
+ if event._start_timezone is not None:
+ stz = event._start_timezone
+ else:
+ stz = gcal_tz
+ if event._end_timezone is not None:
+ etz = event._end_timezone
+ else:
+ etz = gcal_tz
if event.is_all_day:
- gevent["end"]={"date": str(event.end.astimezone(gcal_tz).date())}
- gevent["start"]={"date": str(event.start.astimezone(gcal_tz).date())}
+ gevent["end"]={"date": str(event.end.astimezone(etz).date())}
+ gevent["start"]={"date": str(event.start.astimezone(stz).date())}
else:
- gevent["end"]={"dateTime": event.end.astimezone(gcal_tz).isoformat(),
- "timeZone": str(gcal_tz)}
- gevent["start"]={"dateTime": event.start.astimezone(gcal_tz).isoformat(),
- "timeZone": str(gcal_tz)}
+ gevent["end"]={"dateTime": event.end.astimezone(etz).isoformat(),
+ "timeZone": str(etz)}
+ gevent["start"]={"dateTime": event.start.astimezone(stz).isoformat(),
+ "timeZone": str(stz)}
if event.text_body is not None and event.text_body.strip() != '':
gevent["description"] = event.text_body
if event.location is not None:
else:
gcal_id = args.gcalid
+ #Make our config dir if it doesn't exist
+ if not os.path.exists(gsdir):
+ os.mkdir(gsdir,0o700)
+ #Cache file is specific to the Exchange calendar
+ global cachepath
+ cachepath = gsdir + "/.cache-%s" % \
+ (args.exchemail.replace('@','_').replace('/','_'))
+
#log in to the accounts
ex_account = ex_login(args.exchuser,args.exchemail,
- ".gooswapper_exch_conf.dat")
+ gsdir+"/.gooswapper_exch_conf.dat")
gcal_account = gcal_login(args)
gcal_tz = get_gcal_timezone(gcal_account,gcal_id)