Jellyfin sync only ingests played movies — shows never sync #30
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Reference
marvin8/xique#30
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
TV is wired end-to-end except at the one gate that matters: the Jellyfin delta sync only requests played movies, so shows reach the ledger solely through a Trakt export import. A user who connects Jellyfin and skips the Trakt bootstrap gets an empty /shows page and no TV recommendations, because the engine has no show seeds to fan out from.
Everything downstream already handles shows: the media table carries a show media type, the engine ranks core_tv and discover_tv categories, the TMDB client speaks /tv, and the browse UI has /shows and /discover pages. The sync is the only movie-only piece.
This is Phase 1 scope, not new work: the spec's Phase 1 sync bullet covers the played-items ledger generally, and the movie/TV browse lists were both Phase 1 deliverables. Episode-level tracking remains deliberately deferred (see #25); shows here means series-level, the same resolution a Trakt import produces.
Spec §8.1, §14 (Phase 1).
Implementation recon:
Seriesto the canonical"show"type, but every played-items fetch filters onMovieonly, so the sync never sees shows.DatePlayeddesc) and relies on the ledger's(user, media, watched_at, source)uniqueness for re-sync dedupe — no watermark machinery exists, and this change adds none.Plan of attack:
services/jellyfin.py:JellyfinEpisodeandJellyfinSeriesdataclasses;fetch_played_episodes(paged,IncludeItemTypes=Episode,IsPlayed,DatePlayeddesc);fetch_series(batchedids=lookup carrying ProviderIds, Genres, Overview, and UserData for the rating).services/sync.py:sync_jellyfin_shows— walk played episodes, group by parent series, fetch each distinct series once, upsert the show (keyable on tmdb/imdb/tvdb), mirror the series rating, append one watch event per played episode (source ref = episode item id, timestamp = that episode'sLastPlayedDate). Series whose metadata is missing or unkeyable are skipped without failing the pass.worker.py: thejellyfin_synchandler runs the movies pass and the shows pass, recording one shared sync result.TDD throughout: failing tests per slice (
test_jellyfin.py,test_sync.py, worker tests), then the implementation, then the fulluv run noxsuite before pushing.Branch:
feat/issue-30-jellyfin-show-syncCommits:
:sparkles: feat: fetch played episodes and series from the Jellyfin client:sparkles: feat: sync played Jellyfin shows into the ledgerPR:
POST /repos/marvin8/xique/pulls(headfeat/issue-30-jellyfin-show-sync, basemain,Closes #30).