68 lines
3.6 KiB
Markdown
68 lines
3.6 KiB
Markdown
# trash-calendar
|
|
|
|
Mirrors Kennelbach's trash/recycling collection dates into the household's own
|
|
Nextcloud calendar, from [Phase 19 of the project plan](../docs/project-plan.md).
|
|
|
|
**Not a new trash-schedule data source** — Kennelbach's own site (kennelbach.at) and
|
|
Vorarlberg's Umweltverband (umweltv.at) already publish a personal, address-specific
|
|
ICS feed of your collection dates; this repo doesn't scrape or re-derive that. What's
|
|
missing without this tool is getting those dates into the **same** calendar the
|
|
household already looks at (the one `digest-engine/ingest/caldav.py` already reads
|
|
from) instead of a second app/URL nobody checks.
|
|
|
|
## How it works
|
|
|
|
1. Download the household's real personal ICS feed URL (see
|
|
`trash-calendar.env.example` for where to get it — it's address-specific, this
|
|
repo can't hardcode it).
|
|
2. `sync.py` downloads and parses that feed, keeps only events in the next
|
|
`WASTE_LOOKAHEAD_DAYS` (default 60).
|
|
3. For each one, it checks whether an event with a deterministic UID
|
|
(`smartesthome-trash-<hash of summary+date>`) already exists in
|
|
`CALDAV_TARGET_CALENDAR`; if not, it creates it. **It never updates or deletes
|
|
anything** — a re-run that finds nothing new touches nothing at all, and it never
|
|
reads or writes any event outside its own `smartesthome-trash-` prefix.
|
|
|
|
Oneshot + systemd timer (daily via `ENABLE_TRASH_CALENDAR` in
|
|
`setup-container-host.sh`), not an always-on service — same shape as
|
|
`digest-engine`'s own scheduling.
|
|
|
|
## Why this isn't part of digest-engine
|
|
|
|
`digest-engine/ingest/caldav.py` has one documented invariant: it never mutates the
|
|
calendar it reads from (see that file's own docstring, "READ-ONLY INVARIANT"). Adding
|
|
a write path into the same component would either break that invariant or need a
|
|
confusing second mode. A separate, smaller tool that reuses the exact same
|
|
`CALDAV_URL`/`CALDAV_USERNAME`/`CALDAV_PASSWORD`/`CALDAV_VERIFY_TLS` credentials (one
|
|
Nextcloud app password, not two) keeps the "never mutates" guarantee real for the
|
|
digest while still solving the actual problem.
|
|
|
|
## Configure
|
|
|
|
```sh
|
|
cp trash-calendar/trash-calendar.env.example /opt/smart-home/trash-calendar/trash-calendar.env
|
|
chmod 600 /opt/smart-home/trash-calendar/trash-calendar.env
|
|
$EDITOR /opt/smart-home/trash-calendar/trash-calendar.env
|
|
```
|
|
|
|
`WASTE_ICS_URL` and `CALDAV_TARGET_CALENDAR` are both required and both
|
|
household-specific — see the template's own comments for where to get each.
|
|
|
|
## Manual verification still outstanding
|
|
|
|
1. **The exact "download/subscribe" UI on kennelbach.at's/umweltv.at's Abfallkalender
|
|
page** — confirmed these pages exist and serve a personal calendar (see
|
|
`docs/project-plan.md` §1.17's research note), but the precise click-path to an
|
|
ICS URL wasn't captured here; get it once, it should be a fixed URL after that.
|
|
2. Whether `calendar.event_by_uid()` on a real Nextcloud instance behaves the way
|
|
the `caldav` library's docs describe (raises when not found — caught here as
|
|
"doesn't exist yet, create it") — this exact call is already used read-side by
|
|
nothing in this repo, only written fresh here; unverified against a live server.
|
|
3. Whether Nextcloud's CalDAV endpoint accepts a bare `save_event()` with the
|
|
minimal VEVENT built here (no `DTEND`, all-day via `DTSTART;VALUE=DATE`) without
|
|
complaint — a deliberately minimal event, not tested against a real server.
|
|
4. Timezone/date-boundary edge cases right around midnight — `date.today()` uses the
|
|
container's own clock/timezone; confirm the container host's `TZ` is set
|
|
correctly (`setup-container-host.sh`'s own `TIMEZONE` variable already threads
|
|
through to every other container, this one included).
|