Fix date generation if no start is specified in the repeat rules.

This commit is contained in:
redxef 2023-11-14 18:11:58 +01:00
parent 74cd1f91b4
commit 264301ecc0
Signed by: redxef
GPG key ID: 7DAC3AA211CBD921
3 changed files with 46 additions and 4 deletions

View file

@ -1,8 +1,10 @@
import abc import abc
import typing import typing
import datetime import datetime
import copy
import schema import schema
import dateutil.rrule
class Adapter(abc.ABC): class Adapter(abc.ABC):
schema: schema.Schema schema: schema.Schema
@ -30,6 +32,47 @@ class Source(abc.ABC):
) -> typing.Iterable[dict]: ) -> typing.Iterable[dict]:
raise NotImplementedError() raise NotImplementedError()
def get_events_resolved(
self,
start: datetime.datetime | None=None,
until: datetime.timedelta | None=None,
limit=None,
) -> typing.Iterable[dict]:
until = until if until else datetime.timedelta(days=365)
now = start if start else datetime.datetime.utcnow().astimezone()
now_365 = now + until
for e in self.get_events(
start=start,
until=until,
limit=limit,
):
if 'recurrence' not in e:
yield e
continue
r = e.pop('recurrence')
r = dateutil.rrule.rrulestr(
'\n'.join(r),
unfold=True,
ignoretz=True,
dtstart=datetime.datetime.fromisoformat(
e['start']['dateTime']
if 'dateTime' in e['start'] else
e['start']['date']
).replace(tzinfo=None)
)
for t_ in r.between(now.replace(tzinfo=None), now_365.replace(tzinfo=None)):
e_ = copy.deepcopy(e)
if 'dateTime' in e['start']:
e_['start']['dateTime'] = datetime.datetime.combine(t_.date(), datetime.datetime.fromisoformat(e['start']['dateTime']).time()).isoformat()
elif 'date' in e['start']:
e_['start']['date'] = datetime.datetime.combine(t_.date(), datetime.time())
if 'dateTime' in e['end']:
e_['end']['dateTime'] = datetime.datetime.combine(t_.date(), datetime.datetime.fromisoformat(e['end']['dateTime']).time()).isoformat()
elif 'date' in e['end']:
e_['end']['date'] = datetime.datetime.combine(t_.date(), datetime.time())
yield e_
yield e
class Sink(abc.ABC): class Sink(abc.ABC):
@abc.abstractmethod @abc.abstractmethod

View file

@ -151,7 +151,7 @@ def main(config, dryrun, level, range):
source_results = [] source_results = []
for source in sources: for source in sources:
try: try:
events += source.get_events(until=config['range']) events += source.get_events_resolved(until=config['range'])
source_results += [True] source_results += [True]
except Exception: except Exception:
logger.exception('failed to get events from source %s', source) logger.exception('failed to get events from source %s', source)
@ -167,9 +167,7 @@ def main(config, dryrun, level, range):
logger.log(logging.VERBOSE, 'events are: %s', [f"{e.get('summary', '<NO SUMMARY PROVIDED>')} ({e.get('start')})" for e in events]) logger.log(logging.VERBOSE, 'events are: %s', [f"{e.get('summary', '<NO SUMMARY PROVIDED>')} ({e.get('start')})" for e in events])
# post events # post events
if dryrun: if not dryrun:
logger.info("dryrun; would post events: %s", events)
else:
sink_results = [] sink_results = []
for sink in sinks: for sink in sinks:
try: try:

View file

@ -5,3 +5,4 @@ google-auth-httplib2
google-auth-oauthlib google-auth-oauthlib
click click
bs4 bs4
python-dateutil