type annotations - ical

This commit is contained in:
Dmitry Belyaev 2021-04-29 16:19:41 +03:00
parent 8669aefabe
commit a6474ee984
Signed by: b4tman
GPG Key ID: 41A00BF15EA7E5F3
1 changed files with 28 additions and 22 deletions

View File

@ -1,12 +1,14 @@
import datetime import datetime
import logging import logging
from typing import Union, Dict, Any, Callable, Optional, List
from icalendar import Calendar, Event from icalendar import Calendar, Event
from pytz import utc from pytz import utc
def format_datetime_utc(value): def format_datetime_utc(value: Union[datetime.date, datetime.datetime]) -> str:
"""utc datetime as string from date or datetime value """utc datetime as string from date or datetime value
Arguments: Arguments:
value -- date or datetime value value -- date or datetime value
@ -23,20 +25,23 @@ def format_datetime_utc(value):
).replace(tzinfo=None).isoformat() + 'Z' ).replace(tzinfo=None).isoformat() + 'Z'
def gcal_date_or_dateTime(value, check_value=None): def gcal_date_or_dateTime(value: Union[datetime.date, datetime.datetime],
check_value: Union[datetime.date, datetime.datetime, None] = None)\
-> Dict[str, str]:
"""date or dateTime to gcal (start or end dict) """date or dateTime to gcal (start or end dict)
Arguments: Arguments:
value -- date or datetime value value: date or datetime
check_value - date or datetime to choise result type (if not None) check_value: optional for choose result type
Returns: Returns:
dict { 'date': ... } or { 'dateTime': ... } { 'date': ... } or { 'dateTime': ... }
""" """
if check_value is None: if check_value is None:
check_value = value check_value = value
result = {} result: Dict[str, str] = {}
if isinstance(check_value, datetime.datetime): if isinstance(check_value, datetime.datetime):
result['dateTime'] = format_datetime_utc(value) result['dateTime'] = format_datetime_utc(value)
else: else:
@ -52,7 +57,7 @@ class EventConverter(Event):
( https://developers.google.com/calendar/v3/reference/events#resource-representations ) ( https://developers.google.com/calendar/v3/reference/events#resource-representations )
""" """
def _str_prop(self, prop): def _str_prop(self, prop: str) -> str:
"""decoded string property """decoded string property
Arguments: Arguments:
@ -64,7 +69,7 @@ class EventConverter(Event):
return self.decoded(prop).decode(encoding='utf-8') return self.decoded(prop).decode(encoding='utf-8')
def _datetime_str_prop(self, prop): def _datetime_str_prop(self, prop: str) -> str:
"""utc datetime as string from property """utc datetime as string from property
Arguments: Arguments:
@ -76,7 +81,7 @@ class EventConverter(Event):
return format_datetime_utc(self.decoded(prop)) return format_datetime_utc(self.decoded(prop))
def _gcal_start(self): def _gcal_start(self) -> Dict[str, str]:
""" event start dict from icalendar event """ event start dict from icalendar event
Raises: Raises:
@ -89,7 +94,7 @@ class EventConverter(Event):
value = self.decoded('DTSTART') value = self.decoded('DTSTART')
return gcal_date_or_dateTime(value) return gcal_date_or_dateTime(value)
def _gcal_end(self): def _gcal_end(self) -> Dict[str, str]:
"""event end dict from icalendar event """event end dict from icalendar event
Raises: Raises:
@ -112,7 +117,9 @@ class EventConverter(Event):
raise ValueError('no DTEND or DURATION') raise ValueError('no DTEND or DURATION')
return result return result
def _put_to_gcal(self, gcal_event, prop, func, ics_prop=None): def _put_to_gcal(self, gcal_event: Dict[str, Any],
prop: str, func: Callable[[str], str],
ics_prop: Optional[str] = None):
"""get property from ical event if exist, and put to gcal event """get property from ical event if exist, and put to gcal event
Arguments: Arguments:
@ -127,7 +134,7 @@ 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): def to_gcal(self) -> Dict[str, Any]:
"""Convert """Convert
Returns: Returns:
@ -135,12 +142,11 @@ class EventConverter(Event):
""" """
event = { event = {
'iCalUID': self._str_prop('UID') 'iCalUID': self._str_prop('UID'),
'start': self._gcal_start(),
'end': self._gcal_end()
} }
event['start'] = self._gcal_start()
event['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)
self._put_to_gcal(event, 'location', self._str_prop) self._put_to_gcal(event, 'location', self._str_prop)
@ -155,28 +161,28 @@ class EventConverter(Event):
return event return event
class CalendarConverter(): class CalendarConverter:
"""Convert icalendar events to google calendar resources """Convert icalendar events to google calendar resources
""" """
logger = logging.getLogger('CalendarConverter') logger = logging.getLogger('CalendarConverter')
def __init__(self, calendar=None): def __init__(self, calendar: Optional[Calendar] = None):
self.calendar = calendar self.calendar: Optional[Calendar] = calendar
def load(self, filename): def load(self, filename: str):
""" load calendar from ics file """ load calendar from ics file
""" """
with open(filename, 'r', encoding='utf-8') as f: with open(filename, 'r', encoding='utf-8') as f:
self.calendar = Calendar.from_ical(f.read()) self.calendar = Calendar.from_ical(f.read())
self.logger.info('%s loaded', filename) self.logger.info('%s loaded', filename)
def loads(self, string): def loads(self, string: str):
""" load calendar from ics string """ load calendar from ics string
""" """
self.calendar = Calendar.from_ical(string) self.calendar = Calendar.from_ical(string)
def events_to_gcal(self): def events_to_gcal(self) -> List[Dict[str, Any]]:
"""Convert events to google calendar resources """Convert events to google calendar resources
""" """