-
released this
2026-08-09 09:53:14 -05:00 | 110 commits to main since this releaseAdded
-
Read-only iCalendar subscriptions (
ICS_FEEDS), fetched over HTTPS and merged into
the existing tools. A subscribed calendar is not stored in the iCloud account — every
device polls the URL independently — so CalDAV never returns one and noCALENDARS
value could ever reach it. That is why Apple's US Holidays was missing rather than
filtered: the account only ever offered six collections and it was not among them.
Feeds go through the sameexpand()as CalDAV data, so an occurrence from a
subscription is indistinguishable downstream, including recurrence and all-day
handling. Verified against Apple's realUS_en.ics: 45 events in 2026, July 4 spanning
exactly one day.Fetching the feed rather than importing it into a real calendar is the point — the file
currently runs to Dec 2029, and an import would quietly stop returning holidays when it
ran out, with nothing to say why.Failure modes here nearly all produce an empty calendar rather than an error, so each
is made loud: an undecoded gzip body (iCloud serves gzip whether asked or not), an HTML
error page served as 200, a body over 5 MB, a non-http(s)scheme (urlopenwill read
file://quite happily), and a feed that is simply unreachable — which reports the
calendar as unavailable rather than empty, and logs an advisory at boot.Not filtered by
CALENDARS: configuring a feed is already the act of opting in, and the
name is not knowable until after the first fetch. -
A
subscriptionspreflight check, present only when feeds are configured. Advisory
rather than fatal — a third-party URL being down is no reason to stop serving the
account's own calendars. -
The boot log now names the calendars the allowlist hid, not just how many.
skipped_by_allowlist=2answers "am I seeing everything?" with "no" and stops there,
and the only other way to learn the names was to run once withCALENDARSempty —
deliberately reading every subscribed collection on the account to find out which ones
to exclude. A calendar created on the phone now shows up in this line. -
A
CALENDARSentry that matches nothing is now warned about individually. The
existing warning only fired when every entry was wrong; one bad entry among several
good ones started cleanly and quietly never consulted that calendar, which is
indistinguishable from an empty calendar at the tool layer. The realistic cause is
emoji — a warning sign is two codepoints (U+26A0 U+FE0F) and the bare U+26A0 renders
identically without matching.
Fixed
- CI's
gatejob ran on Python 3.11 while the container runs 3.12, so nothing
exercised the interpreter production actually uses. It runs on 3.12 now, and
requires-pythonand mypy'spython_versionmoved to 3.12 to match — a floor nothing
tests is a claim nobody checks, and one version everywhere is simpler than two. The
package is not published anywhere, so nothing downstream cares about the floor.
Dropping the 3.11 leg also halves CI wall-clock: there is one shared runner, so matrix
legs ran sequentially rather than in parallel.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-