Fix date generation if no start is specified in the repeat rules.
This commit is contained in:
parent
74cd1f91b4
commit
264301ecc0
3 changed files with 46 additions and 4 deletions
|
@ -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
|
||||||
|
|
6
main.py
6
main.py
|
@ -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:
|
||||||
|
|
|
@ -5,3 +5,4 @@ google-auth-httplib2
|
||||||
google-auth-oauthlib
|
google-auth-oauthlib
|
||||||
click
|
click
|
||||||
bs4
|
bs4
|
||||||
|
python-dateutil
|
||||||
|
|
Loading…
Reference in a new issue