Skip to content

Commit eb3d21c

Browse files
committed
some more documentation, trying to make it more visible that a CalendarObjectResource (event) should contain one calendar component except for recurrences where it may contain overridden instances
1 parent 856269b commit eb3d21c

4 files changed

Lines changed: 28 additions & 9 deletions

File tree

caldav/calendarobjectresource.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,17 @@
7979

8080

8181
class CalendarObjectResource(DAVObject):
82-
"""
83-
Ref RFC 4791, section 4.1, a "Calendar Object Resource" can be an
82+
"""Ref RFC 4791, section 4.1, a "Calendar Object Resource" can be an
8483
event, a todo-item, a journal entry, or a free/busy entry
84+
85+
As per the RFC, a CalendarObjectResource can at most contain one
86+
calendar component, with the exception of recurrence components.
87+
Meaning that event.data typically contains one VCALENDAR with one
88+
VEVENT and possibly one VTIMEZONE.
89+
90+
In the case of expanded calendar date searches, each recurrence
91+
will (by default) wrapped in a distinct CalendarObjectResource
92+
object. This is a deviation from the definition given in the RFC.
8593
"""
8694

8795
## There is also STARTTOFINISH, STARTTOSTART and FINISHTOFINISH in RFC9253,
@@ -473,7 +481,7 @@ def _set_icalendar_component(self, value) -> None:
473481
icalendar_component = property(
474482
_get_icalendar_component,
475483
_set_icalendar_component,
476-
doc="icalendar component - should not be used with recurrence sets",
484+
doc="icalendar component - this is the simplest way to access the event/task - it will give you the first component that isn't a timezone component. For recurrence sets, the master component will be returned. For any non-recurring event/task/journal, there should be only one calendar component in the object. For results from an expanded search, there should be only one calendar component in the object",
477485
)
478486

479487
component = icalendar_component

caldav/davclient.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -563,14 +563,22 @@ def principals(self, name=None):
563563
## TODO: allow server side filtering. We need a <D:property-search><D:prop><D:displayname/></D:prop><D:match>{name}</D:match></D:property-search> inside the PrincipalPropertySearch
564564

565565
if name:
566-
name_filter = [ dav.PropertySearch() + [dav.Prop() + [dav.DisplayName()]] + dav.Match(value=name)]
567-
import pdb; pdb.set_trace()
566+
name_filter = [
567+
dav.PropertySearch()
568+
+ [dav.Prop() + [dav.DisplayName()]]
569+
+ dav.Match(value=name)
570+
]
571+
import pdb
572+
573+
pdb.set_trace()
568574
else:
569575
name_filter = []
570576

571-
query = dav.PrincipalPropertySearch() + name_filter + [
572-
dav.Prop() + cdav.CalendarHomeSet() + dav.DisplayName()
573-
]
577+
query = (
578+
dav.PrincipalPropertySearch()
579+
+ name_filter
580+
+ [dav.Prop() + cdav.CalendarHomeSet() + dav.DisplayName()]
581+
)
574582
response = self.report(self.url, etree.tostring(query.xmlelement()))
575583
principal_dict = response.find_objects_and_props()
576584
ret = []

caldav/elements/dav.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,14 @@ class PrincipalPropertySearch(BaseElement):
3030
class PropertySearch(BaseElement):
3131
tag: ClassVar[str] = ns("D", "property-search")
3232

33+
3334
# Filters
3435

36+
3537
class Match(BaseElement):
3638
tag: ClassVar[str] = ns("D", "match")
3739

40+
3841
# Conditions
3942
class SyncToken(BaseElement):
4043
tag: ClassVar[str] = ns("D", "sync-token")

tests/test_vcal.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def normalize(s, ignore_uid):
4949
## ref https://github.com/python-caldav/caldav/issues/380
5050
for i in range(0, len(s)):
5151
## We cut the value itself, just asserting the attribute is present
52-
if s[i].startswith(b'DTSTAMP'):
52+
if s[i].startswith(b"DTSTAMP"):
5353
s[i] = s[i][:9]
5454
return b"\n".join(s)
5555

0 commit comments

Comments
 (0)