raise VObjectBugException for bugs with recurrence rules

This commit is contained in:
Unrud 2017-06-09 02:30:21 +02:00 committed by Unrud
parent 02371685bd
commit f5835cfe46

View File

@ -66,6 +66,10 @@ TIMESTAMP_MIN = math.floor(DATETIME_MIN.timestamp())
TIMESTAMP_MAX = math.ceil(DATETIME_MAX.timestamp()) TIMESTAMP_MAX = math.ceil(DATETIME_MAX.timestamp())
class VObjectBugException(Exception):
"""Exception for workarounds related to bugs in VObject."""
def pretty_xml(element, level=0): def pretty_xml(element, level=0):
"""Indent an ElementTree ``element`` and its children.""" """Indent an ElementTree ``element`` and its children."""
if not level: if not level:
@ -287,20 +291,32 @@ def _visit_time_ranges(vobject_item, child_name, range_fn, infinity_fn):
# RECURRENCE-ID (http://www.kanzaki.com/docs/ical/recurrenceId.html). They # RECURRENCE-ID (http://www.kanzaki.com/docs/ical/recurrenceId.html). They
# are currently ignored but can change the start and end time. # are currently ignored but can change the start and end time.
def getrruleset(child):
try:
first_dtstart = next(iter(child.getrruleset(addRDate=True)),
None)
except TypeError as e:
raise VObjectBugException(
"failed to call getrruleset: %s" % e) from e
if first_dtstart is None:
raise VObjectBugException(
"empty iterator from getrruleset")
if (hasattr(child, "rrule") and
";UNTIL=" not in child.rrule.value.upper() and
";COUNT=" not in child.rrule.value.upper()):
if infinity_fn(_date_to_datetime(first_dtstart)):
return (), True
return child.getrruleset(addRDate=True), False
# Comments give the lines in the tables of the specification # Comments give the lines in the tables of the specification
if child_name == "VEVENT": if child_name == "VEVENT":
# TODO: check if there's a timezone # TODO: check if there's a timezone
dtstart = child.dtstart.value dtstart = child.dtstart.value
if child.rruleset: if child.rruleset:
if (hasattr(child, "rrule") and dtstarts, infinity = getrruleset(child)
";UNTIL=" not in child.rrule.value.upper() and if infinity:
";COUNT=" not in child.rrule.value.upper()):
for dtstart in child.getrruleset(addRDate=True):
if infinity_fn(_date_to_datetime(dtstart)):
return return
break
dtstarts = child.getrruleset(addRDate=True)
else: else:
dtstarts = (dtstart,) dtstarts = (dtstart,)
@ -367,14 +383,9 @@ def _visit_time_ranges(vobject_item, child_name, range_fn, infinity_fn):
created = _date_to_datetime(created.value) created = _date_to_datetime(created.value)
if child.rruleset: if child.rruleset:
if (hasattr(child, "rrule") and reference_dates, infinity = getrruleset(child)
";UNTIL=" not in child.rrule.value.upper() and if infinity:
";COUNT=" not in child.rrule.value.upper()):
for reference_date in child.getrruleset(addRDate=True):
if infinity_fn(_date_to_datetime(reference_date)):
return return
break
reference_dates = child.getrruleset(addRDate=True)
else: else:
if dtstart is not None: if dtstart is not None:
reference_dates = (dtstart,) reference_dates = (dtstart,)
@ -443,14 +454,9 @@ def _visit_time_ranges(vobject_item, child_name, range_fn, infinity_fn):
if dtstart is not None: if dtstart is not None:
dtstart = dtstart.value dtstart = dtstart.value
if child.rruleset: if child.rruleset:
if (hasattr(child, "rrule") and dtstarts, infinity = getrruleset(child)
";UNTIL=" not in child.rrule.value.upper() and if infinity:
";COUNT=" not in child.rrule.value.upper()):
for dtstart in child.getrruleset(addRDate=True):
if infinity_fn(_date_to_datetime(dtstart)):
return return
break
dtstarts = child.getrruleset(addRDate=True)
else: else:
dtstarts = (dtstart,) dtstarts = (dtstart,)