Skip to content

Commit

Permalink
Search method: fixed inconsistencies and optimized a bit
Browse files Browse the repository at this point in the history
Some logic was only run when the expand-flag was set to True:

1) The logic automatically loading objects that aren't loaded

2) The logic removing "empty" responses from Google,

This logic ensures a consistent return from the search-method also for servers
not conforming to the RFC (by returning unloaded data or empty responses)

The second was fixed in the previous commit, but it feels wrong converting the
data to an icalendar object unless it's needed.
  • Loading branch information
tobixen committed Dec 26, 2023
1 parent bf9cd74 commit b7a5553
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 13 deletions.
30 changes: 20 additions & 10 deletions caldav/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,13 @@ def search(
xml, comp_class, props=props
)

for o in objects:
## This would not be needed if the servers would follow the standard ...
o.load(only_if_unloaded=True)

## Google sometimes returns empty objects
objects = [o for o in objects if o.has_component()]

if kwargs.get("expand", False):
## expand can only be used together with start and end.
## Error checking is done in build_search_xml_query. If
Expand All @@ -1229,13 +1236,6 @@ def search(
start = kwargs["start"]
end = kwargs["end"]

for o in objects:
## This would not be needed if the servers would follow the standard ...
o.load(only_if_unloaded=True)

## Google sometimes returns empty objects
objects = [o for o in objects if o.icalendar_component]

for o in objects:
component = o.icalendar_component
if component is None:
Expand All @@ -1248,9 +1248,6 @@ def search(
objects = []
for o in objects_:
objects.extend(o.split_expanded())
else:
## Google sometimes returns empty objects
objects = [o for o in objects if o.icalendar_component]

def sort_key_func(x):
ret = []
Expand Down Expand Up @@ -2122,6 +2119,8 @@ def _get_icalendar_component(self, assert_one=False):
See also https://github.com/python-caldav/caldav/issues/232
"""
self.load(only_if_unloaded=True)
if not self.icalendar_instance:
return None
ret = [
x
for x in self.icalendar_instance.subcomponents
Expand Down Expand Up @@ -2530,6 +2529,17 @@ def is_loaded(self):
self._data or self._vobject_instance or self._icalendar_instance
) and self.data.count("BEGIN:") > 1

def has_component(self):
return (
self._data
or self._vobject_instance
or (self._icalendar_instance and self.icalendar_component)
) and self.data.count("BEGIN:VEVENT") + self.data.count(
"BEGIN:VTODO"
) + self.data.count(
"BEGIN:VJOURNAL"
) > 0

def __str__(self) -> str:
return "%s: %s" % (self.__class__.__name__, self.url)

Expand Down
8 changes: 5 additions & 3 deletions tests/test_caldav_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,12 +350,14 @@ def testAbsoluteURL(self):
"http://cal.example.com/home/bernard/calendars/"
)

@mock.patch("caldav.objects.CalendarObjectResource.is_loaded")
def testDateSearch(self, mocked):
def _load(self, only_if_unloaded=True):
self.data = todo6

@mock.patch("caldav.objects.CalendarObjectResource.load", new=_load)
def testDateSearch(self):
"""
## ref https://github.com/python-caldav/caldav/issues/133
"""
mocked.__bool__ = lambda self: True
xml = """<xml><multistatus xmlns="DAV:">
<response>
<href>/principals/calendar/[email protected]/963/43B060B3-A023-48ED-B9E7-6FFD38D5073E.ics</href>
Expand Down

0 comments on commit b7a5553

Please sign in to comment.