You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
3.8 KiB
136 lines
3.8 KiB
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
|