from enum import IntEnum import datetime import re from dateutil import rrule from .calendar_api import calendar_api from .utils import to_dateTime, from_dateTime class weekdays(IntEnum): SUN = 6 MON = 0 TUE = 1 WED = 2 THU = 3 FRI = 4 SAT = 5 class Calendar: """Model for representing a Google calendar""" pass 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.recurrence = recurrence 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): if not until.tzinfo: until = until.astimezone() ret = rrule.rrule( freq=rrule.WEEKLY, dtstart=self.start, wkst=weekdays.SUN, until=until, byweekday=days, ) ret_str = str(ret).split("\n")[-1] ret_str = re.sub(r"(UNTIL=[^;]+)", r"\1Z", ret_str) if self.recurrence is None: 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()) self.id = event_id return event_id def delete(self, api: calendar_api): pass