more types in gcal

This commit is contained in:
Dmitry Belyaev 2022-06-03 23:42:29 +03:00
parent 260f168077
commit 2f3a87f25f
Signed by: b4tman
GPG Key ID: 41A00BF15EA7E5F3
2 changed files with 90 additions and 30 deletions

View File

@ -1,6 +1,17 @@
import logging import logging
from datetime import datetime from datetime import datetime
from typing import List, Dict, Any, Callable, Tuple, Optional, Union, TypedDict, TypeAlias from typing import (
List,
Dict,
Any,
Callable,
Tuple,
Optional,
Union,
TypedDict,
TypeAlias,
Literal,
)
import google.auth import google.auth
from google.oauth2 import service_account from google.oauth2 import service_account
@ -20,7 +31,55 @@ class EventDateTime(TypedDict, total=False):
EventDateOrDateTime: TypeAlias = Union[EventDate, EventDateTime] EventDateOrDateTime: TypeAlias = Union[EventDate, EventDateTime]
EventData: TypeAlias = Dict[str, Union[str, EventDateOrDateTime, None]]
class ACLScope(TypedDict, total=False):
type: str
value: str
class ACLRule(TypedDict, total=False):
scope: ACLScope
role: str
class CalendarData(TypedDict, total=False):
id: str
summary: str
description: str
timeZone: str
class EventData(TypedDict, total=False):
id: str
summary: str
description: str
start: EventDateOrDateTime
end: EventDateOrDateTime
iCalUID: str
location: str
status: str
created: str
updated: str
sequence: int
transparency: str
visibility: str
EventDataKey = Union[
Literal["id"],
Literal["summary"],
Literal["description"],
Literal["start"],
Literal["end"],
Literal["iCalUID"],
Literal["location"],
Literal["status"],
Literal["created"],
Literal["updated"],
Literal["sequence"],
Literal["transparency"],
Literal["visibility"],
]
EventList: TypeAlias = List[EventData] EventList: TypeAlias = List[EventData]
EventTuple: TypeAlias = Tuple[EventData, EventData] EventTuple: TypeAlias = Tuple[EventData, EventData]
@ -90,7 +149,7 @@ def select_event_key(event: EventData) -> Optional[str]:
key name or None if no key found key name or None if no key found
""" """
key = None key: Optional[str] = None
if "iCalUID" in event: if "iCalUID" in event:
key = "iCalUID" key = "iCalUID"
elif "id" in event: elif "id" in event:
@ -118,9 +177,10 @@ class GoogleCalendar:
callback function callback function
""" """
def callback(request_id: str, response: Any, exception: Exception): def callback(request_id: str, response: Any, exception: Optional[Exception]):
event: EventData = events_by_req[int(request_id)] event: EventData = events_by_req[int(request_id)]
key: str = str(select_event_key(event)) event_key: Optional[str] = select_event_key(event)
key: str = event_key if event_key is not None else ""
if exception is not None: if exception is not None:
self.logger.error( self.logger.error(
@ -131,7 +191,7 @@ class GoogleCalendar:
str(exception), str(exception),
) )
else: else:
resp_key: str = select_event_key(response) resp_key: Optional[str] = select_event_key(response)
if resp_key is not None: if resp_key is not None:
event = response event = response
key = resp_key key = resp_key
@ -183,7 +243,9 @@ class GoogleCalendar:
exists: List[EventTuple] = [] exists: List[EventTuple] = []
not_found: EventList = [] not_found: EventList = []
def list_callback(request_id: str, response: Any, exception: Exception): def list_callback(
request_id: str, response: Any, exception: Optional[Exception]
):
found: bool = False found: bool = False
cur_event: EventData = events_by_req[int(request_id)] cur_event: EventData = events_by_req[int(request_id)]
if exception is None: if exception is None:
@ -333,7 +395,7 @@ class GoogleCalendar:
calendar Resource calendar Resource
""" """
calendar: Dict[str, str] = {"summary": summary} calendar: CalendarData = CalendarData(summary=summary)
if time_zone is not None: if time_zone is not None:
calendar["timeZone"] = time_zone calendar["timeZone"] = time_zone
@ -349,12 +411,7 @@ class GoogleCalendar:
def make_public(self): def make_public(self):
"""make calendar public""" """make calendar public"""
rule_public: Dict[str, Union[str, Dict[str, str]]] = { rule_public: ACLRule = ACLRule(scope=ACLScope(type="default"), role="reader")
"scope": {
"type": "default",
},
"role": "reader",
}
return ( return (
self.service.acl() self.service.acl()
.insert(calendarId=self.calendar_id, body=rule_public) .insert(calendarId=self.calendar_id, body=rule_public)
@ -368,13 +425,9 @@ class GoogleCalendar:
email -- email to add email -- email to add
""" """
rule_owner: Dict[str, Union[str, Dict[str, str]]] = { rule_owner: ACLRule = ACLRule(
"scope": { scope=ACLScope(type="user", value=email), role="owner"
"type": "user", )
"value": email,
},
"role": "owner",
}
return ( return (
self.service.acl() self.service.acl()
.insert(calendarId=self.calendar_id, body=rule_owner) .insert(calendarId=self.calendar_id, body=rule_owner)

View File

@ -5,7 +5,14 @@ from typing import Union, Dict, Callable, Optional, Mapping, TypeAlias, TypedDic
from icalendar import Calendar, Event from icalendar import Calendar, Event
from pytz import utc from pytz import utc
from .gcal import EventData, EventList, EventDateOrDateTime, EventDateTime, EventDate from .gcal import (
EventData,
EventList,
EventDateOrDateTime,
EventDateTime,
EventDate,
EventDataKey,
)
DateDateTime: TypeAlias = Union[datetime.date, datetime.datetime] DateDateTime: TypeAlias = Union[datetime.date, datetime.datetime]
@ -121,7 +128,7 @@ class EventConverter(Event):
def _put_to_gcal( def _put_to_gcal(
self, self,
gcal_event: EventData, gcal_event: EventData,
prop: str, prop: EventDataKey,
func: Callable[[str], str], func: Callable[[str], str],
ics_prop: Optional[str] = None, ics_prop: Optional[str] = None,
): ):
@ -139,18 +146,18 @@ class EventConverter(Event):
if ics_prop in self: if ics_prop in self:
gcal_event[prop] = func(ics_prop) gcal_event[prop] = func(ics_prop)
def to_gcal(self) -> EventData: def convert(self) -> EventData:
"""Convert """Convert
Returns: Returns:
dict - google calendar#event resource dict - google calendar#event resource
""" """
event: EventData = { event: EventData = EventData(
"iCalUID": self._str_prop("UID"), iCalUID=self._str_prop("UID"),
"start": self._gcal_start(), start=self._gcal_start(),
"end": self._gcal_end(), end=self._gcal_end(),
} )
self._put_to_gcal(event, "summary", self._str_prop) self._put_to_gcal(event, "summary", self._str_prop)
self._put_to_gcal(event, "description", self._str_prop) self._put_to_gcal(event, "description", self._str_prop)
@ -189,6 +196,6 @@ class CalendarConverter:
ics_events = calendar.walk(name="VEVENT") ics_events = calendar.walk(name="VEVENT")
self.logger.info("%d events read", len(ics_events)) self.logger.info("%d events read", len(ics_events))
result = list(map(lambda event: EventConverter(event).to_gcal(), ics_events)) result = list(map(lambda event: EventConverter(event).convert(), ics_events))
self.logger.info("%d events converted", len(result)) self.logger.info("%d events converted", len(result))
return result return result