Sync WebCal and CalDAV directly; add a skip_past cutoff
WebCal is calcalist's own (src/webcal.rs), with Calendar::split_by_uid to turn one feed document into one file per UID. Shared crate::http and crate::secret came out of google/ so every leg uses them. CalDAV follows, behind a per-endpoint 'native' flag so it can run beside pimsync one collection at a time: src/caldav/client.rs speaks PROPFIND, sync-collection, calendar-multiget and conditional PUT/DELETE, and src/caldav/mod.rs is the pull/push pair. Radicale answers an initial sync-collection with no members, so a cursor is only stored alongside a complete read. doctor reports what a server advertises. skip_past (src/horizon.rs) takes a date, not a flag: a rolling 'before now' would retire events from the aggregate as they aged, deleting yesterday's events on every cycle. Pinned to a date, what is mirrored stays mirrored. On the real configuration it leaves 2600 of 3282 events behind. The filter sits above the prior-links lookup in mirror_source, which is what makes it safe: from there DeleteSource is unreachable, so excluding an event can never be read as the user having deleted its mirror. pimsync: CWD pinned so vstorage's relative unlink cannot reach the user's files; the dry-run workspace is removed by Drop rather than by a line every '?' stepped over. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d03748472a
commit
622a71dcd6
28 changed files with 2717 additions and 188 deletions
30
CLAUDE.md
30
CLAUDE.md
|
|
@ -67,8 +67,32 @@ hand-editable artefact. Anything that writes it must preserve comments,
|
|||
ordering and omitted defaults — `toml::to_string` on the `Serialize` derive
|
||||
does none of those things.
|
||||
|
||||
**WebCal and Google are calcalist's own; CalDAV is being taken back too.** A
|
||||
feed is one iCalendar document fetched over HTTP and read-only by protocol, so
|
||||
routing it through a generated config, a subprocess and a status database bought
|
||||
nothing — it cost three minutes a cycle in observed stalls. CalDAV has followed,
|
||||
behind a per-endpoint `native` flag so the two run side by side until the
|
||||
native client has earned the default. The argument
|
||||
is not that pimsync is bad but that calcalist was paying for generality it never
|
||||
used: one server, against 528 lines of adapter, a 59.6 MB flake closure, an
|
||||
undocumented `discover` format that is scraped, a version range to maintain, and
|
||||
a `vstorage` bug that unlinked `order` relative to the working directory.
|
||||
|
||||
**Radicale is the CalDAV target; other servers are untested, not unsupported.**
|
||||
Narrowing is what makes owning the protocol reasonable: the integration tests
|
||||
already run against Radicale, so every assumption is checked on every
|
||||
`devbox run check`, and when the RFC is ambiguous its source settles it. The
|
||||
discipline that keeps this honest is that server-specific accommodations stay
|
||||
*named*, never absorbed into the general path — Radicale answers an initial
|
||||
`sync-collection` with a token and no members, which is written as "always load
|
||||
in full first, then go incremental", correct anywhere, rather than as a quirk
|
||||
worked around in place. `doctor` reports what a server advertises so that
|
||||
pointing calcalist elsewhere fails legibly.
|
||||
|
||||
## Known gap
|
||||
|
||||
A failing `pimsync sync` stops the whole CalDAV leg. Unlike the Google side this
|
||||
cannot be narrowed: pimsync is one process covering every pair, and a failure
|
||||
does not say which pair it belongs to.
|
||||
A failing `pimsync sync` stops every CalDAV endpoint pimsync still owns. It is
|
||||
one process covering every pair, and a failure does not say which pair it
|
||||
belongs to, so the endpoints cannot be told apart the way the Google ones are.
|
||||
`native = true` takes an endpoint out of its reach entirely, which is the way
|
||||
out rather than a narrowing of pimsync's own reporting.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue