fix: CalDAV REPORT time-range - 500 wenn end fehlt
DAVx5 sendet bei calendar-query oft nur <time-range start=.../> ohne end. Mein Code hat dann blind CalendarEvent.dtstart < None gefiltert, was SQLAlchemy mit TypeError abbrechen liess - Ergebnis HTTP 500, Sync scheitert komplett. Zwei Korrekturen: * end-Filter wird nur gesetzt wenn end wirklich vorhanden ist * time-range-Parser strippt tzinfo, damit Vergleiche mit den tz-naiven DB-Spalten keine Exception werfen Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e7f469f477
commit
0edd41e46a
|
|
@ -343,11 +343,13 @@ def report(subpath):
|
|||
return _xml_response(multistatus)
|
||||
|
||||
if tag == _qn('c', 'calendar-query'):
|
||||
# Parse optional time-range
|
||||
# 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 start is not None:
|
||||
if end is not None:
|
||||
q = q.filter(CalendarEvent.dtstart < end)
|
||||
if start is not None:
|
||||
q = q.filter(
|
||||
(CalendarEvent.dtend >= start) | (CalendarEvent.dtstart >= start)
|
||||
| (CalendarEvent.recurrence_rule.isnot(None))
|
||||
|
|
@ -368,17 +370,22 @@ def _extract_time_range(root: ET.Element):
|
|||
if not s:
|
||||
return None
|
||||
s = s.replace('Z', '+00:00')
|
||||
dt = None
|
||||
try:
|
||||
return datetime.fromisoformat(s)
|
||||
except ValueError:
|
||||
# Compact ICS form: 20260412T120000Z
|
||||
try:
|
||||
return datetime.strptime(s, '%Y%m%dT%H%M%S%z')
|
||||
dt = datetime.fromisoformat(s)
|
||||
except ValueError:
|
||||
try:
|
||||
return datetime.strptime(s[:15], '%Y%m%dT%H%M%S').replace(tzinfo=timezone.utc)
|
||||
dt = datetime.strptime(s, '%Y%m%dT%H%M%S%z')
|
||||
except ValueError:
|
||||
try:
|
||||
dt = datetime.strptime(s[:15], '%Y%m%dT%H%M%S').replace(tzinfo=timezone.utc)
|
||||
except ValueError:
|
||||
return None
|
||||
# Unsere DB-Spalten sind tz-naive (lokal UTC) - Vergleich ginge
|
||||
# sonst mit TypeError. Also tz-Info abstreifen.
|
||||
if dt.tzinfo is not None:
|
||||
dt = dt.astimezone(timezone.utc).replace(tzinfo=None)
|
||||
return dt
|
||||
return parse(tr.get('start')), parse(tr.get('end'))
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue