fix: CalDAV calendar-query liefert nur angefragte Props

Bisher wurde immer die komplette calendar-data mitgeschickt, auch
wenn der Client nur getetag wollte. DAVx5 macht einen zweistufigen
Sync: erst calendar-query nach ETags, dann multiget fuer die
neuen/geaenderten Events. Server-seitig zu viel zu liefern bricht
diesen Ablauf - Client denkt er hat alles und ueberspringt die
zweite Stufe, aber die Events landen nicht in der Android-Kalender-
DB.

Jetzt: calendar-query schaut nach ob <c:calendar-data/> in den
angefragten Props steht und liefert entsprechend.
calendar-multiget liefert weiterhin immer die vollen Daten.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stefan Hacker 2026-04-12 14:31:53 +02:00
parent 0edd41e46a
commit fbf10197d7
1 changed files with 6 additions and 3 deletions

View File

@ -333,6 +333,11 @@ def report(subpath):
multistatus = ET.Element(_qn('d', 'multistatus'))
tag = root.tag
# Prüfen ob der Client calendar-data angefragt hat. Falls nicht,
# liefern wir es auch nicht mit - strikter nach RFC und DAVx5
# entscheidet dann sauber "ich brauche Phase 2: multiget".
wants_data = root.find(f".//{_qn('c', 'calendar-data')}") is not None
if tag == _qn('c', 'calendar-multiget'):
hrefs = [h.text for h in root.findall(_qn('d', 'href')) if h.text]
for href in hrefs:
@ -343,8 +348,6 @@ def report(subpath):
return _xml_response(multistatus)
if tag == _qn('c', 'calendar-query'):
# Parse optional time-range. start ohne end = "ab jetzt offen";
# end ohne start = "bis X"; beide None = kein Filter.
start, end = _extract_time_range(root)
q = CalendarEvent.query.filter_by(calendar_id=cal.id)
if end is not None:
@ -355,7 +358,7 @@ def report(subpath):
| (CalendarEvent.recurrence_rule.isnot(None))
)
for ev in q.all():
multistatus.append(_event_response(user, cal, ev, include_data=True))
multistatus.append(_event_response(user, cal, ev, include_data=wants_data))
return _xml_response(multistatus)
# Unknown report - return empty multistatus so clients don't break