Ignore overwritten recurrences in time range filter (fixes #630)
This commit is contained in:
parent
ae897c1cd3
commit
a6663f19f0
@ -279,44 +279,44 @@ def _visit_time_ranges(vobject_item, child_name, range_fn, infinity_fn):
|
|||||||
"""
|
"""
|
||||||
child = getattr(vobject_item, child_name.lower())
|
child = getattr(vobject_item, child_name.lower())
|
||||||
|
|
||||||
# TODO: Single recurrences can be overwritten by components with
|
def getrruleset(child, ignore=()):
|
||||||
# RECURRENCE-ID (http://www.kanzaki.com/docs/ical/recurrenceId.html). They
|
|
||||||
# may overwrite the start and end time. Currently these components and
|
|
||||||
# the overwritten recurrences are both considered. The overwritten
|
|
||||||
# recurrence should be ignored instead.
|
|
||||||
|
|
||||||
def getrruleset(child):
|
|
||||||
if (hasattr(child, "rrule") and
|
if (hasattr(child, "rrule") and
|
||||||
";UNTIL=" not in child.rrule.value.upper() and
|
";UNTIL=" not in child.rrule.value.upper() and
|
||||||
";COUNT=" not in child.rrule.value.upper()):
|
";COUNT=" not in child.rrule.value.upper()):
|
||||||
first_dtstart = next(iter(child.getrruleset(addRDate=True)), None)
|
for dtstart in child.getrruleset(addRDate=True):
|
||||||
if (first_dtstart is not None and
|
if dtstart in ignore:
|
||||||
infinity_fn(_date_to_datetime(first_dtstart))):
|
continue
|
||||||
return (), True
|
if infinity_fn(_date_to_datetime(dtstart)):
|
||||||
return child.getrruleset(addRDate=True), False
|
return (), True
|
||||||
|
break
|
||||||
|
return filter(lambda dtstart: dtstart not in ignore,
|
||||||
|
child.getrruleset(addRDate=True)), False
|
||||||
|
|
||||||
def get_children(components):
|
def get_children(components):
|
||||||
main = None
|
main = None
|
||||||
|
recurrences = []
|
||||||
for comp in components:
|
for comp in components:
|
||||||
if hasattr(comp, "recurrence_id") and comp.recurrence_id.value:
|
if hasattr(comp, "recurrence_id") and comp.recurrence_id.value:
|
||||||
|
recurrences.append(comp.recurrence_id.value)
|
||||||
if comp.rruleset:
|
if comp.rruleset:
|
||||||
# Prevent possible infinite loop
|
# Prevent possible infinite loop
|
||||||
raise ValueError("Overwritten recurrence with RRULESET")
|
raise ValueError("Overwritten recurrence with RRULESET")
|
||||||
yield comp, True
|
yield comp, True, ()
|
||||||
else:
|
else:
|
||||||
if main is not None:
|
if main is not None:
|
||||||
raise ValueError("Multiple main components")
|
raise ValueError("Multiple main components")
|
||||||
main = comp
|
main = comp
|
||||||
yield main, False
|
yield main, False, recurrences
|
||||||
|
|
||||||
# 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":
|
||||||
for child, recurrence in get_children(vobject_item.vevent_list):
|
for child, recurrence, recurrences in get_children(
|
||||||
|
vobject_item.vevent_list):
|
||||||
# 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:
|
||||||
dtstarts, infinity = getrruleset(child)
|
dtstarts, infinity = getrruleset(child, recurrences)
|
||||||
if infinity:
|
if infinity:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
@ -362,7 +362,8 @@ def _visit_time_ranges(vobject_item, child_name, range_fn, infinity_fn):
|
|||||||
return
|
return
|
||||||
|
|
||||||
elif child_name == "VTODO":
|
elif child_name == "VTODO":
|
||||||
for child, recurrence in get_children(vobject_item.vtodo_list):
|
for child, recurrence, recurrences in get_children(
|
||||||
|
vobject_item.vtodo_list):
|
||||||
dtstart = getattr(child, "dtstart", None)
|
dtstart = getattr(child, "dtstart", None)
|
||||||
duration = getattr(child, "duration", None)
|
duration = getattr(child, "duration", None)
|
||||||
due = getattr(child, "due", None)
|
due = getattr(child, "due", None)
|
||||||
@ -386,7 +387,7 @@ 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:
|
||||||
reference_dates, infinity = getrruleset(child)
|
reference_dates, infinity = getrruleset(child, recurrences)
|
||||||
if infinity:
|
if infinity:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
@ -461,13 +462,14 @@ def _visit_time_ranges(vobject_item, child_name, range_fn, infinity_fn):
|
|||||||
return
|
return
|
||||||
|
|
||||||
elif child_name == "VJOURNAL":
|
elif child_name == "VJOURNAL":
|
||||||
for child, recurrence in get_children(vobject_item.vjournal_list):
|
for child, recurrence, recurrences in get_children(
|
||||||
|
vobject_item.vjournal_list):
|
||||||
dtstart = getattr(child, "dtstart", None)
|
dtstart = getattr(child, "dtstart", None)
|
||||||
|
|
||||||
if dtstart is not None:
|
if dtstart is not None:
|
||||||
dtstart = dtstart.value
|
dtstart = dtstart.value
|
||||||
if child.rruleset:
|
if child.rruleset:
|
||||||
dtstarts, infinity = getrruleset(child)
|
dtstarts, infinity = getrruleset(child, recurrences)
|
||||||
if infinity:
|
if infinity:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user