github jessielw/Reclaimerr 0.3.7

4 hours ago

Note

This requires a Media Sync for some of the changes to take place. There is also a migration so startup will take a moment longer once as this takes place during this process.

Added

  • Added separate Plex, Jellyfin, and Emby genre rule conditions sourced from the configured main media server. Provider genres remain isolated from TMDB genres and include searchable rule pickers.
  • Rule descriptions:
    • Added editor textarea, rule-card display, import/export/API support.
    • Candidate and protected detail views now show current rule descriptions; deleted rules omit them.
  • Per user control for datetime format
  • Settings -> User Signals -> Ignore Seerr Request Dates. Turns the request-date comparison off for Seerr requester watched after requesting, leaving it to check completion alone. Intended for installs where the request dates cannot be trusted -- a rebuilt or migrated Seerr, or re-requested seasons, dates its rows after the plays they describe, which makes that comparison un-passable for a whole library. Off by default, applies to every rule at once, and relaxes only the date half: an item nobody finished stays false, and an unreadable media server stays unknown. The Why? dialog reports when the switch is on and still lists the plays that predate the request.
  • More detailed information for why rules match releases

Changed

  • Behavior change: Seerr requester has watched no longer includes the request date. It now answers only "did a requester watch this", matching how other projects models the same question. The old meaning moved to a new Seerr requester watched after requesting condition, and rules saved before this release are migrated onto that field automatically, so no existing rule changes what it matches. New rules should prefer the plain field unless they specifically need the request-date gate.
  • Fixed a false negative in requester watch rules. The "watched after requesting" bar used the newest request a user had for a movie or season. Seerr writes a separate request row for a 4K copy and for every re-request of an airing season, so a later request moved the bar past plays that had already happened and a season the requester demonstrably finished reported as not watched. The bar is now that requester's earliest request. Request age (Seerr latest active request) still tracks the newest request.
  • Playback-user identities reported by more than one provider for the same media server are now merged into one account. A Plex server, the Tautulli watching it, and a Plex-bound Tracearr all describe the same people, and treating them as separate accounts made every shared name look like a collision -- which disabled the alias registry entirely for those setups and left manual mappings as the only thing that worked. A name a single provider gives to two of its own users still bridges nothing, and provider ids never bridge across providers.
  • The Seerr requester watch-user picker now lists one entry per playback account. Account ids, Tracearr identity uuids, and email addresses appear as that account's other names instead of as separate selectable users, and remain searchable. Mapping coverage is calculated from every identity requester matching actually tries, including the email address it previously ignored.
  • At season scope, Path now reports the season's own folder, falling back to the series roots only when the provider reports no season path. A series held by two Sonarr instances has one root per instance, so season rules could not tell an HD season from a UHD one.
  • Path is/is not now considers every path in scope rather than whichever one was returned first, so the result no longer depends on row order.
  • Sonarr series are now matched by TVDB id when Sonarr reports no TMDB id. Sonarr is TVDB-native and returns tmdbId: 0 for shows it could not map; those series were never matched, so they had no Arr reference or tags and their seasons reported Season inventory unavailable on every scan no matter how often Sync Media ran.
  • The requester watch Why? explanation now shows the request date it compared against, each requester's per-season request dates, the timestamp of every completed play, and -- when the answer is false -- which episodes were never watched versus which were watched before the request. It also reports both requester-watch fields, and lists only the episodes the target actually requires instead of every episode in the series.
  • Jellyfin v12 user-scoped favorites and episode-parent lookups now use the supported Items?userId=... route instead of the removed Users/{id}/Items route.
  • Requester watch rules now resolve identities through a playback-user alias registry. Every name a provider reports for an account -- Plex account id, username, title, friendly name, and email, plus the Jellyfin, Emby, Tautulli, and Tracearr equivalents -- is recorded together, so matching any one of them reaches the rest. Aliases bridge accounts only within the same media server, and a name shared by two accounts (two Plex profiles both titled Home) bridges neither.
  • Seerr requester identities now include the linked plexUsername, plexId, jellyfinUsername, and jellyfinUserId from Seerr's user directory, and requests keep the identities embedded in their requestedBy payload as a fallback when that directory is unreachable.
  • Completed plays retained from a superseded durable provider now count as watch evidence for Seerr requester has watched. Playback totals still use exactly one provider per media server so plays are never double counted.
  • Previewing or scanning a rule that uses Seerr requester has watched or Seerr requester watched after requesting now refreshes the watch snapshot itself instead of relying on the last Sync Media run. The refresh previously keyed on the pre-split field name only, so every rule the split migration moved onto the new field evaluated against whatever the last Sync Media left behind.
  • Playback-user identities are registered during Sync Media and the periodic playback refresh, and once in the background at startup when none have been recorded yet.
  • Behavior change: Seerr requester has watched is now unknown, not false, when the media server holding an item cannot report completion and no retained durable history covers it. Unknown matches neither is true nor is false, so rules that delete on is false will match fewer items -- previously an unreadable media server was indistinguishable from "nobody watched it". The rule preview reports how many items were affected.
  • Season fully watched and Season watched (%) judge stale watch data per episode instead of per season. Replacing one episode file bumped the season added date and discarded the recorded watch state of every other episode in that season.
  • Rule previews now warn when Seerr request data could not be loaded, instead of silently evaluating every Seerr condition as unknown and showing an ordinary empty result.
  • Rule preview rows using Seerr requester has watched gained a Why? action that reports the requesters, every identity tried for each of them, the completed watches found, the episodes required, and any media server that could not be read. Backed by a new GET /api/rules/requester-watch-explain, whose verdict comes from the same code a cleanup scan uses.
  • The Seerr requester watch-user picker now lists every playback account the alias registry knows, including Tautulli and Tracearr users who never appear in the watch snapshot tables and previously could not be selected at all.
  • Renamed the Media Identity Links panel under Settings -> Users to Sign-In Identity Links, and pointed it at Settings -> User Signals. It controls sign-in only and has no effect on rules; the shared name repeatedly sent people to the wrong screen.
  • Rule condition filter is now more accurate when searching.
  • Updated dependencies:
    • apprise to 1.13.0
    • granian to 2.8.2
    • platformdirs to 4.11.4

Fixed

  • The requester-watch Why? dialog no longer claims an unwatched movie requester watched every required episode. Movie requester details now use movie-specific wording and reflect that requester's completed-play state and request date.
  • Seerr requester has watched reported false for media the requester had demonstrably finished when the Seerr account name differed from the media-server account name, which could make an is false cleanup rule delete watched media.
  • Binding Tracearr to a Plex server no longer discards the Tautulli history that predates Tracearr when evaluating requester watch state.
  • Tracearr play chains whose watched flag is not a JSON boolean (1, "true", watched_status) are no longer treated as unknown completion, which had silently disabled requester watch rules for a bound Plex server. A Tracearr server that returns plays but never reports completion is now logged as a warning.
  • Removed three uncalled supplemental play-count sync functions whose docstrings described precedence rules that no longer ran, so searching for that behavior no longer lands on dead code.
  • Durable playback events imported before their media-server IDs were known are re-resolved on each refresh instead of staying permanently unmapped and invisible to rules.
  • Sync Media failed with "can't compare offset-naive and offset-aware datetimes" while merging episode dates. Media servers report timezone-aware timestamps and SQLite reads them back naive; episode and season dates are now normalized to naive UTC on the way in so the two can never be compared directly.
  • Automatic deletion now re-checks any rule whose verdict depends on watch state, not just playback.* rules. A season queued as "the requester never watched it" could still be deleted after they watched it during the auto-delete delay.
  • Rule editor and preview reasons now use the same label for every field. Sixteen had drifted (Views vs View count, Color space vs Video color space, Seerr requested by user IDs vs Seerr requester IDs, and so on), which read as two different conditions. TMDB rating (0-10) intentionally keeps its scale hint in the editor, and a test now guards the rest.
  • Preview reasons render byte and duration values in human units (5 GiB, 2h 0m) instead of raw numbers, so size and duration conditions are readable without knowing the field's unit.
  • A Tracearr user whose account on the bound server was removed keeps their username for requester matching instead of falling back to an opaque identity id, so their retained history stays attributable.
  • Tracearr HTTP 429 responses honor Retry-After again. The parsing body had been spliced into an unrelated function after its return, leaving it unreachable.

What's Changed

Full Changelog: 0.3.6...0.3.7

Don't miss a new Reclaimerr release

NewReleases is sending notifications on new releases.