Conversation
|
Validated at runtime, on top of the 29 entries recovered in one session, 0 unresolved. Every First candidate, as intended — the entry opens on the parent title with season 4 and its correct air Other franchise-IMDB recoveries in the same session: Two things the live run surfaced that the offline analysis had not: The fallback also recovers non-IMDB canonical IDs. Cinemeta has a second failure mode besides Full-suite state is unchanged from the PR description: |
|
Pushed a second commit — f61320b — after running this branch as a daily driver on Windows and finding that the fallback introduces a Continue Watching regression of its own. Better caught here than after merge. What went wrongTwo entries appeared under Next Up on Home for shows that were finished months or years ago:
Both offered episodes already watched, under a different Simkl entry. Why the fallback causes itBoth entries carry a season-specific IMDB ID and both are misses for Cinemeta, so both now reach
Each then resolves through the franchise IMDB ID its TVDB siblings carry ( The seed does not follow. Before this PR neither entry produced a card at all: the meta lookup failed, The fix
A candidate that reseeds onto nothing, or onto a season-zero special, is dropped rather than guessed at — the same rule Nothing changes when the addon serves the requested ID, which is every entry that resolved before the fallback existed. TestingReplay over the real library. Re-ran the Next Up pipeline over a 1284-entry Simkl snapshot with the live Cinemeta responses, before and after: The "before" run reproduces the two cards exactly as they appeared on the Home screen, down to the episode titles, which is what makes the "after" run meaningful. Unit: five tests in Full suite: Manual: Windows 11, local build of this branch installed over 1.1.20. Both cards are gone from Continue Watching; the rest of the rail is unchanged. ScopeThree files, +192/-6. Two of them are the same files this PR already touches. No dependency, UI, or architecture changes. |
A Simkl anime season can carry a season-specific IMDB ID that no installed meta addon indexes. Re:Zero season 4 is reported by Simkl as tt36501927, which Cinemeta answers with an empty object, so the Library entry cannot be opened at all: findMetaManifests only offers Cinemeta for a tt ID, and tryFetchTmdbFallbackMeta bails unless the ID starts with tmdb:. The IDs needed to recover are already known. Add alternateContentIdsFor(), which returns the other IDs the matching Simkl entry is known under, and consult it from MetaDetailsRepository only after every addon and the TMDB fallback have already missed. The normal path is untouched. Sibling IMDB IDs come first. Simkl models each anime season as its own entry but keeps the franchise TVDB ID on all of them, so the seasons sharing a parent IMDB ID identify that parent for the season that does not - four Re:Zero entries carry tt5607616 against one carrying tt36501927. Preferring those keeps Cinemeta as the metadata source, and with it correct episode air dates, which is also what the "Prefer IMDB" option already promises. The entry's own MAL/AniDB/AniList/Kitsu IDs follow as a last resort. Measured against a 1283-entry Simkl library: 43 entries could not be opened, 38 now resolve - 12 via the franchise IMDB ID, 26 via an anime ID. The remaining 5 are movies carrying only a TMDB ID, which need a configured TMDB key rather than a code change. Fixes NuvioMedia#457
The alternate-ID fallback added in the previous commit lets an entry whose own
ID no addon serves borrow a sibling's metadata. Home's Next Up then reads a
franchise episode list against a single arc's watch history, and offers an
episode the viewer already watched under a sibling entry.
Two Simkl anime entries carrying a season-specific IMDB ID reproduce it:
Demon Slayer: Entertainment District Arc tt15757634 TVDB S3E1-11
JoJo's Bizarre Adventure: Stardust Crusaders tt3687376 TVDB S2E1-24
Cinemeta answers tt15757634 with 200 {} and tt3687376 with a meta object that
has no name field, which MetaDetailsParser requires. Both are misses, so both
now fall back to the franchise IMDB ID their TVDB siblings carry - tt9335498
and tt2359704 - and come back with the whole franchise's episodes. The seed
stays the arc's own finale, because the sibling arcs' watched episodes are
recorded under the franchise ID, not this one. Next after S3E11 is S4E1
"Someone's Dream"; next after S2E24 is S2E25. Both already watched.
reanchorHomeNextUpCandidate() moves the candidate onto the ID the metadata
actually came from and recomputes the seed from that ID's history, so the
episode list and the history are read on one identity. It also collapses the
arc candidate onto the franchise's own candidate, so one series cannot produce
two cards. A candidate that reseeds onto nothing, or onto a season-zero
special, is dropped rather than guessed at - the same rule
buildHomeNextUpSeedCandidates already applies to its seeds.
Nothing changes when the addon serves the requested ID, which is every entry
that resolved before the fallback existed.
Replayed over a 1284-entry Simkl library with the real Cinemeta responses:
before, the two entries above produce exactly the cards seen on the Home
screen; after, Demon Slayer has no episode past its S5E8 seed and JoJo
collapses onto the franchise seed. Verified on Windows with a local build -
both cards are gone from Continue Watching.
Five tests in HomeScreenTest cover the reseeding, the untouched path, both
drop conditions, and the dismiss-key collapse. :composeApp:desktopTest is
796/796.
f61320b to
2cf5283
Compare
|
Not desktop-specific please move to NuvioMobile. |
Fixes #483.
Old behavior
SimklMedia.canonicalContentId()picks one ID and the meta lookup either resolves it or gives up.For anime under
Prefer IMDBthat ID is whateverimdbvalue Simkl attached to that entry.Broken behavior
Simkl gives some anime seasons their own IMDB title. Re:Zero season 4 is reported as
tt36501927,and Cinemeta answers
GET /meta/series/tt36501927.jsonwith200 {}. The entry then cannot beopened at all:
resolveMetaLookupIdreturns the ID unchanged — it only rewritestmdb:IDs.findMetaManifestsoffers only Cinemeta, since manifestidPrefixesfiltering excludes everyanime-ID addon for a
ttID.{}is correctly treated as a miss —MetaDetailsParserthrows andtryFetchMetareturns null — but there is nothing left to try.
tryFetchTmdbFallbackMetareturns null immediately:fetchStandaloneMetabails unless the IDstarts with
tmdb:.details_load_failed_all_addons.Meanwhile the same Simkl entry carries
mal:61316,anidb:19242,anilist:189046,kitsu:49746,and four sibling Re:Zero entries on the same TVDB series carry the parent
tt5607616— whichCinemeta serves with season 4 and correct air dates. None of it was consulted.
New behavior
SimklSyncSnapshot.alternateContentIdsFor(contentId)returns the other IDs the matching entry isknown under.
MetaDetailsRepositoryconsults it only after every addon and the TMDB fallback havealready missed, so the normal path is unchanged and costs nothing.
Sibling IMDB IDs are tried first, most common first. Simkl models each anime season as its own entry
but keeps the franchise TVDB ID on all of them, so the seasons that do share a parent IMDB ID
identify that parent for the season that does not. Preferring them keeps Cinemeta as the metadata
source — and with it correct episode air dates — instead of silently moving one title to a different
metadata provider. That is also what the
Prefer IMDBoption already describes: "Group animeseasons under a shared IMDB ID". The entry's own MAL/AniDB/AniList/Kitsu IDs follow as a last resort.
Reuses the existing
alternateContentIds(), which was already computed for watched-key emission; itonly changes from
privatetointernal.How this was tested
Unit: three tests in
SimklProjectionsTestcovering the real Re:Zero ID set — that the franchiseIMDB ID is returned and ordered ahead of the anime IDs, that anime IDs are still used when no sibling
shares the TVDB series, and that an unknown content ID yields nothing.
SimklProjectionsTestis14/14.
Full suite:
:composeApp:desktopTest— 790 tests, 1 failure inNativePlayerControllerTeardownTest.sourceGapsDisposeSuccessfulSupersededCreatesBeforeReplacementPublication,which reproduces identically on a clean checkout of
Devwith these changes stashed. Unrelated tothis PR.
Against a real library: replayed the resolution logic over a 1283-entry Simkl library
(1099 unique
(id, type)pairs) with Cinemeta and AIOStreams installed. 43 entries could not beopened before; 38 resolve after — 12 via the franchise IMDB ID, 26 via an anime ID. Full per-title
breakdown in #483. The 5 remaining are movies carrying only a TMDB ID, which need a configured TMDB
key rather than a code change.
Manually verified on Windows with a patched local build: the Re:Zero season 4 Library entry opens on
the parent title, which is also where Continue Watching already points and where that show's watch
history is stored.
Scope
Three files, +187/-2, no dependency, UI, or architecture changes. The new lookup runs only on the
path that previously ended in an error.
Second commit: reseed Next Up when an entry resolves through a sibling ID
Found by running this branch on Windows for a day. The fallback above turns a dead meta lookup into
a live one, and Home's Next Up was not ready for a candidate whose metadata belongs to a different
ID than its watch history. Two finished shows started offering episodes already watched:
tt15757634— Entertainment District Arctt3687376— Stardust CrusadersBoth entries are Cinemeta misses —
tt15757634answers200 {},tt3687376answers200with nonamefield, whichMetaDetailsParserrequires — so both reach the new fallback and resolve throughthe franchise IMDB ID their TVDB siblings carry. They come back with the whole franchise's episode
list, while
latestCompletedSeriesEpisodestill filters watch history by the candidate's own contentID, where only that arc's episodes are recorded:
reanchorHomeNextUpCandidate()moves the candidate onto the ID the metadata actually came from andrecomputes the seed from that ID's history, so both halves are read on one identity. It also
collapses the arc candidate onto the franchise's own candidate, so one series cannot produce two
cards. A candidate that reseeds onto nothing, or onto a season-zero special, is dropped rather than
guessed at — the same rule
buildHomeNextUpSeedCandidatesalready applies to its seeds. Nothingchanges when the addon serves the requested ID, which is every entry that resolved before this PR.
Tested by replaying the Next Up pipeline over the same 1284-entry library with the live Cinemeta
responses: the "before" run reproduces both cards exactly as they appeared on the Home screen, down
to the episode titles, and the "after" run produces neither. Five tests in
HomeScreenTestcover thereseeding, the untouched path, both drop conditions, and the dismiss-key collapse. Manually verified
on Windows 11 with a local build installed over 1.1.20 — both cards are gone from Continue Watching
and the rest of the rail is unchanged. Full reasoning and the replay output are in
this comment.
:composeApp:desktopTestfor the branch as a whole is now 796 tests, 0 failures — theNativePlayerControllerTeardownTestflake noted above did not reproduce.Three files, +192/-6, two of which this PR already touches.