fix: CalDAV HEAD auf Events + PROPPATCH auf Kalender
* GET-Route akzeptiert jetzt auch HEAD - manche Clients pruefen Existenz einer Ressource via HEAD bevor sie GET senden. * Neue PROPPATCH-Route auf der Kalender-Collection: erkennt calendar-color + displayname und persistiert beides. Andere Properties werden als "angewendet" bestaetigt, damit DAVx5 und Apple Calendar nicht enttaeuscht sind. Damit sollten die 500-Fehler beim Sync verschwinden. Falls nicht, bitte Server- oder DAVx5-Log posten. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
189aa18be8
commit
e7f469f477
|
|
@ -386,7 +386,7 @@ def _extract_time_range(root: ET.Element):
|
||||||
# GET single event
|
# GET single event
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
@dav_bp.route('/<username>/<cal_part>/<filename>', methods=['GET'])
|
@dav_bp.route('/<username>/<cal_part>/<filename>', methods=['GET', 'HEAD'])
|
||||||
@basic_auth
|
@basic_auth
|
||||||
def get_event(username, cal_part, filename):
|
def get_event(username, cal_part, filename):
|
||||||
user: User = request.dav_user
|
user: User = request.dav_user
|
||||||
|
|
@ -500,6 +500,53 @@ def delete_calendar(username, cal_part):
|
||||||
return Response('', 204)
|
return Response('', 204)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# PROPPATCH (Clients setzen gerne Anzeigefarbe/-name). Wir persistieren
|
||||||
|
# den Kalenderfarbe (calendar-color) + Displayname; andere Properties
|
||||||
|
# bestaetigen wir als "angewendet" damit DAVx5/Apple zufrieden sind.
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@dav_bp.route('/<username>/<cal_part>/', methods=['PROPPATCH'])
|
||||||
|
@dav_bp.route('/<username>/<cal_part>', methods=['PROPPATCH'])
|
||||||
|
@basic_auth
|
||||||
|
def proppatch_calendar(username, cal_part):
|
||||||
|
user: User = request.dav_user
|
||||||
|
if username != user.username:
|
||||||
|
return Response('', 403)
|
||||||
|
cal_id = _parse_calendar_path(cal_part)
|
||||||
|
cal = _calendar_for(user, cal_id) if cal_id else None
|
||||||
|
if not cal:
|
||||||
|
return Response('Not found', 404)
|
||||||
|
try:
|
||||||
|
root = ET.fromstring(request.data or b'<x/>')
|
||||||
|
except ET.ParseError:
|
||||||
|
return Response('Malformed XML', 400)
|
||||||
|
|
||||||
|
for el in root.iter():
|
||||||
|
tag = el.tag
|
||||||
|
if tag == _qn('ic', 'calendar-color') and el.text:
|
||||||
|
cal.color = el.text.strip()[:7]
|
||||||
|
elif tag == _qn('d', 'displayname') and el.text:
|
||||||
|
cal.name = el.text.strip()[:255]
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
# Respond with 207 marking everything as applied so the client is happy.
|
||||||
|
multistatus = ET.Element(_qn('d', 'multistatus'))
|
||||||
|
href = _href_calendar(user.username, cal.id)
|
||||||
|
resp = ET.SubElement(multistatus, _qn('d', 'response'))
|
||||||
|
ET.SubElement(resp, _qn('d', 'href')).text = href
|
||||||
|
propstat = ET.SubElement(resp, _qn('d', 'propstat'))
|
||||||
|
prop = ET.SubElement(propstat, _qn('d', 'prop'))
|
||||||
|
# Echo back everything the client asked to set
|
||||||
|
for set_block in root.findall(_qn('d', 'set')):
|
||||||
|
inner_prop = set_block.find(_qn('d', 'prop'))
|
||||||
|
if inner_prop is not None:
|
||||||
|
for child in inner_prop:
|
||||||
|
ET.SubElement(prop, child.tag)
|
||||||
|
ET.SubElement(propstat, _qn('d', 'status')).text = 'HTTP/1.1 200 OK'
|
||||||
|
return _xml_response(multistatus)
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# MKCALENDAR (create a new calendar collection via the DAV URL)
|
# MKCALENDAR (create a new calendar collection via the DAV URL)
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue