mirror of
https://github.com/b4tman/sync_ics2gcal
synced 2025-02-01 12:28:29 +00:00
type aliases
This commit is contained in:
parent
5e01b6dd01
commit
052ba440d0
@ -1,12 +1,16 @@
|
|||||||
|
|
||||||
from .ical import (
|
from .ical import (
|
||||||
CalendarConverter,
|
CalendarConverter,
|
||||||
EventConverter
|
EventConverter,
|
||||||
|
DateDateTime
|
||||||
)
|
)
|
||||||
|
|
||||||
from .gcal import (
|
from .gcal import (
|
||||||
GoogleCalendarService,
|
GoogleCalendarService,
|
||||||
GoogleCalendar
|
GoogleCalendar,
|
||||||
|
EventData,
|
||||||
|
EventList,
|
||||||
|
EventTuple
|
||||||
)
|
)
|
||||||
|
|
||||||
from .sync import (
|
from .sync import (
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
import logging
|
import logging
|
||||||
|
from datetime import datetime
|
||||||
|
from typing import List, Dict, Any, Callable, Tuple, Optional, Union
|
||||||
|
|
||||||
import google.auth
|
import google.auth
|
||||||
from google.oauth2 import service_account
|
from google.oauth2 import service_account
|
||||||
from googleapiclient import discovery
|
from googleapiclient import discovery
|
||||||
from pytz import utc
|
from pytz import utc
|
||||||
from datetime import datetime
|
|
||||||
from typing import List, Dict, Any, Callable, Tuple, Optional
|
EventData = Dict[str, Union[str, 'EventData', None]]
|
||||||
|
EventList = List[EventData]
|
||||||
|
EventTuple = Tuple[EventData, EventData]
|
||||||
|
|
||||||
|
|
||||||
class GoogleCalendarService:
|
class GoogleCalendarService:
|
||||||
@ -62,7 +66,7 @@ class GoogleCalendarService:
|
|||||||
return service
|
return service
|
||||||
|
|
||||||
|
|
||||||
def select_event_key(event: Dict[str, Any]) -> Optional[str]:
|
def select_event_key(event: EventData) -> Optional[str]:
|
||||||
"""select event key for logging
|
"""select event key for logging
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
@ -90,7 +94,7 @@ class GoogleCalendar:
|
|||||||
self.service: discovery.Resource = service
|
self.service: discovery.Resource = service
|
||||||
self.calendarId: str = calendarId
|
self.calendarId: str = calendarId
|
||||||
|
|
||||||
def _make_request_callback(self, action: str, events_by_req: List[Dict[str, Any]]) -> Callable:
|
def _make_request_callback(self, action: str, events_by_req: EventList) -> Callable:
|
||||||
"""make callback for log result of batch request
|
"""make callback for log result of batch request
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
@ -117,9 +121,10 @@ class GoogleCalendar:
|
|||||||
key = resp_key
|
key = resp_key
|
||||||
self.logger.info('event %s ok, %s: %s',
|
self.logger.info('event %s ok, %s: %s',
|
||||||
action, key, event.get(key))
|
action, key, event.get(key))
|
||||||
|
|
||||||
return callback
|
return callback
|
||||||
|
|
||||||
def list_events_from(self, start: datetime) -> List[Dict[str, Any]]:
|
def list_events_from(self, start: datetime) -> EventList:
|
||||||
""" list events from calendar, where start date >= start
|
""" list events from calendar, where start date >= start
|
||||||
"""
|
"""
|
||||||
fields = 'nextPageToken,items(id,iCalUID,updated)'
|
fields = 'nextPageToken,items(id,iCalUID,updated)'
|
||||||
@ -141,7 +146,7 @@ class GoogleCalendar:
|
|||||||
self.logger.info('%d events listed', len(events))
|
self.logger.info('%d events listed', len(events))
|
||||||
return events
|
return events
|
||||||
|
|
||||||
def find_exists(self, events: List) -> Tuple[List[Tuple[Dict[str, Any], Dict[str, Any]]], List[Dict[str, Any]]]:
|
def find_exists(self, events: List) -> Tuple[List[EventTuple], EventList]:
|
||||||
""" find existing events from list, by 'iCalUID' field
|
""" find existing events from list, by 'iCalUID' field
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
@ -189,7 +194,7 @@ class GoogleCalendar:
|
|||||||
len(exists), len(not_found))
|
len(exists), len(not_found))
|
||||||
return exists, not_found
|
return exists, not_found
|
||||||
|
|
||||||
def insert_events(self, events: List[Dict[str, Any]]):
|
def insert_events(self, events: EventList):
|
||||||
""" insert list of events
|
""" insert list of events
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
@ -211,7 +216,7 @@ class GoogleCalendar:
|
|||||||
i += 1
|
i += 1
|
||||||
batch.execute()
|
batch.execute()
|
||||||
|
|
||||||
def patch_events(self, event_tuples: List[Tuple[Dict[str, Any], Dict[str, Any]]]):
|
def patch_events(self, event_tuples: List[EventTuple]):
|
||||||
""" patch (update) events
|
""" patch (update) events
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
@ -234,7 +239,7 @@ class GoogleCalendar:
|
|||||||
i += 1
|
i += 1
|
||||||
batch.execute()
|
batch.execute()
|
||||||
|
|
||||||
def update_events(self, event_tuples: List[Tuple[Dict[str, Any], Dict[str, Any]]]):
|
def update_events(self, event_tuples: List[EventTuple]):
|
||||||
""" update events
|
""" update events
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
@ -257,7 +262,7 @@ class GoogleCalendar:
|
|||||||
i += 1
|
i += 1
|
||||||
batch.execute()
|
batch.execute()
|
||||||
|
|
||||||
def delete_events(self, events: List[Dict[str, Any]]):
|
def delete_events(self, events: EventList):
|
||||||
""" delete events
|
""" delete events
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
from typing import Union, Dict, Any, Callable, Optional, List
|
from typing import Union, Dict, Callable, Optional
|
||||||
|
|
||||||
from icalendar import Calendar, Event
|
from icalendar import Calendar, Event
|
||||||
from pytz import utc
|
from pytz import utc
|
||||||
|
|
||||||
|
from .gcal import EventData, EventList
|
||||||
|
|
||||||
def format_datetime_utc(value: Union[datetime.date, datetime.datetime]) -> str:
|
DateDateTime = Union[datetime.date, datetime.datetime]
|
||||||
|
|
||||||
|
|
||||||
|
def format_datetime_utc(value: DateDateTime) -> str:
|
||||||
"""utc datetime as string from date or datetime value
|
"""utc datetime as string from date or datetime value
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
@ -25,8 +29,8 @@ def format_datetime_utc(value: Union[datetime.date, datetime.datetime]) -> str:
|
|||||||
).replace(tzinfo=None).isoformat() + 'Z'
|
).replace(tzinfo=None).isoformat() + 'Z'
|
||||||
|
|
||||||
|
|
||||||
def gcal_date_or_dateTime(value: Union[datetime.date, datetime.datetime],
|
def gcal_date_or_dateTime(value: DateDateTime,
|
||||||
check_value: Union[datetime.date, datetime.datetime, None] = None)\
|
check_value: Optional[DateDateTime] = None) \
|
||||||
-> Dict[str, str]:
|
-> Dict[str, str]:
|
||||||
"""date or dateTime to gcal (start or end dict)
|
"""date or dateTime to gcal (start or end dict)
|
||||||
|
|
||||||
@ -117,7 +121,7 @@ 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: Dict[str, Any],
|
def _put_to_gcal(self, gcal_event: EventData,
|
||||||
prop: str, func: Callable[[str], str],
|
prop: str, func: Callable[[str], str],
|
||||||
ics_prop: Optional[str] = None):
|
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
|
||||||
@ -134,7 +138,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) -> Dict[str, Any]:
|
def to_gcal(self) -> EventData:
|
||||||
"""Convert
|
"""Convert
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@ -182,7 +186,7 @@ class CalendarConverter:
|
|||||||
"""
|
"""
|
||||||
self.calendar = Calendar.from_ical(string)
|
self.calendar = Calendar.from_ical(string)
|
||||||
|
|
||||||
def events_to_gcal(self) -> List[Dict[str, Any]]:
|
def events_to_gcal(self) -> EventList:
|
||||||
"""Convert events to google calendar resources
|
"""Convert events to google calendar resources
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
import operator
|
import operator
|
||||||
from typing import List, Any, Dict, Set, Tuple, Union, Callable
|
from typing import List, Dict, Set, Tuple, Union, Callable
|
||||||
|
|
||||||
import dateutil.parser
|
import dateutil.parser
|
||||||
from pytz import utc
|
from pytz import utc
|
||||||
|
|
||||||
from .gcal import GoogleCalendar
|
from .gcal import GoogleCalendar, EventData, EventList, EventTuple
|
||||||
from .ical import CalendarConverter
|
from .ical import CalendarConverter, DateDateTime
|
||||||
|
|
||||||
|
|
||||||
class CalendarSync:
|
class CalendarSync:
|
||||||
@ -19,15 +19,15 @@ class CalendarSync:
|
|||||||
def __init__(self, gcalendar: GoogleCalendar, converter: CalendarConverter):
|
def __init__(self, gcalendar: GoogleCalendar, converter: CalendarConverter):
|
||||||
self.gcalendar: GoogleCalendar = gcalendar
|
self.gcalendar: GoogleCalendar = gcalendar
|
||||||
self.converter: CalendarConverter = converter
|
self.converter: CalendarConverter = converter
|
||||||
self.to_insert: List[Dict[str, Any]] = []
|
self.to_insert: EventList = []
|
||||||
self.to_update: List[Tuple[Dict[str, Any], Dict[str, Any]]] = []
|
self.to_update: List[EventTuple] = []
|
||||||
self.to_delete: List[Dict[str, Any]] = []
|
self.to_delete: EventList = []
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _events_list_compare(items_src: List[Dict[str, Any]],
|
def _events_list_compare(items_src: EventList,
|
||||||
items_dst: List[Dict[str, Any]],
|
items_dst: EventList,
|
||||||
key: str = 'iCalUID') \
|
key: str = 'iCalUID') \
|
||||||
-> Tuple[List[Dict[str, Any]], List[Tuple[Dict[str, Any], Dict[str, Any]]], List[Dict[str, Any]]]:
|
-> Tuple[EventList, List[EventTuple], EventList]:
|
||||||
""" compare list of events by key
|
""" compare list of events by key
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
@ -41,7 +41,7 @@ class CalendarSync:
|
|||||||
items_to_delete)
|
items_to_delete)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_key(item: Dict[str, Any]) -> str: return item[key]
|
def get_key(item: EventData) -> str: return item[key]
|
||||||
|
|
||||||
keys_src: Set[str] = set(map(get_key, items_src))
|
keys_src: Set[str] = set(map(get_key, items_src))
|
||||||
keys_dst: Set[str] = set(map(get_key, items_dst))
|
keys_dst: Set[str] = set(map(get_key, items_dst))
|
||||||
@ -50,9 +50,9 @@ class CalendarSync:
|
|||||||
keys_to_update = keys_src & keys_dst
|
keys_to_update = keys_src & keys_dst
|
||||||
keys_to_delete = keys_dst - keys_src
|
keys_to_delete = keys_dst - keys_src
|
||||||
|
|
||||||
def items_by_keys(items: List[Dict[str, Any]],
|
def items_by_keys(items: EventList,
|
||||||
key_name: str,
|
key_name: str,
|
||||||
keys: Set[str]) -> List[Dict[str, Any]]:
|
keys: Set[str]) -> EventList:
|
||||||
return list(filter(lambda item: item[key_name] in keys, items))
|
return list(filter(lambda item: item[key_name] in keys, items))
|
||||||
|
|
||||||
items_to_insert = items_by_keys(items_src, key, keys_to_insert)
|
items_to_insert = items_by_keys(items_src, key, keys_to_insert)
|
||||||
@ -70,7 +70,7 @@ class CalendarSync:
|
|||||||
""" filter 'to_update' events by 'updated' datetime
|
""" filter 'to_update' events by 'updated' datetime
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def filter_updated(event_tuple: Tuple[Dict[str, Any], Dict[str, Any]]) -> bool:
|
def filter_updated(event_tuple: EventTuple) -> bool:
|
||||||
new, old = event_tuple
|
new, old = event_tuple
|
||||||
new_date = dateutil.parser.parse(new['updated'])
|
new_date = dateutil.parser.parse(new['updated'])
|
||||||
old_date = dateutil.parser.parse(old['updated'])
|
old_date = dateutil.parser.parse(old['updated'])
|
||||||
@ -79,10 +79,10 @@ class CalendarSync:
|
|||||||
self.to_update = list(filter(filter_updated, self.to_update))
|
self.to_update = list(filter(filter_updated, self.to_update))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _filter_events_by_date(events: List[Dict[str, Any]],
|
def _filter_events_by_date(events: EventList,
|
||||||
date: Union[datetime.date, datetime.datetime],
|
date: DateDateTime,
|
||||||
op: Callable[[Union[datetime.date, datetime.datetime],
|
op: Callable[[DateDateTime,
|
||||||
Union[datetime.date, datetime.datetime]], bool]) -> List[Dict[str, Any]]:
|
DateDateTime], bool]) -> EventList:
|
||||||
""" filter events by start datetime
|
""" filter events by start datetime
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
@ -94,10 +94,10 @@ class CalendarSync:
|
|||||||
list of filtred events
|
list of filtred events
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def filter_by_date(event: Dict[str, Any]) -> bool:
|
def filter_by_date(event: EventData) -> bool:
|
||||||
date_cmp = date
|
date_cmp = date
|
||||||
event_start: Dict[str, str] = event['start']
|
event_start: Dict[str, str] = event['start']
|
||||||
event_date: Union[datetime.date, datetime.datetime, str, None] = None
|
event_date: Union[DateDateTime, str, None] = None
|
||||||
compare_dates = False
|
compare_dates = False
|
||||||
|
|
||||||
if 'date' in event_start:
|
if 'date' in event_start:
|
||||||
@ -117,7 +117,7 @@ class CalendarSync:
|
|||||||
return list(filter(filter_by_date, events))
|
return list(filter(filter_by_date, events))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _tz_aware_datetime(date: Union[datetime.date, datetime.datetime]) -> datetime.datetime:
|
def _tz_aware_datetime(date: DateDateTime) -> datetime.datetime:
|
||||||
"""make tz aware datetime from datetime/date (utc if no tzinfo)
|
"""make tz aware datetime from datetime/date (utc if no tzinfo)
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
@ -133,7 +133,7 @@ class CalendarSync:
|
|||||||
date = date.replace(tzinfo=utc)
|
date = date.replace(tzinfo=utc)
|
||||||
return date
|
return date
|
||||||
|
|
||||||
def prepare_sync(self, start_date: Union[datetime.date, datetime.datetime]) -> None:
|
def prepare_sync(self, start_date: DateDateTime) -> None:
|
||||||
"""prepare sync lists by comparsion of events
|
"""prepare sync lists by comparsion of events
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user