Per-location alert feed (RSS / JSON / iCal) #75

Closed
opened 2026-07-18 05:31:37 +00:00 by claude-bot · 1 comment
Contributor

Public pages exist; a /p/{token}.json or RSS variant makes locations consumable by other homelab automations (Home Assistant!). Effort S, value M for the integration-minded.


Filed from the 2026-07-17 codebase audit (docs/.internal/report-2026-07-17.md), finding I-05.

Public pages exist; a `/p/{token}.json` or RSS variant makes locations consumable by other homelab automations (Home Assistant!). Effort S, value M for the integration-minded. --- _Filed from the 2026-07-17 codebase audit (`docs/.internal/report-2026-07-17.md`), finding I-05._
Author
Contributor

Done in #112 (merged). GET /p/{location_id}.json|.rss|.ics — JSON, RSS 2.0, and iCal feeds of a location's active alerts, gated by Location.public_enabled + the public rate limiter, exposing the same alert set as the public HTML page. Stdlib-only builders in services/feeds.py (proper XML escaping; RFC-5545 iCal escaping + line folding), no new deps. Routes are defined before the /p/{token} catch-all and the PublicToken alphabet has no dots, so there's no collision.

Implementation note: I used the location's own id as the feed token (mirroring the existing /api/locations/{id}/public page) rather than minting single-alert PublicTokens, since those map to one alert lifecycle each, not a whole-location feed.

Follow-up (not blocking): SentAlert has no onset/area_desc columns (they live on NWSAlertSnapshot), so the JSON exposes them as null and iCal DTSTART falls back to sent_at. A snapshot-join backfill would enrich the feeds (and pairs naturally with #84's lead-time work).

Done in #112 (merged). `GET /p/{location_id}.json|.rss|.ics` — JSON, RSS 2.0, and iCal feeds of a location's active alerts, gated by `Location.public_enabled` + the public rate limiter, exposing the same alert set as the public HTML page. Stdlib-only builders in `services/feeds.py` (proper XML escaping; RFC-5545 iCal escaping + line folding), no new deps. Routes are defined before the `/p/{token}` catch-all and the PublicToken alphabet has no dots, so there's no collision. Implementation note: I used the location's own `id` as the feed token (mirroring the existing `/api/locations/{id}/public` page) rather than minting single-alert `PublicToken`s, since those map to one alert lifecycle each, not a whole-location feed. Follow-up (not blocking): `SentAlert` has no `onset`/`area_desc` columns (they live on `NWSAlertSnapshot`), so the JSON exposes them as null and iCal `DTSTART` falls back to `sent_at`. A snapshot-join backfill would enrich the feeds (and pairs naturally with #84's lead-time work).
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/WeatherBot#75
No description provided.