|
|
from dateutil import rrule, tzfrom oauth2client import toolsfrom dateutil.parser import parse as date_parseimport reimport tzlocalimport argparseimport datetimeif __name__ == "__main__": from api import API, HttpErrorelse: from gapi.api import API, HttpError
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()APPLICATION_NAME = 'Google Calendar API Python'
SUN = 0MON = 1TUE = 2WED = 3THU = 4FRI = 5SAT = 6
def to_dateTime(datetime: datetime.datetime): """converts a datetime into json format for rest api""" if not datetime.tzinfo: datetime = datetime.astimezone() zone = tzlocal.get_localzone().zone datetime = datetime.isoformat(timespec='seconds') return { "timeZone": zone, "dateTime": datetime, }
def from_dateTime(dateTime): """converts to a datetime from json format returned by rest api""" timezone = tz.gettz(dateTime['timeZone']) datetime = date_parse(dateTime['dateTime']) datetime.replace(tzinfo=timezone) return datetime
class calendar_api(API): def __init__(self, app_name, client_secret_file, credentials_dir, scopes='https://www.googleapis.com/auth/calendar', version='v3', ): super().__init__('calendar', scopes, app_name, client_secret_file, credentials_dir, version)
self.calendars = self.get_calendars() self.ids = dict((calendar['summary'].lower(), calendar['id']) for calendar in self.calendars)
def create_event(self, calendar_id, body):
try: calendar_id = self.ids[calendar_id] except KeyError: pass service = self.service event_service = service.events() event = event_service.insert( calendarId=calendar_id, body=body).execute() return event['id']
def update_event(self, calendar_id, event_id, body): try: calendar_id = self.ids[calendar_id] except KeyError: pass
service = self.service event_service = service.events() try: event = event_service.get( calendarId=calendar_id, eventId=event_id).execute() except HttpError as e: if e.resp.status == 404: return self.create_event(calendar_id, body)
updated_event = service.events().update( calendarId=calendar_id, eventId=event['id'], body=body).execute() return updated_event["id"]
def get_calendars(self): page_token = None cl = [] first = True while page_token or first: first = False calendar_list_service = self.service.calendarList() calendar_list = calendar_list_service.list( pageToken=page_token).execute() cl += list( calendar_entry for calendar_entry in calendar_list['items']) page_token = calendar_list.get('nextPageToken') return cl
def get_events(self, cal_id): service = self.service try: cal_id = self.ids[cal_id] except KeyError: pass page_token = None ret = [] while True: event_service = service.events() events = event_service.list( calendarId=cal_id, pageToken=page_token).execute() ret += events['items'] page_token = events.get('nextPageToken') if not page_token: break return ret
def get_event_by_id(self, cal_id, event_id): """Retrieves event from cal_id and event_id""" service = self.service event_service = service.events() return event_service.get(calendarId=cal_id, eventId=event_id).execute()
class Event: """Model for a calendar event that can be uploaded"""
def __init__(self, start, end, name, description=None, recurrence=None, reminders=None, attendees=None, location=None, id=None ): self.start = start self.attendees = attendees self.end = end self.name = name self.description = description self.location = location self.id = id if reminders is None: self.reminders = {'useDefault': True} else: self.reminders = reminders
def add_reminder(self, until, method='popup'): """Add a reminder minutes before an event.
Use either a notification (popup) or email"""
assert method in ("email", "popup") self.reminders['useDefault'] = False if isinstance(until, datetime.timedelta): minutes_until = until.days * 24 * 60 minutes_until += until.seconds//60 else: minutes_until = until self.reminders.setdefault('overrides', []).append({ 'method': method, 'minutes': minutes_until, })
def add_weekly_recurrence(self, until: datetime.datetime, *days): ret = rrule.rrule(freq=rrule.WEEKLY, dtstart=self.start, wkst=SUN, until=until, byweekday=days) ret_str = str(ret).split('\n')[-1] ret_str = re.sub(r'(UNTIL=[^;]+)', r'\1Z', ret_str) try: self.recurrence except AttributeError: self.recurrence = [] self.recurrence.append(ret_str)
def to_json(self): keys = ('attendees', 'description', 'location', 'recurrence', 'reminders') ret = { 'summary': self.name, 'start': to_dateTime(self.start), 'end': to_dateTime(self.end), } for key in keys: try: value = self.__getattribute__(key) if value: ret[key] = value except AttributeError: pass return ret
def add_attendees(self): pass
@classmethod def from_json(cls, body): args = {} args['name'] = body.get('summary', 'unnamed') args['start'] = from_dateTime(body['start']) args['end'] = from_dateTime(body['end']) keys = ('attendees', 'description', 'location', 'recurrence', 'reminders', 'id') for key in keys: try: args[key] = body[key] except KeyError: pass instance = cls(**args) return instance
@classmethod def from_id(cls, api: calendar_api, calendar_id, event_id): """creates an event model from specified calendar and event_id""" event = api.get_event_by_id(calendar_id, event_id) return cls.from_json(event)
def upload(self, api: calendar_api, calendar_id): """Upload an event to calendar.
Either modifies an event in place or creates a new event."""
if self.id is not None: event_id = api.update_event(calendar_id, self.id, self.to_json()) else: event_id = api.create_event(calendar_id, self.to_json()) return event_id
if __name__ == "__main__": import os # ~~BODY EXAMPLE~~##~~BODY EXAMPLE~~ example = { 'attendees': [{'email': 'lpage@example.com'}, {'email': 'sbrin@example.com'}], 'description': "A chance to hear more about Google's\
developer products.", 'end': {'dateTime': '2015-05-28T17:00:00-07:00', 'timeZone': 'America/Los_Angeles'}, 'location': '800 Howard St., San Francisco, CA 94103', 'recurrence': ['RRULE:FREQ=DAILY;COUNT=2'], 'reminders': {'overrides': [ { 'method': 'email', 'minutes': 1440 }, { 'method': 'popup', 'minutes': 10 } ], 'useDefault': False}, 'start': {'dateTime': '2015-05-28T09:00:00-07:00', 'timeZone': 'America/Los_Angeles'}, 'summary': 'Google I/O 2015' } e = Event( date_parse('march 16, 2019 10:00 am'), date_parse('march 16, 2019 3:30 pm'), 'Hang out with Matt' ) path = r"C:\Users\Raphael\Documents\local_repo\cred" my_api = my_api = calendar_api('python', os.path.join( path, 'client_secret.json', path), path) cal_id = 'raphael.roberts48@gmail.com' e2 = Event.from_id(my_api, cal_id, 'qmrsd88ma8ko67ri98d8pbhd7s') # e2.upload(my_api, cal_id)
|