From ed208d7120b6e6a7c2ce234504228b5a1ba48f11 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Tue, 5 May 2026 11:16:25 +0300 Subject: Update AGENTS.md with podcast support documentation --- AGENTS.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 855d7e8..a50ba5f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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. -- cgit v1.2.3