mirror of
https://github.com/Kozea/Radicale.git
synced 2025-06-26 16:45:52 +00:00
honor TRIGGER of VALARM for timerange filtering
This commit is contained in:
parent
3ea22a7ea4
commit
f56416b2fb
1 changed files with 28 additions and 4 deletions
|
@ -121,6 +121,7 @@ def comp_match(item: "item.Item", filter_: ET.Element, level: int = 0) -> bool:
|
|||
logger.warning("Filtering %s is not supported", name)
|
||||
return True
|
||||
# Point #3 and #4 of rfc4791-9.7.1
|
||||
trigger = None
|
||||
if level == 0:
|
||||
components = [item.vobject_item]
|
||||
elif level == 1:
|
||||
|
@ -128,15 +129,18 @@ def comp_match(item: "item.Item", filter_: ET.Element, level: int = 0) -> bool:
|
|||
elif level == 2:
|
||||
components = list(getattr(item.vobject_item, "%s_list" % tag.lower()))
|
||||
for comp in components:
|
||||
if not hasattr(comp, name.lower()):
|
||||
subcomp = getattr(comp, name.lower(), None)
|
||||
if not subcomp:
|
||||
return False
|
||||
if hasattr(subcomp, "trigger"):
|
||||
trigger = subcomp.trigger.value
|
||||
for child in filter_:
|
||||
if child.tag == xmlutils.make_clark("C:prop-filter"):
|
||||
if not any(prop_match(comp, child, "C")
|
||||
for comp in components):
|
||||
return False
|
||||
elif child.tag == xmlutils.make_clark("C:time-range"):
|
||||
if not time_range_match(item.vobject_item, filter_[0], tag):
|
||||
if not time_range_match(item.vobject_item, filter_[0], tag, trigger):
|
||||
return False
|
||||
elif child.tag == xmlutils.make_clark("C:comp-filter"):
|
||||
if not comp_match(item, child, level=level + 1):
|
||||
|
@ -166,7 +170,7 @@ def prop_match(vobject_item: vobject.base.Component,
|
|||
# Point #3 and #4 of rfc4791-9.7.2
|
||||
for child in filter_:
|
||||
if ns == "C" and child.tag == xmlutils.make_clark("C:time-range"):
|
||||
if not time_range_match(vobject_item, child, name):
|
||||
if not time_range_match(vobject_item, child, name, None):
|
||||
return False
|
||||
elif child.tag == xmlutils.make_clark("%s:text-match" % ns):
|
||||
if not text_match(vobject_item, child, name, ns):
|
||||
|
@ -180,9 +184,10 @@ def prop_match(vobject_item: vobject.base.Component,
|
|||
|
||||
|
||||
def time_range_match(vobject_item: vobject.base.Component,
|
||||
filter_: ET.Element, child_name: str) -> bool:
|
||||
filter_: ET.Element, child_name: str, trigger: datetime | None) -> bool:
|
||||
"""Check whether the component/property ``child_name`` of
|
||||
``vobject_item`` matches the time-range ``filter_``."""
|
||||
# supporting since 3.5.4 now optional trigger (either absolute or relative offset)
|
||||
|
||||
if not filter_.get("start") and not filter_.get("end"):
|
||||
return False
|
||||
|
@ -193,6 +198,25 @@ def time_range_match(vobject_item: vobject.base.Component,
|
|||
def range_fn(range_start: datetime, range_end: datetime,
|
||||
is_recurrence: bool) -> bool:
|
||||
nonlocal matched
|
||||
if trigger:
|
||||
# if trigger is given, only check range_start
|
||||
if isinstance(trigger, timedelta):
|
||||
# trigger is a offset, apply to range_start
|
||||
if start < range_start + trigger and range_start + trigger < end:
|
||||
matched = True
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
elif isinstance(trigger, datetime):
|
||||
# trigger is absolute, use instead of range_start
|
||||
if start < trigger and trigger < end:
|
||||
matched = True
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
logger.warning("item/filter/time_range_match/range_fn: unsupported data format of provided trigger=%r", trigger)
|
||||
return True
|
||||
if start < range_end and range_start < end:
|
||||
matched = True
|
||||
return True
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue