Commit Graph
37 Commits
Author SHA1 Message Date
RXWatcherandClaude Opus 4.7 fab95e291f feat(audiobooks): library-type recognizers for scanner dispatch
isAudiobookLibraryType and isPodcastLibraryType match singular and
plural forms case-insensitively, mirroring isMovieLibraryType. Used by
upcoming scanner walk branches (Task 4) that filter audio files into
audiobook and podcast libraries.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 13:50:46 +02:00
RXWatcherandClaude Opus 4.7 5f1ca3f825 feat(audiobooks): add audio-extension recognizer for scanner
Mirrors the existing videoExtensions/SupportsVideoFile pair. Used by
upcoming audiobook and podcast scanner branches to filter directory
walks.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 13:28:40 +02:00
RXWatcherandClaude Opus 4.7 da3d3198c8 feat(audiobooks): add Author and Narrator PersonKind constants
Discovery audit confirmed item_people.kind is unconstrained smallint
with values 1-6 in use. Reserve 7 = Author, 8 = Narrator for audiobook
people-links written by the upcoming scanner branches.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 13:26:38 +02:00
RXWatcherandClaude Opus 4.7 31704a2855 docs(audiobooks): implementation plan sub-plan 2 (scanner)
Second of six sub-plans. 10 tasks: PersonKind constants for Author and
Narrator, audio-extension recognizer, library-type helpers, a
walkLogicalTree refactor (movieLibrary bool -> typed walkMode), chapter
extraction via ffprobe, single-file and multi-file audiobook parsers,
scanner write path producing media_items.type='audiobook', and a
filesystem podcast parser (RSS deferred to sub-plan 5).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 13:25:49 +02:00
RXWatcherandClaude Opus 4.7 bc19ce34f6 style(audiobooks): cosmetic cleanups in scaffolded package
Two pre-emptive cleanups flagged by code review before sub-plan 2
copies the patterns:

  1. Sort the internal/audiobooks import after internal/adminjob in
     cmd/silo/main.go (alphabetical).
  2. Drop the redundant "audiobooks: " prefix from the Enabled() error
     wrap; matches how every other top-level service package
     (watchstate, scanqueue, metadata, etc.) formats errors.

No behavior change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 12:56:09 +02:00
RXWatcherandClaude Opus 4.7 e917d00d33 feat(audiobooks): scaffold internal/audiobooks package
Empty-but-compiling Service that reads the audiobooks.enabled feature
flag from server_settings. Wired into cmd/silo so the package is
referenced from the binary; no routes mounted, no scheduled tasks
registered, no DB writes. Subsequent sub-plans hang scanner branches,
ABS handlers, Socket.io, podcast refresher, and SPA pages off this
Service.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 12:51:07 +02:00
RXWatcherandClaude Opus 4.7 7011220d3b feat(audiobooks): migration 142 add audiobooks.enabled flag
Server-settings row that gates the absorbed audiobooks feature.
Defaults to 'false' so sub-plan 1 lands as a strict no-op; subsequent
sub-plans branch on this flag and operators flip it to 'true' at
cutover.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 12:27:40 +02:00
RXWatcherandClaude Opus 4.7 3da2b4d572 chore(audiobooks): migration 141 no-op for media_folders.type
Sub-plan 1 originally reserved migration 141 to add a 'kind' column to
media_libraries discriminating audiobook/podcast libraries. Discovery
audit (sub-plan 1 Task 1) found that the actual table is media_folders
and it already has a type text NOT NULL column with no CHECK constraint
or enum, so 'audiobooks' and 'podcasts' can be added as future values
without DDL.

Landing this migration as a documented no-op preserves the version
numbering audit trail and pins the decision in git history. The
matching down migration is also a no-op.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 12:21:53 +02:00
RXWatcherandClaude Opus 4.7 d9d92a0bab style(audiobooks): uppercase PRIMARY KEY in migration 140
Aligns with the codebase convention (type keywords lowercase,
constraint keywords uppercase) established in migration 139's
post-style-fix form. Cosmetic only — running schema is unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 12:19:36 +02:00
RXWatcherandClaude Opus 4.7 a947e28ad7 feat(audiobooks): migration 140 add podcast_feeds table
Side table on media_items for RSS-subscribed podcasts. Holds feed URL,
ETag/Last-Modified for conditional fetches, last-refresh timestamp, and
the per-feed refresh interval consumed by the upcoming
podcastfeed.Refresher scheduled task.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 12:13:56 +02:00
RXWatcherandClaude Opus 4.7 37f4bff45c style(audiobooks): match codebase conventions in migration 139
Lowercases type keywords in the abs_sessions CREATE TABLE body to
match neighboring migrations, fixes the client_version column
alignment, and replaces the misleading "parallel to
jellycompat_sessions" header comment with a more accurate
description of the table's role.

Cosmetic only — the running schema is unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 12:11:30 +02:00
RXWatcherandClaude Opus 4.7 b9951581a5 feat(audiobooks): migration 139 add abs_sessions table
Parallel of jellycompat_sessions for Audiobookshelf-compatible clients.
Lets ABS mobile/desktop apps maintain a device-bound session that
silo's audiobooks/abs handlers will validate.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 12:06:04 +02:00
RXWatcherandClaude Opus 4.7 ba457c04e5 docs(audiobooks): discovery findings for absorption sub-plan 1
Locks schema/code decisions for migrations 139-142 and downstream
sub-plans. Resolves open Risk questions from the absorption design spec.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 09:48:25 +02:00
RXWatcherandClaude Opus 4.7 1a0701f585 docs(audiobooks): implementation plan sub-plan 1 (discovery + schema)
First of six sub-plans for the absorption. Six tasks: a discovery
audit that resolves the spec's Risk questions, four idempotent SQL
migrations (abs_sessions, podcast_feeds, media_libraries.kind,
audiobooks.enabled feature flag), and an empty-but-compiling
internal/audiobooks package scaffolded into cmd/silo. Lands as a
strict no-op for users (feature flag defaults to false).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 09:43:08 +02:00
RXWatcherandClaude Opus 4.7 1ad020f1e6 docs(audiobooks): design spec for plugin absorption
Plan to absorb silo-plugin-audiobooks into silo-server as a first-party
feature. Audiobooks land in silo's existing SPA; ABS clients connect
directly. Hard constraints: reuse existing tables (media_items,
media_files, user_watch_progress, user_playback_sessions, people,
item_people, library_collections); only two new tables (abs_sessions,
podcast_feeds) and at most one column add (media_libraries.kind);
silo's main :8080 listener handles ABS Socket.io natively. Out of
scope: audiobook requests flow, smart collections, share links,
external recommender, custom metadata providers, separate audiobook
SPA.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 09:43:08 +02:00
RXWatcherandClaude Opus 4.7 8d01dad757 fix(api): allow HEAD on /api/v1/direct-download
Firefox (and some download managers) issue a HEAD request before
starting a download. The route only registered GET, so HEAD returned
405 Method Not Allowed and the browser aborted the download.

Mirrors the pattern already used by /stream/{session_id}, which
registers both GET and HEAD on the same handler. ServeDirect is built
on http.ServeContent / ServeFile, which natively handle HEAD by
writing headers without a body, so no handler changes are needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 08:57:42 +02:00
QuickandGitHub e574b6b649 Merge pull request #4 from Silo-Server/t3code/pg-fts-numerals
feat(catalog): normalize number words in title search
2026-05-24 01:21:07 -04:00
Silo Server Migration a608f28836 feat(catalog): normalize number words in title search
- Map number words and ordinals (e.g. "Two"/"2nd") to digit tokens in both SQL normalize_search_text and the Go mirror so "Dune: Part Two" and "Dune Part 2" match
- Rebuild title_normalized generated column and title FTS GIN indexes (migration 138)
2026-05-24 01:14:39 -04:00
QuickandGitHub cdf5fe3a50 Merge pull request #3 from Silo-Server/t3code/ef35ed7f
Rename webhook sync actors to profile mappings
2026-05-24 00:55:41 -04:00
QuickandGitHub c2ddeb45f4 Merge pull request #2 from Silo-Server/t3code/8d852355
Add online recap and preview marker support
2026-05-24 00:49:42 -04:00
Silo Server Migration cc2f016464 Reconcile playback versions after realtime reconnect
- Track realtime connection state from the video player
- Refresh watch detail versions once the session reconnects
2026-05-24 00:47:47 -04:00
Silo Server Migration 669be3a2b4 Rename recap preview marker migrations
- Move migration pair to 137 to keep numbering aligned
- Preserve the existing recap preview marker schema change
2026-05-24 00:26:29 -04:00
Silo Server Migration b1f2d164ac Add live introdb key reload and recap playback markers
- reload introdb API key on setting updates
- support recap/preview markers in playback and next-episode flow
- add profile defaults for recap and preview auto-play settings
2026-05-24 00:14:17 -04:00
Silo Server Migration f1e82f1eec Rename webhook sync actors to profile mappings
- Rename actor-oriented API, storage, and webhook fields to user/profile terminology
- Switch dev compose helpers to use docker-compose.yml
- Update frontend types and webhook sync settings for the new endpoints
2026-05-24 00:04:25 -04:00
Silo Server Migration ea92f7a311 Add online marker support for recap and preview segments
- Wire introdb marker fetching into playback and Jellyfin compat
- Persist and expose recap/preview markers alongside intro and credits
- Add new playback/profile settings for recap and preview behavior
2026-05-23 23:48:25 -04:00
QuickandGitHub 12fe7cab19 Merge pull request #1 from Silo-Server/codex/collections-template-port
Add poster-aware collection templates and async sync queueing
2026-05-23 21:41:13 -04:00
Silo Server Migration 0719f8d28d Preserve collection apply progress until completion
- Keep the last reported template bundle apply progress on success and failure
- Poll admin collection apply jobs every 5 seconds in the UI
2026-05-23 21:36:41 -04:00
Silo Server Migration 08fff4db68 Handle bundled collection poster failures gracefully
- Log poster store/update failures instead of aborting collection sync
- Preallocate matched collection replacements using the active limit
2026-05-23 21:32:22 -04:00
Silo Server Migration bad0a3d74a Queue template bundle applies in background
- Add admin job support for collection defaults applies
- Keep preview synchronous while real applies run via the job queue
- Show collection apply job status in the admin UI
2026-05-23 21:19:33 -04:00
Silo Server Migration 01b9709e4f Port collection templates to bundled poster storage
- Store bundled template posters in public S3 when available
- Presign imported user collection posters in API responses
- Thread frontend assets into router and collection handlers
2026-05-23 20:26:05 -04:00
Silo Server Migration 70b8f6ca2c fix(collections): address template sync review comments 2026-05-23 17:43:35 -04:00
Silo Server Migration 841e63e88b Track template poster origin in collection sync
- add poster_from_template to collection records and update flows
- preserve template-applied posters while keeping admin uploads sticky
- improve template bundle sync/status reporting and MDBList limit handling
2026-05-23 14:19:04 -04:00
Silo Server Migration 3eddacfe88 Port collection templates with poster support and async syncs
- Add poster URLs through collection import and template apply flows
- Queue large template bundle syncs and preserve existing collection posters
- Update template bundle assets, docs, and limit handling
2026-05-23 12:31:08 -04:00
4a88c5ac44 fix(collections): propagate template DefaultSortOrder to created collection
Agent F's code review surfaced a critical gap: every Phase 1-3 template
ships a non-zero `DefaultSortOrder` in the documented PMM-style bands
(1000s charts, 2000s best-of-year, 3000s awards, 4000s streaming,
5000s popular by genre, 6000s top rated by genre, 7000s franchises,
8000s seasonal, 9000s misc/kids) and the test suite pins those values,
but none of the four `createCollectionFromTemplate` dispatch paths
forwarded the rank into `catalog.CreateLibraryCollectionInput.SortOrder`.
Applying any template — bundled or one-off — landed the new collection at
SortOrder 0, defeating the band scheme entirely.

Fix: add `SortOrder int` to each request struct
(`importMDBListRequest`, `importTMDBRequest`, `importTMDBFranchiseRequest`,
`importTMDBDiscoverRequest`) and forward `tmpl.DefaultSortOrder` →
`req.SortOrder` → `CreateLibraryCollectionInput.SortOrder` end-to-end.

The pre-existing `SourceTrakt` path is unchanged — no Trakt template
currently sets a non-zero `DefaultSortOrder` so the gap is dormant
there; revisit if/when a Trakt template needs ordering.

No new unit test: the fix is a per-struct field forward whose
end-to-end exercise requires the live repository. Adding a fake repo
to test the propagation would be a refactor beyond this fix's scope.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 23:53:43 -04:00
QuickandSilo Server Migration 6ee6ba7226 feat(collections): add tmdb_collection franchise templates
Phase-3 of the collection-templates expansion. Adds ten curated movie
franchises plus a generic placeholder template, all backed by Agent B's
tmdb_collection source. Templates land in the 7000s sort-order band.

Verified TMDB collection IDs (via api.themoviedb.org/3/collection/{id}):
  - 10        Star Wars Collection (9 films)
  - 645       James Bond Collection (25 films)
  - 1241      Harry Potter Collection (8 films) — used for "Wizarding World"
  - 9485      The Fast and the Furious Collection (12 films)
  - 119       The Lord of the Rings Collection (3 films)
  - 121938    The Hobbit Collection (3 films)
  - 328       Jurassic Park Collection (7 films)
  - 295       Pirates of the Caribbean Collection (5 films)
  - 87359     Mission: Impossible Collection (8 films)
  - 535313    Godzilla Collection (3 films) — used for "MonsterVerse"

Plan corrections / skips:
  - MCU (plan ID 86311) resolves to "The Avengers Collection" (6 films),
    not the full Marvel Cinematic Universe. TMDB has no umbrella MCU
    collection. Skipped per the no-invent-IDs rule. Sort slot 7001 left
    open.
  - DC Extended Universe (plan ID 573436) resolves to "Spider-Man:
    Spider-Verse Collection" — unrelated. No DCEU umbrella exists on
    TMDB. Skipped. Sort slot 7005 left open.
  - Wizarding World (plan ID 1241) is TMDB's Harry Potter octalogy;
    Fantastic Beasts lives in a separate collection (435259). Used as-is
    with description noting the scope.
  - MonsterVerse (plan ID 535313) is labelled "Godzilla Collection" but
    contains the three Legendary MonsterVerse Godzilla films, which is
    the closest TMDB representation. Used as-is.

The placeholder template ships with CollectionID=0 and an empty sync
schedule so it can be applied without a valid franchise ID; admins edit
the resulting collection's source_config before the first sync.
2026-05-22 23:53:43 -04:00
df5e427232 feat(collections): add tmdb_discover genre templates
Append the Phase-2 catalog from the collection-templates expansion plan:

- 18 Popular by Genre (sort_order 5001..5018, daily 0 4 * * *,
  popularity.desc with vote_count_gte=300)
- 18 Top Rated by Genre (sort_order 6001..6018, weekly 0 5 * * 0,
  vote_average.desc with vote_count_gte=1000)
- 1 Kids Movies (sort_order 9050, weekly, Family genre with
  certification_lte=PG)

Adds TestPhase2DiscoverTemplatesUseExpectedBands to pin the band ranges
and the TMDB query parameters that define each section.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 23:53:43 -04:00
Silo Server Migration c085b12fd1 Initial Silo migration 2026-05-22 23:26:56 -04:00