Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions docs-developers/architecture/cross-repo-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,10 @@ Since podcasts are shown only to an identified 2.2.0 or later player, the
cross-origin dev loop shows none unless a development build opts in with
`EXPO_PUBLIC_IDENTIFY_CROSS_ORIGIN=1` (never in a production build).

For an allowed origin the server also allows `Range` and exposes
`Retry-After` and the OPML export's `X-OPML-*` counts (Phase 2d-2), with what
an older server means for the player: [CORS](../server/api/index.md#cors).

**A change requires:** nothing structural - just remember self-signed TLS (the
server default) needs trusting in the browser, or use `AUDIOSILO_TLS_MODE=off`
for plain-HTTP local dev.
Expand Down Expand Up @@ -823,7 +827,8 @@ security-critical: allowed and denied tests on the server.

Phase 2c-2 extends the server/Bridge seam with episodes on disk, retention
and on-demand fetching/status/Retry. Phase 2d-1 ships the player's views to
players from 2.2.0; discovery and OPML in the player are Phase 2d-2.
players from 2.2.0; Phase 2d-2 adds discovery, follow by URL, OPML and Check
for new episodes to the player.
See [Podcasts](../bridge/podcasts.md) and the
[API reference](../server/api/reference.md#podcasts) for exact fields.

Expand Down Expand Up @@ -976,9 +981,13 @@ See [Podcasts](../bridge/podcasts.md) and the
counts omissions in `X-OPML-Exported` / `X-OPML-Omitted-Private` /
`X-OPML-Omitted-Unavailable`. An open subscribe is reused only at the same
privacy (`409 privacy_conflict`). Optional flags `podcast_discovery` and
`podcast_opml`; exact shapes and the player rules are in the
[2d-2 handoff](../bridge/podcasts.md#player-handoff-discovery-and-opml-phase-2d-2-not-implemented)
and the [reference](../server/api/reference.md#podcast-discovery).
`podcast_opml`; exact shapes and the player's rules (search on submit,
artwork through the proxy only, the import waves, export with the
`Authorization` header) are in
[Player: discovery and OPML](../bridge/podcasts.md#player-discovery-and-opml-phase-2d-2)
and the [reference](../server/api/reference.md#podcast-discovery). CORS
exposes `Retry-After` and the `X-OPML-*` counts and allows `Range` for an
allowed origin ([CORS](../server/api/index.md#cors)).
- **CHAP:** the [sidecar](../bridge/attachments.md#podcast-chap-attachments)
is a version-1 stem-prefixed `chapters.json` using `from:id3_chap`, Fetch timestamp and one matching
basename/size/duration. No ASR/agent/generated flag; server consumes valid
Expand Down
6 changes: 4 additions & 2 deletions docs-developers/bridge/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ reserved download slot for play requests. **Phase 2c-3** adds server-side
podcast [directory search and OPML import/export](podcasts.md#discovery-and-opml-transfer)
with no Bridge change. **Phase 2d-1** adds the player's
[podcast views](podcasts.md#player-phase-2d-1) (players from 2.2.0), again
with no Bridge change. Discovery and OPML in the player (Phase 2d-2), read-along,
Audible backups and file moves arrive later.
with no Bridge change, and **Phase 2d-2** its
[discovery, follow by URL and OPML screens](podcasts.md#player-discovery-and-opml-phase-2d-2)
(a CORS change on the server only). Read-along, Audible backups and file moves
arrive later.
:::

## What it is for
Expand Down
278 changes: 170 additions & 108 deletions docs-developers/bridge/podcasts.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions docs-developers/contributing/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ mappings:
| Community chapters (`internal/chapteralign`, `internal/chaptercheck`, `catalog/communitychapters.go`, the Chapters card's panel) | [server/community-chapters.md](../server/community-chapters.md) + the Community chapters section of `/users/admin/books` (and `/users/admin/health` for the Health rows) |
| Auth, invites, shares | [server/auth-and-security.md](../server/auth-and-security.md) + `/users/admin/users-and-invites`, `/users/admin/sharing` |
| The Bridge: the server's side (`auth/bridge.go`, `internal/bridge`, `handlers_bridge.go`, `handlers_bridge_estimate.go`, the `bridge` capability, the console's `features/bridge/`) or `audiosilo-bridge` (its config, images, compose example, mapping checks, job runner, page, the agent container and its credential hand-off, `sidecars.generate`, `sidecars.describe`, `sidecars.contribute`, `meta.correct`, the setup checklist, the Accounts tab and its GitHub sign-in) | [the Bridge developer pages](../bridge/index.md) (index, pairing and jobs, mappings, characters and recaps, the .audiosilo folder, the agent container, contributions, configuration, development) + the [reference](../server/api/reference.md#the-bridge) + [api/index.md](../server/api/index.md#capability-flags---gate-your-features) (the capability, the codes, the bridge token) + [auth-and-security.md](../server/auth-and-security.md#bridge-tokens) + [data-model.md](../server/data-model.md#the-bridge) + [backups-and-notifications.md](../server/backups-and-notifications.md#events) (the `bridge_job_*` events) + [web-ui.md](../server/web-ui.md) (the console's Settings > Bridge and the book page's Bridge parts) + the [cross-repo contract](../architecture/cross-repo-contract.md#16-the-bridge) (after the workspace `CROSS-REPO.md` §23) + `/users/admin/bridge`, `/users/admin/generating-characters-and-recaps`, `/users/getting-started/running-a-bridge` (its steps follow the setup checklist's order), `/users/getting-started/bridge-accounts` and `/users/community/contributing-from-your-server` + [meta/contributing-data.md](../meta/contributing-data.md#issues-filed-through-the-audiosilo-app) (what the Bridge files, and how meta routes it) + the `admin/settings-bridge*.png`, `admin/bridge-setup.png`, `admin/bridge-pair.png`, `admin/book-generate.png`, `admin/generate-dialog.png` and `admin/book-description.png` screenshots |
| Podcasts: library kind, `internal/podcast`, catalog/handlers, the Bridge's `podcastjob`, `netguard`, feed/Fetch files, downloads, on-demand/status/Retry and queue prefetch, listener fetch limits, claim priority/reserved capacity, retention aggregates/policies, generations/ETags, publication journals, CHAP or root markers; directory search and OPML (`internal/podcast/{discovery,opml,quota}`, `follow.go`, `opmlimport.go`, `export.go`, `podcasts.discovery.enabled`, the Podcast Index variables) | [bridge/podcasts.md](../bridge/podcasts.md) (with its [discovery and OPML](../bridge/podcasts.md#discovery-and-opml-transfer) section, its [player](../bridge/podcasts.md#player-phase-2d-1) section and the 2d-2 handoff) + [server/modules.md](../server/modules.md), [configuration.md](../server/configuration.md#managed-modules-modules) (and its [podcast discovery](../server/configuration.md#podcast-discovery-podcastsdiscovery) section), [API reference](../server/api/reference.md#podcasts) (including admin storage and Bridge retention), [API flags](../server/api/index.md#capability-flags---gate-your-features), [data-model.md](../server/data-model.md#podcasts), [scanner.md](../server/scanner.md#podcast-libraries), [auth-and-security.md](../server/auth-and-security.md#podcast-visibility), [bridge/configuration.md](../bridge/configuration.md#podcasts), [attachments.md](../bridge/attachments.md#podcast-chap-attachments), [mappings.md](../bridge/mappings.md#podcast-libraries-the-marker), [pairing-and-jobs.md](../bridge/pairing-and-jobs.md#podcast-jobs), [bridge/index.md](../bridge/index.md), [cross-repo-contract.md](../architecture/cross-repo-contract.md#17-podcast-shows-feeds-and-client-visibility) + `/users/admin/podcasts`, `/users/admin/libraries`, `/users/admin/bridge`, `/users/admin/server#modules`, `/users/getting-started/running-a-bridge`, `/users/faq` (what a directory search sends) + `admin/libraries.png`, `admin/library-add.png`, `admin/library-add-podcasts.png`, `admin/library-edit.png` and `admin/settings-modules.png` |
| The player's podcasts: `src/components/podcasts/`, `src/playback/episode-fetch.ts`, Home's New episodes (`new-episodes-*`, `use-new-episodes.ts`), the `shows` Library mode, `src/lib/library-kind.ts`, the podcast client gate (`auth.PodcastPlayerMinVersion`, `app.json` `expo.version`, `client-id.ts`), the gated whole-list replace (`catalog.GatedScopes`) | [frontend/podcasts.md](../frontend/podcasts.md) + [bridge/podcasts.md](../bridge/podcasts.md#player-phase-2d-1) (the wire and the controller's rules) + [auth-and-security.md](../server/auth-and-security.md#podcast-visibility) + the [reference](../server/api/reference.md#podcasts) (the gate, the replace rules) + [api/index.md](../server/api/index.md#client-identification-x-audiosilo-client) + the lines in [playback.md](../frontend/playback.md), [state-and-data.md](../frontend/state-and-data.md), [offline.md](../frontend/offline.md), [chromecast.md](../frontend/chromecast.md), [end-of-book.md](../frontend/end-of-book.md) and [kids-mode.md](../frontend/kids-mode.md) + `/users/listening/podcasts` (and the podcast lines in `browsing`, `up-next`, `end-of-book`, `offline-downloads`, `chromecast`, `kids-mode`, `mobile-apps`, `/users/troubleshooting`, `/users/admin/podcasts`) + the `web-player/library-shows.png`, `podcast-show.png`, `home-new-episodes.png`, `episode-fetching.png` and `phone-podcast-show.png` screenshots (the podcast seed in `run.sh`) |
| Podcasts: library kind, `internal/podcast`, catalog/handlers, the Bridge's `podcastjob`, `netguard`, feed/Fetch files, downloads, on-demand/status/Retry and queue prefetch, listener fetch limits, claim priority/reserved capacity, retention aggregates/policies, generations/ETags, publication journals, CHAP or root markers; directory search and OPML (`internal/podcast/{discovery,opml,quota}`, `follow.go`, `opmlimport.go`, `export.go`, `podcasts.discovery.enabled`, the Podcast Index variables) | [bridge/podcasts.md](../bridge/podcasts.md) (with its [discovery and OPML](../bridge/podcasts.md#discovery-and-opml-transfer) section, its [player](../bridge/podcasts.md#player-phase-2d-1) and [player discovery and OPML](../bridge/podcasts.md#player-discovery-and-opml-phase-2d-2) sections) + [server/modules.md](../server/modules.md), [configuration.md](../server/configuration.md#managed-modules-modules) (and its [podcast discovery](../server/configuration.md#podcast-discovery-podcastsdiscovery) section), [API reference](../server/api/reference.md#podcasts) (including admin storage and Bridge retention), [API flags](../server/api/index.md#capability-flags---gate-your-features), [data-model.md](../server/data-model.md#podcasts), [scanner.md](../server/scanner.md#podcast-libraries), [auth-and-security.md](../server/auth-and-security.md#podcast-visibility), [bridge/configuration.md](../bridge/configuration.md#podcasts), [attachments.md](../bridge/attachments.md#podcast-chap-attachments), [mappings.md](../bridge/mappings.md#podcast-libraries-the-marker), [pairing-and-jobs.md](../bridge/pairing-and-jobs.md#podcast-jobs), [bridge/index.md](../bridge/index.md), [cross-repo-contract.md](../architecture/cross-repo-contract.md#17-podcast-shows-feeds-and-client-visibility) + `/users/admin/podcasts`, `/users/admin/libraries`, `/users/admin/bridge`, `/users/admin/server#modules`, `/users/getting-started/running-a-bridge`, `/users/faq` (what a directory search sends) + `admin/libraries.png`, `admin/library-add.png`, `admin/library-add-podcasts.png`, `admin/library-edit.png` and `admin/settings-modules.png` |
| The player's podcasts: `src/components/podcasts/`, `src/playback/episode-fetch.ts`, Home's New episodes (`new-episodes-*`, `use-new-episodes.ts`), the `shows` Library mode, `src/lib/library-kind.ts`, the podcast client gate (`auth.PodcastPlayerMinVersion`, `app.json` `expo.version`, `client-id.ts`), the gated whole-list replace (`catalog.GatedScopes`); finding shows (`find-shows-*`, `directory-search.tsx`, `discovery-*`, `follow-by-url.tsx`, `follow-requests.tsx`, `opml-*`, `use-opml-import.ts`, `shows-actions.tsx`, `check-episodes-button.tsx`, `artwork-retry.ts`, `src/lib/podcast-requests.ts`, `findShowsHref`, the `podcast_discovery` / `podcast_opml` client methods and hooks), the server's CORS lists (`corsAllowHeaders`, `corsExposeHeaders`) | [frontend/podcasts.md](../frontend/podcasts.md) (and its [Finding shows](../frontend/podcasts.md#finding-shows)) + [bridge/podcasts.md](../bridge/podcasts.md#player-phase-2d-1) (the wire and the controller's rules; [discovery and OPML](../bridge/podcasts.md#player-discovery-and-opml-phase-2d-2) for 2d-2) + [api/index.md CORS](../server/api/index.md#cors) and [cross-repo-contract.md §12](../architecture/cross-repo-contract.md#12-cors-for-web-development) + [auth-and-security.md](../server/auth-and-security.md#podcast-visibility) + the [reference](../server/api/reference.md#podcasts) (the gate, the replace rules) + [api/index.md](../server/api/index.md#client-identification-x-audiosilo-client) + the lines in [playback.md](../frontend/playback.md), [state-and-data.md](../frontend/state-and-data.md), [offline.md](../frontend/offline.md), [chromecast.md](../frontend/chromecast.md), [end-of-book.md](../frontend/end-of-book.md) and [kids-mode.md](../frontend/kids-mode.md) + `/users/listening/podcasts` (and the podcast lines in `browsing`, `up-next`, `end-of-book`, `offline-downloads`, `chromecast`, `kids-mode`, `mobile-apps`, `/users/troubleshooting`, `/users/admin/podcasts`, `/users/admin/server#modules`, `/users/faq`) + the `web-player/library-shows.png`, `podcast-show.png`, `home-new-episodes.png`, `episode-fetching.png`, `phone-podcast-show.png`, `find-shows-search.png`, `find-shows-address.png`, `find-shows-import.png` and `phone-find-shows.png` screenshots (the podcast seed in `run.sh` and its `directory` fixture; Find shows' stand-in routes in `capture-web.mjs`) |
| Managed modules: the server's `internal/modules` (its `Runner`, the `builtin` registry), `api/modules.go`, a `modules.<id>` setting, the console's Settings > Modules (`features/settings/modules-topic.tsx`), the player's `src/modules/` registry and slots | [server/modules.md](../server/modules.md) (+ the adding-a-module steps) + [configuration.md](../server/configuration.md#managed-modules-modules) (the key, the variable, the runtime table) + the [reference](../server/api/reference.md#get-apiv1adminmodules) (`GET /admin/modules`, the settings envelope's `modules`, the module's flag on `GET /server`, the module's Bridge jobs) + [api/index.md](../server/api/index.md#capability-flags---gate-your-features) (the flag, `module_off`, `kid_account`, `demo_account`) + [bridge/pairing-and-jobs.md](../bridge/pairing-and-jobs.md#jobs-of-a-managed-module) (the jobs a module owns, held while it is off) + [web-ui.md](../server/web-ui.md) + [frontend/state-and-data.md](../frontend/state-and-data.md#player-modules-srcmodules) + the [cross-repo contract](../architecture/cross-repo-contract.md#8-capability-flags-get-apiv1server) + `/users/admin/server#modules` (the console's Learn more link opens it: keep the heading) + `/users/admin/bridge#when-the-contributions-module-is-off` + the `admin/settings-modules.png` screenshot |
| Chapterless books: the Bridge's `internal/chapterdetect`, `chapter_detecting`, the windows manifest, `chapters.detect`; the server's `metadata/chapterlist.go`, `catalog/generatedchapters.go`, the console's Detect chapters (`health/detect-chapters-dialog.tsx`) and the Chapters card's source control; the player's generated caption | [bridge/chapters.md](../bridge/chapters.md) + [bridge/attachments.md](../bridge/attachments.md#chaptersjson) + [bridge/pairing-and-jobs.md](../bridge/pairing-and-jobs.md#kinds-are-allow-listed-twice) (the kinds table) + [server/community-chapters.md](../server/community-chapters.md#generated-chapters) + the [reference](../server/api/reference.md#post-apiv1adminbridgejobs) (`chapters_source`, `chapter_choice`, `generated_chapters_fit`, the `409` codes) + [api/index.md](../server/api/index.md#capability-flags---gate-your-features) (the `chapters` feature, the codes) + [data-model.md](../server/data-model.md) + [backups-and-notifications.md](../server/backups-and-notifications.md#events) (`chapters_source` on the event) + [web-ui.md](../server/web-ui.md) (Health, the Chapters card) + [frontend/book-page.md](../frontend/book-page.md#the-chapters-tab) (the caption) + `/users/admin/generating-characters-and-recaps#books-without-chapters`, `/users/admin/health`, `/users/admin/books#chapters-found-in-the-narration`, `/users/listening/book-page#chapters` + the `admin/health-detect-chapters.png`, `admin/detect-chapters-dialog.png` and `admin/book-chapters-generated.png` screenshots |
| Generated characters, recaps and descriptions: `.audiosilo/` (the server's `library/attachments.go`, `metadata/attachments.go`, `catalog/attachments.go`, `meta/generated.go`; the Bridge's `internal/generate`, `internal/pipeline/describe_stage.go`), the console's Description part (`describe-section.tsx`) or the player's generate action, mark and About (`src/components/bridge/`, `GeneratedMark`, `aboutContent`) | [bridge/attachments.md](../bridge/attachments.md) + [bridge/generating.md](../bridge/generating.md) + [server/scanner.md](../server/scanner.md#the-bridges-attachments) + the `/meta` [generated content](../server/api/reference.md#generated-content) + [frontend/book-page.md](../frontend/book-page.md#the-primary-action-and-the-action-row) (and its About) + `/users/admin/generating-characters-and-recaps`, `/users/listening/recaps-and-characters`, `/users/listening/book-page` (About) + the `admin/book-description.png` and `web-player/book-about-generated.png` screenshots |
Expand Down
Loading
Loading