Skip to content

fix: keep the monitored state when a season is partially downloaded - #32

Open
Raffa2001 wants to merge 2 commits into
varunaditya-plus:mainfrom
Raffa2001:fix-partial-season-monitored
Open

Raffa2001 wants to merge 2 commits into
varunaditya-plus:mainfrom
Raffa2001:fix-partial-season-monitored

Conversation

@Raffa2001

Copy link
Copy Markdown

Fixes #31.

The problem

Any TV request whose season is partially downloaded — the normal state of a
currently airing show — is shown as Missing (Unmonitored) on the Requests tab,
even when every episode is monitored in Sonarr.

ServarrProgressService.cs decides the label with this chain (lines ~330–348):

if (allUnreleased && !anyFile)      return ... // Unreleased
if (allHaveFiles && allMonitored)   return ... // Downloaded (Monitored)
if (allHaveFiles)                   return ... // Downloaded (Unmonitored)
if (!anyFile && anyMonitored)       return ... // Missing (Monitored)
return BuildLibraryProgress(false, false, ...); // Missing (Unmonitored)

There are branches for nothing downloaded and for everything downloaded, but
none for some episodes downloaded:

  • allHaveFiles is false → branches 2 and 3 are skipped
  • !anyFile is false → branch 4 is skipped, even when every episode is
    monitored

So it reaches the final return, which hardcodes monitored: false. The
label's second half is then simply untrue.

This is not about season scoping — FilterEpisodesBySeasons works correctly.
Verified below: restricting to the requested season changes the episode count
but not the outcome.

The change

-        return BuildLibraryProgress(false, false, false, 0, seriesOpenUrl);
+        return BuildLibraryProgress(false, anyMonitored, false, 0, seriesOpenUrl);

BuildLibraryProgress(hasFile: false, monitored: true, …) already renders
Missing (Monitored), so no new state is introduced and no other branch changes
behaviour — the earlier !anyFile && anyMonitored return covers the "nothing
downloaded yet" case identically.

Verified against

Request Episodes in requested season With a file Monitored Before After
Tomb Raider King — s1 12 4 10 Missing (Unmonitored) Missing (Monitored)
That Time I Got Reincarnated as a Slime — s4 24 4 10 Missing (Unmonitored) Missing (Monitored)

Numbers taken from GET /api/v3/episode?seriesId=N. In the second case the
season filter is demonstrably active — the requested season yields 24 episodes
where the whole series has 96 — and the label was unchanged, which is what rules
scoping out as the cause.

Environment: SeerrFin 1.6.6.0 · Jellyfin 10.11.11 · Sonarr 4.0.19.2979 ·
Jellyseerr 3.4.1.

Builds clean against JellyfinVersion=10.11.11 on .NET 9 — 0 warnings, 0 errors.

Possible follow-up (not in this PR)

A partially downloaded season could deserve its own state rather than sharing
Missing: the progress bar currently reads 0% while totalSize is already
known for the episodes that do have files, so it could show real progress.

Also worth knowing: Sonarr's series-level statistics.episodeFileCount counts
only monitored episodes — it reports 4/4 for the first case above while the
episode list reports 4 of 12. If that field is used anywhere the two numbers
will disagree in exactly this scenario.

The status chain in ServarrProgressService has branches for "nothing
downloaded" and "everything downloaded", but none for a season where some
episodes have files. Such a request matches neither `allHaveFiles` nor
`!anyFile`, so it reaches the final return, which hardcodes `monitored:
false` and renders "Missing (Unmonitored)" even when every episode is
monitored in Sonarr.

That is the normal state of any currently airing show, so the label was
effectively permanent for those requests.

Pass `anyMonitored` instead of the hardcoded `false`, so a partially
downloaded season that is still monitored reads "Missing (Monitored)".
No other branch changes behaviour: the earlier `!anyFile && anyMonitored`
return already covers the "nothing downloaded yet" case identically.
@varunaditya-plus

Copy link
Copy Markdown
Owner

Thank you for your contribution. The diagnosis is correct, but anyMonitored includes downloaded episodes.

  • Check whether any missing episode is monitored.
  • Confirm the intended UI: missing-monitored progress is currently removed before reaching the client.
  • Test monitored and unmonitored partial seasons.

After that, this should safely close #31.

…is monitored

Follow-up to the review: `anyMonitored` is true when *any* episode is
monitored, including ones that already have a file. For the "Missing
(Monitored)" label the monitoring that matters is the monitoring of the
episodes that are actually missing, so a season whose downloaded episodes are
monitored but whose missing ones are not was about to be mislabelled the other
way round.

Introduce `anyMissingMonitored`, restricted to episodes without a file, and use
it in the final return. The earlier `!anyFile && anyMonitored` branch is left
untouched on purpose: when nothing has a file every episode is missing, so the
two predicates are equivalent there and changing it would only add noise.

Verified on a live library: 18 partially downloaded seasons, of which 2 are
exactly the case the review describes (downloaded episodes monitored, missing
ones not). Those two keep "Missing (Unmonitored)" with this change and would
have flipped to "Monitored" without it.

Builds clean on the branch: 0 warnings, 0 errors.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Raffa2001

Copy link
Copy Markdown
Author

Thanks for the review — you were right on all three points. Revised commit pushed (4bf6f25).

1. Monitoring restricted to the missing episodes

bool anyMissingMonitored = episodes.Any(e => e.Value<bool?>("hasFile") != true
                                          && e.Value<bool?>("monitored") == true);

used in the final return. I deliberately left the earlier !anyFile && anyMonitored branch untouched: when nothing has a file, every episode is missing, so the two predicates are equivalent there and changing it would only add noise to the diff.

2. Intended UI — confirmed, and it is worth being explicit about

With statusKey == "missing-monitored", JellyseerrRequestsService drops the progress object entirely:

// Unsure state (don't show a bar). Maybe show a gray bar?
mapped.Remove("servarrProgress");

So the visible effect of this PR is not a Missing (Monitored) bar appearing. It is the false 0% Missing (Unmonitored) bar disappearing for any currently airing show. That reads right to me — no bar beats a bar with a wrong label — but the gray bar in your comment is your call. Happy to add it in this PR if you want it.

3. Tested on monitored and unmonitored partial seasons

Live library, numbers straight from GET /api/v3/episode?seriesId=N. 18 partially downloaded seasons:

season episodes with file missing anyMonitored anyMissingMonitored
16 seasons (Clevatess S02, Tomb Raider King S01, …) true true
The Villager of Level 999 S01 12 2 10 true false
From Overshadowed to Overpowered S01 12 2 10 true false

Those two are exactly the case you described: the downloaded episodes are monitored, the missing ones are not. With this change they keep Missing (Unmonitored); with the previous version of the patch they would have flipped to Monitored — the same error in the other direction.

Builds clean on the branch (net9.0): 0 warnings, 0 errors. I also applied and compiled the same two lines against tag 1.7.1.1 (net10.0) to confirm they still apply to current main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Requests tab: a partially downloaded season falls through to Missing (Unmonitored) even when every episode is monitored

2 participants