diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-05 11:16:25 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-05 11:16:25 +0300 |
| commit | ed208d7120b6e6a7c2ce234504228b5a1ba48f11 (patch) | |
| tree | ba3b79bca8cfaaba5d77697446a6f26f57c037eb | |
| parent | a7a346ef6018ec675c2256380f3f7758a24fc5ed (diff) | |
Update AGENTS.md with podcast support documentation
| -rw-r--r-- | AGENTS.md | 44 |
1 files changed, 44 insertions, 0 deletions
@@ -201,6 +201,50 @@ This triggers `FSScanner.Scan()`, which: --- +## Podcast Support + +Podcasts are **special sets** (`sets.is_podcast = 1`). They reuse set permissions, browsing, and cover images, while adding feed management and episode tracking. + +### Subscribing + +Admin opens the **Podcasts** button in the admin panel (or calls `POST /api/podcasts`): +- Submit an RSS/Atom feed URL and optional folder name. +- Server creates a set folder, parses the feed, downloads the cover image, and inserts episodes into `podcast_episodes`. + +### Episode Management + +Episodes are stored in `podcast_episodes` and rendered in the browse grid for podcast sets: +- **Undownloaded** episodes show a **Download to server** button (calls `POST /api/podcasts/episodes/{id}/download`). +- **Downloaded** episodes become regular `media` rows and appear as normal media cards. +- Users can mark episodes as listened/unlistened via the checkmark button. + +### Background Feed Checker + +A background goroutine (`CheckFeeds`) refreshes feeds every hour (configurable via `PODCAST_CHECK_INTERVAL_MINUTES`). It uses conditional GET (`If-None-Match`, `If-Modified-Since`) to avoid re-downloading unchanged feeds. + +### New Endpoints + +| Method | Path | Description | +|--------|------|-------------| +| `GET` | `/api/podcasts` | List podcast sets | +| `POST` | `/api/podcasts` | Subscribe to a new feed (admin) | +| `GET` | `/api/podcasts/{id}/episodes` | List episodes with status | +| `POST` | `/api/podcasts/episodes/{id}/download` | Server-side download | +| `POST` | `/api/podcasts/episodes/{id}/complete` | Toggle completion | + +### New Files + +- `internal/model/podcast.go` — PodcastFeed, PodcastEpisode, PodcastStatus +- `internal/repository/podcast.go` — CRUD and queries +- `internal/podcast/feed.go` — RSS/Atom parser using `gofeed` +- `internal/podcast/cover.go` — Cover image downloader +- `internal/service/podcast.go` — Business logic and background checker +- `internal/api/handlers_podcast.go` — REST handlers +- `internal/service/import.go` — Shared `ImportMediaFile` helper (used by uploads + downloader) +- `web/js/podcasts.js` — Feed manager modal and episode renderer + +--- + ## Notes for Agents - When modifying tests, always run `go test ./... -race -cover` before committing. |
