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>
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>
* 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>
Bisher war der href in der Response immer /dav/, auch wenn DAVx5
einen PROPFIND auf / oder /.well-known/caldav gemacht hat. Das
kann Clients verwirren - die erwarten, dass der Response-Pfad zum
angefragten Pfad passt. current-user-principal zeigt weiterhin
korrekt auf /dav/Adam/.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Aenderungen fuer besseren DAVx5-Support:
* /.well-known/caldav reagiert jetzt direkt auf PROPFIND/OPTIONS
ohne Redirect-Zickerei. GET/HEAD redirecten weiterhin auf /dav/
als visuelle Fallback.
* strict_slashes app-weit aus: /dav und /dav/ sind gleichwertig,
ebenso die Unterpfade. DAVx5 nutzt beides gemischt.
* Jede DAV-Response traegt jetzt den DAV-Header (1, 2, 3,
calendar-access), nicht nur OPTIONS.
* Kalender-Response enthaelt jetzt supported-report-set mit
calendar-query + calendar-multiget (DAVx5 prueft das).
* current-user-privilege-set wird mit konkreten Privilegien gefuellt
(read, write, write-properties, write-content, bind, unbind)
statt leer.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Property-Elemente wurden unter einem Container mit demselben Tag
erzeugt, z.B.:
<current-user-principal>
<current-user-principal> <!-- falsch, doppelt -->
<href>/dav/adam/</href>
</current-user-principal>
</current-user-principal>
Clients wie DAVx5 und Thunderbird erkennen dadurch den Principal
nicht und melden "Kein CalDAV-Dienst gefunden". XML-Generierung
umgebaut - Response-Helfer bekommen jetzt eine populate_prop-
Callback, die die tatsaechlichen Property-Children direkt ins
<prop>-Element setzt.
Zusaetzlich:
* /.well-known/caldav und /carddav akzeptieren jetzt auch PROPFIND,
OPTIONS, HEAD (einige Clients halten die Methode beim ersten
Aufruf bei).
* Kalender-Response enthaelt current-user-privilege-set (leer, als
Signal dass der Client nicht ACL-abhaengig pruefen muss).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Vollstaendige CalDAV-Implementierung unter /dav/ - Thunderbird,
DAVx5, Apple Calendar und Outlook (CalDAV-Synchronizer) koennen
sich einfach ueber HTTP-Basic-Auth mit ihrem Mini-Cloud-Account
anmelden und ihre Kalender synchronisieren.
Unterstuetzte Methoden:
* OPTIONS - DAV-Capabilities
* PROPFIND - Discovery, Principal, Calendar-Home, Kalender,
Termin-Listings (Depth 0/1 beachtet)
* REPORT - calendar-query + calendar-multiget mit
optionalem Zeitraumfilter (<time-range>)
* GET - einzelner Termin als VCALENDAR
* PUT - Termin erstellen/aktualisieren (mit ETag-Check
via If-Match + If-None-Match)
* DELETE - Termin oder ganzer Kalender
* MKCALENDAR - neuen Kalender vom Client aus anlegen
iCal-Parser verarbeitet SUMMARY, DESCRIPTION, LOCATION, DTSTART,
DTEND, RRULE, EXDATE - inklusive Line-Folding (RFC 5545).
Ganztages-Termine (VALUE=DATE) werden korrekt erkannt.
ETags basieren auf updated_at-Zeitstempel und werden pro
PUT-Response zurueckgegeben, damit Clients Konflikte erkennen.
nginx.example.conf: /dav/ mit proxy_request_buffering off fuer
groessere PUTs und Weiterleitung der .well-known-URLs.
README: eigener "CalDAV-Zugriff"-Block mit Tabelle pro Client.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>