Skip to content

Latest commit

 

History

History
645 lines (499 loc) · 52.1 KB

File metadata and controls

645 lines (499 loc) · 52.1 KB

Changelog

[0.9.0] - 2026-05-02

Highlights

  • Unified media, history, and enrichment provider selection across Setup, /api/config, and the main UI so selected, available, effective, and degraded states are visible instead of silently falling back.
  • Promoted Mismatch Center and provider diagnostics into first-class troubleshooting tools, with provider-aware mismatch reasons across supported history and enrichment providers.
  • Finalized the basic, basic_local_bypass, and external auth/deployment model with setup validation, recovery guidance, and documented support boundaries for direct, reverse-proxy, Docker, Unraid, and Windows installs.
  • Expanded the modern UI pass across the toolbar, filters, status blocks, setup flow, tables, provider chips, mobile controls, and reduced-motion-safe animations.
  • Expanded German UI coverage and refreshed the translation catalog for the 0.9.0 interface.

Fixes

  • Setup provider-state summaries now treat stored-secret-backed providers and Arr instances as configured during live setup preview, so the Setup page no longer marks active Tautulli/Plex/Arr selections as unavailable when the main app is already using them.
  • Mismatch Center now distinguishes between loaded rows and total mismatch counts when the response is capped, avoiding contradictory summaries such as showing 3000 loaded rows while reporting a larger provider-conflict total.
  • Provider Insights and Mismatch Center now render explicit loading states on first open instead of presenting mostly empty shells while their API requests are still in flight.
  • Mobile filter/header layout keeps the advanced-help control aligned with the filter bar and gives the footer controls a more stable stack on narrow coarse-pointer screens.
  • Status blocks now surface provider-specific activity more clearly: media and enrichment blocks show active loading/refresh text, and each block’s top gradient animates while its provider is doing work.
  • Main UI polish now refines ambient surfaces, toolbar/filter hierarchy, filter focus states, table depth, and reduced-motion-safe animation behavior.
  • Mismatch Center now compares effective history/enrichment providers by default so inactive configured providers do not create pending/conflict rows; pass include_configured=1 to audit every configured provider.

Follow-up

  • Table row-alignment scroll snapping is intentionally disabled for 0.9.0; revisit the implementation for 0.9.1 as a configurable or lower-cost behavior.

[0.8.10] - 2026-04-16

Features

  • Added Emby direct media-source support for shows and movies, including setup/test wiring, cached background refresh, provider-aware drilldowns, image proxying, mismatch-center participation, and Emby-backed diagnostics and insights.
  • Added Emby as a selectable enrichment provider, including setup reuse when Emby is already chosen as the active media source.
  • Added Tracearr as a selectable history provider, including setup/test/save wiring, cache/refresh support, mismatch-center participation, and playback-match diagnostics support.
  • Tracearr support now uses its public API with automatic fallback from stable-ID matching to title/year matching when the newer public fields are unavailable.
  • Added an explicit basic_local_bypass authentication mode for trusted direct LAN installs. This mode requires configured Basic Auth credentials, a direct proxy mode, and an explicit local-bypass opt-in; only direct peer addresses in the configured local CIDRs can bypass the browser auth prompt, and forwarded headers are ignored for bypass decisions.
  • Auth modes are now explicitly split as:
    • basic: Sortarr challenges every client with its own Basic Auth credentials.
    • basic_local_bypass: Sortarr still requires Basic Auth credentials, but allowed direct local peers can bypass the browser auth prompt.
    • external: Sortarr trusts a configured upstream auth header from a trusted reverse proxy and does not require Sortarr-managed Basic Auth for steady-state access.
  • Setup, /api/config, and setup bootstrap payloads now expose shared provider-state data for media, history, and enrichment, making selected, available, effective, and reason values explicit.

Fixes

  • Setup source selection is now authoritative: when a specific media, history, or enrichment provider is selected, Sortarr warns when that provider is not configured or not currently effective instead of silently falling back to another configured provider.
  • Split media-source, history-source, and enrichment-provider semantics more consistently across setup summaries, helper text, and provider-specific actions so history-only flows no longer imply that media-provider features are active.

[0.8.9] - 2026-04-03

Features

  • Setup now shows live per-section header summaries so collapsed steps indicate the current media, history, security, and advanced configuration state at a glance.
  • Setup now prioritizes Plex, Jellystat, Streamystats, or Tautulli within the history/playback section based on the selected preferred history source, keeping the chosen provider closest to the top of the step.
  • Setup now progressively reveals optional Sonarr and Radarr instances behind explicit add actions, keeps history/playback provider forms hidden until they are preferred, already configured, or explicitly added, and adds explicit Remove connection actions for saved optional provider blocks.
  • Setup now adds section-level setup status badges, routes validation failures back to the relevant step, keeps stored-secret-backed sections understandable even when secret fields are blank, and splits setup validation into section-oriented backend helpers.
  • Setup now uses a five-step source-category flow: Media info source, History source, Playback and enrichment providers, Protect access, and Advanced network and performance, with explicit Plex/Jellyfin connection reuse between steps.
  • Added Jellyfin direct media-source support for shows and movies, including provider-aware drilldowns, image proxying, mismatch-center support, and provider-aware insights.
  • Added Jellyfin diagnostics and provider-aware /api/playback/insights support, including library-scoped Jellyfin match-health views.
  • Added Streamystats as a selectable history provider, including setup/test/save wiring, background refresh/cache support, mismatch-center participation, and Streamystats-backed playback overlays for Sonarr/Radarr rows.

Fixes

  • Stopped deleting on-disk Arr, Plex, Tautulli, and Jellystat caches on routine app-version changes during startup. Sortarr now keeps warm caches across normal upgrades and instead relies on explicit cache payload version mismatches to invalidate stale cache formats.
  • Basic Auth setup now accepts a newly entered password even if the remove-password checkbox is ticked, avoiding the upgrade/setup trap where replacing credentials could be misread as requiring the old password to be cleared first.
  • Added env-driven iframe embedding control via SORTARR_FRAME_ANCESTORS while keeping the secure default deny posture. Same-origin embedding now emits X-Frame-Options: SAMEORIGIN; multi-origin embedding relies on CSP frame-ancestors.
  • Sonarr season expansion layout now supports a Merged mode in the season dropdown, combining visible seasons into one sortable episode grid.
  • Sonarr season expansion episode lists now support field-based sorting, including CF Score, via both sticky header clicks and dedicated sort field/order controls.
  • Sonarr score extrema columns now default hidden, and the visible labels/tooltips clarify that they represent the lowest and highest episode custom format scores found within the series or season.
  • Reused the existing startup Arr bootstrap load instead of issuing a second duplicate first-tab fetch during frontend init, reducing redundant initial network and render work without changing visible behavior.
  • Delayed only the hidden-tab startup Arr prefetch so first-load audits prioritize the active tab; manual refreshes and later background refresh behavior are unchanged.
  • Deferred non-critical mobile startup UI wiring for filter/panel controls and Radarr poster hover behavior until after first paint settles, reducing mobile main-thread startup work without changing table load behavior.
  • Expanded header-triggered column filters to more unambiguous numeric and boolean fields, still reusing the existing filter-token engine so sorting and active-filter state stay in sync.
  • Added contextual per-column active filter chips inside the header filter popup so existing column-specific filters are visible and removable without leaving the header workflow.
  • Expanded header-triggered column filters to additional real table columns with unambiguous existing parser semantics, including Instance, Sonarr Avg / Ep and Title Slug, Edition, Video HDR, Watch Time, and TMDB ID.
  • Added the remaining date-like header funnels with conservative raw date-fragment matching for Date Added, Last Aired, Last Search, and Last Watched, keeping the existing parser semantics instead of inventing new date operators.
  • Added a first Excel-style Values mode for safe enum/bool header filters, using the existing popup shell and token engine with dataset-driven checklist values for columns like Status, Monitored, Quality, Resolution, Video Codec, Audio Codec, Has File, Available, and related low-cardinality fields.
  • Expanded the mixed Values/Advanced header popup to Studio and Release Group, using case-insensitive distinct values from the active dataset while keeping the existing advanced text matching available.
  • Capped noisy header checklist popups, added an in-popup overflow hint with search guidance, and frequency-sorted Studio and Release Group values so large distinct-value lists remain usable without disabling mixed mode.
  • Kept Audio Languages and Subtitle Languages in Advanced mode only after auditing the underlying language data, and fixed Users Watched so its header condition menu correctly exposes the numeric operators.
  • Upgraded requests to 2.33.0 to address the current GitHub dependabot advisory for insecure temporary file reuse in extract_zipped_paths().
  • Hardened local secret-file resolution so only files whose real paths remain under the expected base/secrets roots are eligible for loading.
  • Added a defensive secret scrub in env-file writes so plaintext secret values are converted to file/credential refs, or cleared when an external secret ref already exists, before persisting config.
  • Added a lightweight Plex sections bootstrap cache so /api/config can populate plex_libraries without loading the full Plex index cache on cold startup, while still validating the snapshot against the current Plex server URL/token and falling back to the full cache when needed.
  • Jellyfin direct media rows now populate size and bitrate fields from Jellyfin media metadata instead of relying only on local filesystem stats.
  • Jellyfin and Plex direct-media modes now hide Arr-only workflow columns that do not make sense outside Sonarr/Radarr-backed views.
  • Fixed Jellyfin mismatch-center inclusion, insights provider selection, and cache/refresh edge cases that could leave stale partial Jellyfin state in use.
  • Fixed provider-aware match-health reporting so Plex and Jellyfin insights reflect the active playback/history provider instead of misleading provider self-match totals, and now label match summaries as Series / Movies.
  • Fixed direct-media season and episode drilldowns plus poster proxying for Jellyfin and Plex-backed views.
  • Refreshed the Unraid template product description and expanded Docker entrypoint ownership prep to cover Plex, Jellyfin, Jellystat, and Streamystats cache path overrides.

[0.8.7] - 2026-03-19

Features

  • Added Sonarr Lowest Episode Custom Format Score and Highest Episode Custom Format Score row fields, sorting, filtering, CSV export, and season-expansion summaries for score-based analysis. These extrema are derived from episode-file custom format scores within each series or season, with specials excluded.

Fixes

  • Allowed setup-only same-host HTTP/HTTPS scheme drift during CSRF validation when the setup request carries a valid CSRF token, unblocking bootstrap/save flows behind reverse proxies that terminate HTTPS but forward setup POSTs to Sortarr over plain HTTP without usable forwarded scheme headers.
  • Fixed Plex data/index enrichment so existing Plex rows populate stream and metadata fields more reliably instead of dropping details that were already expected to work.

[0.8.6] - 2026-03-18

Fixes

  • Added a simple Sonarr-style authentication choice in Setup and config: Basic or External. Direct installs and transparent reverse proxies keep the existing Basic default, while External is now an explicit opt-in for trusted reverse proxies that already handle login.
  • Centralized route and /setup auth evaluation so both flows use the same auth boundary, and added local regression coverage for trusted-upstream auth, spoof rejection, and external-mode setup access.
  • Added SORTARR_AUTH_METHOD and SORTARR_UPSTREAM_AUTH_HEADER, plus diagnostics/self-check reporting for the active auth source. External mode now requires an explicit SORTARR_WAITRESS_TRUSTED_PROXY and no longer falls back to a browser Basic Auth challenge.
  • Fixed setup/session cookie transport policy so plain HTTP setup/save flows no longer force Secure cookies just because proxy mode is configured or still unset during bootstrap. Session and CSRF cookies now follow the effective request scheme by default, with SORTARR_SESSION_COOKIE_SECURE=1|0 still available as an explicit override.
  • Fixed proxied HTTPS setup/save CSRF origin mismatches on Waitress by stopping Waitress from stripping trusted X-Forwarded-* headers before Sortarr's own proxy middleware can translate them. Sortarr now preserves the raw proxy peer first, then applies trusted forwarded host/proto/port handling for proxied requests.
  • Setup now preserves submitted non-secret values after failed validation or connection testing so operators do not have to re-enter proxy settings, URLs, path maps, and other advanced fields on every failed save attempt.
  • Setup, CSRF diagnostics, and the security self-check now warn explicitly when plain HTTP would still receive Secure session/CSRF cookies, including the forced-override case that would cause the next POST to drop those cookies.
  • Cookie security now also honors an explicit https://... public URL/origin hint from SORTARR_PUBLIC_HOST / SORTARR_PUBLIC_URL / SORTARR_PUBLIC_ORIGIN, preventing accidental cookie downgrades when an HTTPS deployment still has incomplete proxy trust.
  • Upgrade note: if SORTARR_PUBLIC_HOST, SORTARR_PUBLIC_URL, or SORTARR_PUBLIC_ORIGIN is set to https://..., Sortarr now treats that as an HTTPS hint for cookie security. If your actual deployment is still plain HTTP, remove that https://... value or set SORTARR_SESSION_COOKIE_SECURE=0 so browsers will return the setup/session cookies on the next POST.

[0.8.5.1] - 2026-03-12

Fixes

  • Hotfix for the 0.8.5 container publish failure: removed run_waitress.py from .gitignore and added the shared Waitress entrypoint to the repository so Docker releases can actually copy /app/run_waitress.py during image builds.

[0.8.5] - 2026-03-12

Fixes

  • Fixed the Docker release packaging regression introduced in 0.8.4 by restoring run_waitress.py to the Docker build context, so published images can copy the shared Waitress entrypoint and container releases build successfully again.
  • Reduced Waitress proxy-trust startup logging to coarse state only (trust_mode, proxy count, header count) instead of logging exact trusted proxy/header values, resolving the latest CodeQL clear-text logging alerts without losing useful diagnostics.

[0.8.4] - 2026-03-11

Fixes

  • Preserved trusted X-Forwarded-* headers when running behind a proxy on Waitress 3.x by mapping Sortarr proxy mode/hops into Waitress trusted-proxy settings before Flask ProxyFix runs. This fixes proxied setup/save CSRF origin mismatches where upstream headers reached Traefik but were stripped before Sortarr saw them.
  • Limited Waitress trust to the forwarded headers Sortarr is configured to trust, so custom proxy modes no longer over-trust X-Forwarded-Host / Proto / Port when only X-Forwarded-For should be honored.
  • Routed all Waitress entrypoints through the same startup helper so Docker/alternate Waitress launches no longer bypass the proxy-trust fix.
  • Added explicit SORTARR_WAITRESS_TRUSTED_PROXY support so proxied deployments can avoid wildcard * Waitress trust; proxied wildcard fallback now emits a startup warning.
  • Narrowed X-Forwarded-Prefix handling so normal single / double presets keep strict proxy-header clearing, while prefix trust is now an explicit custom-mode opt-in (SORTARR_PROXY_HOPS_PREFIX=1) with a startup warning about the reduced Waitress sanitization.
  • Added SORTARR_WAITRESS_TRUSTED_PROXY to the Setup UI under Advanced Network & CSRF, so proxied deployments can be fully configured from the app instead of editing env files manually.
  • Setup now warns when proxy header trust changes were saved but a restart is still required, and CSRF diagnostics now show live runtime proxy/Waitress settings separately from the saved config.
  • CSRF diagnostics and mismatch logging now warn explicitly when X-Forwarded-Proto or X-Forwarded-Port arrive as comma-separated lists, because Waitress 3.x rejects those trusted-header shapes; operators are now told to normalize them at the immediate proxy instead of chasing a generic CSRF failure.

[0.8.3.1] - 2026-03-10

Security

  • Fixed bootstrap/remediation routing so a partially populated Basic Auth config no longer blocks / with Basic auth misconfigured; bootstrap and setup helper requests now reach Setup instead of failing before the redirect/remediation flow runs.
  • Setup connection-test failures now return normalized connection errors instead of helper-specific exception text, and secret-related startup/migration warnings now use count-based summaries instead of enumerating secret-setting identifiers.
  • Removed the remaining state-changing item refresh from GET item endpoints; forced playback refresh now uses CSRF-protected POST /api/sonarr/item/playback_refresh and POST /api/radarr/item/playback_refresh before the follow-up item fetch.

[0.8.3] - 2026-03-10

Security

  • Added a 0.8.3 security-upgrade flow for configured installs from 0.8.2.1 and earlier: upgrades now lock into a one-time Setup remediation save before normal access resumes.
  • Persistent session-secret references are now the enforced steady-state model. First bootstrap may use a temporary ephemeral session secret until the first successful Setup save, but configured startup aborts when a persistent secret cannot be resolved and unsafe recovery is not enabled.
  • Session-secret resolution is now secure by default: SORTARR_SECRET_KEY honors *_FILE, *_CRED_TARGET, and wincred: references, plaintext secret values are treated as migration-only input, and startup rewrites legacy plaintext secrets to secret files or Windows Credential Manager refs before Flask resolves the signing key.
  • Added bounded unsafe recovery mode via SORTARR_ALLOW_UNSAFE_EPHEMERAL_RECOVERY=1 for lockout repair only; recovery windows now auto-expire and cannot be combined with trusted origins unless explicitly forced.
  • Configured installs now remain in setup-required state until both Basic Auth and persistent-secret requirements are satisfied. Partial Basic Auth config routes into Setup remediation instead of returning a hard 503.
  • Disabled interactive setup connection testing until Basic Auth is configured and security remediation is complete, removing the remaining pre-auth outbound test path while preserving final save-time validation.
  • Hardened CSRF policy around exact trusted origins: trusted-origin fallback is token-gated, same-host by default, cross-host only with ALLOW_CROSS_HOST_TRUSTED_ORIGINS=1, and setup/startup now reject mismatched trusted-origin/public-host combinations.
  • Added proxy/CSRF diagnostics (GET /api/diagnostics/csrf) and security self-check diagnostics (GET /api/diagnostics/security-self-check) so operators can validate proxy forwarding, cookie policy, persistent-secret posture, unsafe recovery state, and trusted-origin policy.
  • Tightened the default CSP connect-src policy to same-origin only, and made session/CSRF cookie Secure defaults follow deployment mode: direct HTTP remains usable by default, while proxied modes stay Secure unless explicitly overridden.
  • Removed state-changing GET ?refresh=1; refresh actions now use CSRF-protected POST endpoints, including Plex insights refresh flows.

Features

  • Sonarr series expansion now includes Season and Episode sort controls (Ascending/Descending) with persisted UI preferences.
  • Episode-list sort controls now use the glass custom-select treatment for consistent styling with the rest of the UI.
  • Episode-list sort carets now indicate selected sort direction (up for ascending, down for descending), independent of open/closed menu state.

UI/UX

  • Upgraded main table column sort indicators from text glyphs to animated caret indicators with direction classes.
  • Tuned sort-indicator sizing and active-state contrast for both light and dark themes.
  • Updated the Filters show/hide button to use a single animated glyph path with synced aria-label/title state, removing duplicate-icon rendering paths.

Fixes

  • Hardened expansion scroll behavior by disabling table scroll-anchor capture/restore while any Sonarr series expansion is active.
  • Reduced first-interaction expansion jump risk by preferring live measured expansion heights and using a conservative fallback estimate in virtualized Sonarr expansion calculations.

[0.8.2.1] - 2026-03-04

Fixes

  • Preloaded the env file before reverse-proxy ProxyFix initialization so SORTARR_PROXY_HOPS* settings from .env apply at startup.
  • Added targeted CSRF mismatch warning logs with sanitized request URL plus Host / Origin / Referer / X-Forwarded-* context.
  • Added narrow same-host CSRF scheme fallback for proxied setups: when only http/https differs and token validation succeeds, request is accepted and logged (origin-scheme-fallback-accepted / referer-scheme-fallback-accepted).
  • Added optional exact trusted-origin CSRF fallback via SORTARR_CSRF_TRUSTED_ORIGINS (still token-gated), with warning reason codes for accepted trusted-origin fallbacks.
  • CSRF tokens are now session-bound with TTL (SORTARR_CSRF_TOKEN_TTL_SECONDS, min 60), and setup GET rotates the token boundary.
  • Added explicit CSRF token-state warning reasons (token-missing-cookie, token-missing-request, token-mismatch, token-session-mismatch) for easier diagnostics.
  • Replaced Windows credential write warning key names with non-sensitive category labels to avoid logging secret-setting identifiers.

Historical Migration Note (0.8.2 and earlier)

  • Before 0.8.3, secret-file/Credential-Manager resolution was introduced as a transition path.
  • As of 0.8.3, secure secret resolution is the default posture; current builds migrate legacy plaintext values to external refs instead of supporting plaintext runtime fallback.

[0.8.2] - 2026-02-26

Features

  • Added a new Year column in the main table and Columns panel so duplicate titles can be distinguished at a glance. Thanks @dimitricappelle.
  • Added duplicate detection across instances (title + year key) with filter support via duplicate:true/false. Thanks @tweety-tv.
  • Added quick duplicate chips to Sonarr and Radarr chip groups. Thanks @tweety-tv.
  • Enhanced advanced/global filtering so bare tokens (for example aac) search across row text, with explicit alias support via any:value. Thanks @malkinskir.
  • Added secret file support for sensitive settings via *_FILE env vars (for example SONARR_API_KEY_FILE, RADARR_API_KEY_FILE, PLEX_TOKEN_FILE), while keeping existing *_KEY/*_TOKEN env vars fully compatible.
  • Added optional Windows Credential Manager secret references (wincred:<target>), with EXE-first defaults and plain .env fallback for compatibility.

Fixes

  • Updated mixed-resolution filtering to also inspect ResolutionAll when rows are marked mixed (ResolutionMixed), so values like resolution:1080p match mixed rows correctly. Thanks @jt3204 for the PR.
  • Adjusted reverse-proxy ProxyFix handling so SORTARR_PROXY_HOPS now applies the full hop count to X-Forwarded-For, while X-Forwarded-Host / Proto / Port / Prefix default to a single trusted forwarded value and can be overridden individually via SORTARR_PROXY_HOPS_*. This fixes CSRF origin mismatches behind mixed proxy chains such as Cloudflare plus Caddy.

[0.8.1] - 2026-02-16

  • Added a Mismatch Center drawer to compare provider-by-provider playback match outcomes (Tautulli/Plex/Jellystat when multiple history providers are configured), with filtering/grouping and CSV export backed by GET /api/mismatches.

  • Resolved an issue where bitrate estimations were falling back to audio only totals, causing unexpectedly small bitrates estimations for some entries. Thanks, sorthe!

  • Added Plex as a read-only playback provider (library scan + history ingestion) with cache-aware matching.

  • Setup: Added Plex connection fields, section filters, and history page sizing.

  • Added Plex diagnostics endpoint summary (sections, history stats, activities).

  • Added provider-agnostic playback diagnostics endpoint (POST /api/diagnostics/playback-match) with shared match/health fields and provider-specific details for Tautulli/Plex.

  • Added Plex media-source table fallback: when Sonarr/Radarr are not configured, /api/shows and /api/movies can populate from Plex library rows (with selected playback/history overlay).

  • Added Plex Insights drawer (hubs, section filter, match health summary, activities, butler) with optional live updates.

  • UI: Hid native scrollbar chrome in the Plex Insights drawer while preserving scroll behavior.

  • UI: Unified glass styling for History, Plex Insights, and Mismatch Center drawers so background blur renders consistently.

  • Fixed playback cache serialization when multiple users are present (user_ids now stored as a list).

  • Fallback when Plex rejects the viewedAt history filter (retries without cutoff).

  • Fixed Plex/Jellystat cache serialization for title-year index keys.

  • Setup now supports multiple history providers at once (Tautulli, Jellystat, Plex) with an explicit preferred history source selector.

  • Added preferred media source selector in setup for clearer provider delineation when multiple sources are configured.

  • Playback provider selection now honors saved history source preference before falling back to auto-priority.

  • Setup validation now supports Plex-only media configurations; Sonarr/Radarr are no longer required when Plex is the selected media source.

  • Added backend provider option-set metadata (option_set) to /api/config for deterministic source/capability handling.

  • UI tabs now use Shows/Movies labels while preserving Sonarr/Radarr internals.

  • Added per-tab Plex library scoping (multi-select) with persisted UI selection.

  • Plex library scope is now exposed in status/diagnostics payloads and response headers for clear in-scope visibility.

  • Fixed status-row hidden state pointer interception that could block top action buttons.

  • Fixed status-row auto-hide spacing so no layout gap remains between the filters panel and table controls after the 5s hide countdown.

  • Standardized UI wording to Shows/Movies for load and refresh status text.

  • Compacted health badges by default and added inline details expansion for long alerts.

  • Simplified numeric cell rendering to improve table readability.

  • Matching: kept ID-first and title+year-first order, then added guarded plain-title fallback (<=2-year drift when Plex year is known) to reduce Plex/*arr false negatives.

  • Performance/UI: enabled Sonarr virtual row rendering for large lists and kept season expansion in-place (no forced full-table handoff) to reduce DOM/a11y snapshot pressure.

  • UI: ensured Columns popout layers above status/progress regions (including fullscreen transitions), with stable header/status/chip loading placeholders.

  • UI: consolidated Reset UI clearing so startup reset_ui and Reset UI button both clear filters/chips/query/view state consistently.

  • Rendering: reduced reflow churn with read/write layout batching, per-render title/path measurement caching, and wrap-height recalculation memoization.

  • Startup/perf: deferred non-critical chip/status bindings until first paint settles, lowered initial hydration pressure, coalesced status poll fetches, and added font preload/fallback metric stabilization.

  • Startup/perf: split boot path work so non-critical UI features (advanced filter custom-select wiring, Radarr poster tooltip delegation, option-set sync) defer to interaction/late idle after first paint.

[0.8.0] - 2026-01-31

  • Fullscreen Data Table: Added a toolbar button to hide panels and expand the table to fill the screen; Escape/✕ exits. Attempts true browser fullscreen when supported.
  • Deployment: Switched the Docker image from Gunicorn to Waitress (threaded, single-process) for simpler runtime behavior.
  • Split URL fallback: If *_URL_API is set and *_URL_EXTERNAL is not, UI hyperlinks now fall back to *_URL (legacy) instead of defaulting to *_URL_API.
  • Setup UI: Added *_URL_API fields (optional) so split-network configs can be edited without losing values.
  • Config persistence: *_URL_API[_N] values are now written to the .env file when saving setup.
  • Compression: Excluded CSS/JS (and JSON) from Flask-Compress to reduce overhead and avoid redundant compression.
  • UI: Increased perf overlay z-index so it stays visible above fullscreen table layouts.
  • UI (Filters): Category dropdown is alphabetized and searchable (desktop custom dropdown).
  • UI (Filters): Chips toggle moved into the filters footer and hides when the filters panel is collapsed.
  • UI (Sonarr): Prevent episode lists from being clipped when expanding multiple seasons in a series.
  • UI (Sonarr): Added an "Expand all seasons" toggle for series expansions (shown when multiple seasons are present).
  • UI (Radarr): Poster tooltip triggers only when hovering the title text (not the whole title cell).
  • UI (History): History drawer stays visible in fullscreen mode; table scrolling is locked while history is open.
  • UI: Health badges can now be dismissed per-alert and remain hidden until that specific alert changes.
  • Windows EXE: Default config path uses a .env next to the EXE for PyInstaller --onefile builds (and creates it on first launch).
  • Localization: Updated German translations for new and modified UI strings.

[0.7.12] - 2026-01-29

  • UI filtering shortcut: Progress/status text can act as a clickable shortcut to toggle filters (matchstatus:matched / -matchstatus:matched), only when the UI is not actively refreshing.
  • Tautulli state handling: Fixed logic that treated empty-but-valid cached Tautulli data as missing; timestamp validation now explicitly checks for None instead of falsy values.
  • Localization: Updated German translation files (translations/de/...messages.po and .mo) for new and modified UI strings.
  • Added support for separate internal (API) and external (UI) Sonarr/Radarr URLs.
  • New env vars: SONARR_URL_API[_N], SONARR_URL_EXTERNAL[_N], RADARR_URL_API[_N], RADARR_URL_EXTERNAL[_N].
  • Internal URLs are used for API communication; external URLs are used for UI hyperlinks.
  • Backward compatible with existing SONARR_URL / RADARR_URL configurations.
  • Added External URL fields for Sonarr and Radarr instances in the setup UI.

[0.7.11] - 2026-01-27

  • Fixed JS init stability issues and guarded optional UI helpers to prevent startup crashes.
  • Replaced buggy table pinch-zoom logic with a deterministic implementation and fixed early self-disable behavior.
  • Improved iOS table interaction and Radarr view stability
  • Expanded German translation coverage
  • Resolved several graphic glitches introduced through translation implementation
  • Corrected CSS grid definition for .history-summary-row to explicitly support label, main content, and delta columns (80px 1fr auto).

[0.7.10] - 2026-01-26

Sortarr now includes an expanded German translation set for both index.html and setup.html! Thank you so much, DerAachener!

The translation catalog covers:

UI labels, column names, filters, and chips

Playback and cache status messages

Setup page labels and configuration help text

Status pill and progress banners

Condition operators and filter UI text

Translations are managed using Flask-Babel with gettext .po and .mo catalogs to improve future translation efforts.

  • Added 'File History' badges to the Radarr title column, and Sonarr episode view.

[0.7.9] - 2026-01-25

  • Add filter builder dropdowns with active filter bubbles and make the Chips toggle switch between builder and classic filters.
  • Hide the Instance filter category unless multiple instances are configured for the active app.
  • Recalculate table height after filter/chip UI changes to avoid empty gaps below the table.
  • Disable iOS status-panel scroll chaining so swiping the status panel does not move the table.

[0.7.8] - 2026-01-25

  • Fix CSRF behind reverse proxy. See README if you run Sortarr behind a reverse proxy. Search for "CSRF".
  • Add Root Folder column for Sonarr and Radarr rows, including CSV export and advanced filter support.

[0.7.7] - 2026-01-25

  • Prevent exception details from leaking in radarr moviefile endpoint error responses.

[0.7.6] - 2026-01-25

Security

  • Prevent exception details from leaking in radarr moviefile endpoint error responses.

[0.7.5] - 2026-01-24

  • Improve table zoom anchoring on touch devices, prevent iOS pinch-zoom from scaling the page, and add Firefox trackpad zoom support.
  • Increase iOS column panel opacity for better readability.
  • Persist per-tab filters, chips, sort order, and column visibility across tab switches and reloads.
  • Wrap toolbar/filters/status actions on smaller screens to avoid clipped controls.
  • Center the Columns panel on small screens to avoid off-screen clipping.
  • Reserve tri-state chip prefix space without reflow so filters remain stable.
  • Clamp table height calculations during scroll so the table does not stretch when filters are visible.
  • Allow the status/progress panel to grow on small screens so action buttons stay visible.
  • Simplify data status refresh actions to three buttons (active app, Tautulli, clear caches).
  • Add Sonarr GiB / Hour and Bitrate columns alongside existing size metrics.
  • Fetch full Radarr moviefile details when needed so Custom Format Score is reported consistently.
  • Keep the status/progress panel above the table while scrolling on iOS and prevent table scroll bleed.
  • Normalize Sonarr series poster sizing on iOS and keep the Advanced filter input height consistent on small screens.
  • Fix Sonarr size/efficiency column ordering so headers align with their data.
  • Keep filter controls stacked on small screens so Advanced + help buttons don't overlap inputs.
  • Add an estimate note for Sonarr series bitrate in the columns panel and header tooltip.
  • Keep Sonarr Studio, remove the redundant Sonarr Languages column, and label Radarr Languages as Audio Languages.

[0.7.4] - 2026-01-24

Feature

  • Added Path Mapping support! You can now map container paths to host paths per instance (e.g. /movies:/mnt/media/movies).
  • This fixes the display of file paths in the UI when using Docker volume mappings.
  • Configurable via Setup page or SONARR_PATH_MAP/RADARR_PATH_MAP env vars.

[0.7.3] - 2026-01-24

Fixed

  • Fixed Docker setup page not saving configuration by respecting SORTARR_CONFIG_PATH.
  • Updated docker-compose.yaml example to use SORTARR_CONFIG_PATH for easier persistence.

[0.7.2] - 2026-01-23

  • Fetch New Data now forces a Tautulli background refresh to pick up new matches
  • Include Tautulli original titles when matching by title

0.7.2

UI Fixes

  • Update styles.css to prevent Title header from disappearing on scroll.

Configuration

  • Allow multiple path mappings per instance via the setup UI; *_PATH_MAP accepts |-separated entries.

0.7.1

Security

  • Prevent exception details from leaking in health endpoint error responses.

0.7.0

New Features

  • Add Sonarr/Radarr health badge system in the toolbar with dismissible alerts and FLIP animations.
  • Add new /api/{app}/health endpoint to fetch instance health alerts from Sonarr/Radarr.
  • Add image proxy endpoint /api/{app}/asset/{instance}/{coverType}/{id} to stream posters directly from Sonarr/Radarr.
  • Add Radarr movie poster hover tooltip on title cells.
  • Add Sonarr series poster in the expanded series panel header.
  • Add tri-state chip filters: click to include (+), click again to exclude (-), click again to disable.
  • Add negated filter token support (-prefix) for excluding items via advanced query.
  • Add perf overlay (toggle with Ctrl+Shift+P) showing FPS, long tasks, render time, visible rows, and DOM counts.
  • Add benchmark mode (?bench=1&app=radarr&rows=N) to render synthetic datasets without connecting to Sonarr/Radarr.
  • Add ?images=0 query param to disable all image loading.

UI Improvements

  • Improve date/time formatting: use locale-aware 12h/24h display, prettier month names.
  • Add Announced, In Cinemas, and Released status labels for Radarr.
  • Add Video column group toggle alongside existing Language and Tautulli groups.
  • Add column width sync for virtualized rows to prevent jitter during scroll.
  • Fetch and display health badges on tab switch and status poll.
  • Improve scroll lock during season toggle clicks in Sonarr expansions.

Performance

  • Add virtualRows render flag for optional row virtualization (Radarr enabled by default).
  • Add TTL filename cache for cover image lookups to reduce repeated metadata fetches.
  • Add pre-hydration overscan window for virtualized rows to reduce visible pop-in.
  • Integrate perf overlay render timing into the render finalize step.

Documentation

  • Document perf overlay, benchmark mode, and image preview options in README.

0.6.12

Maintenance

  • Release version bump to 0.6.12.

0.6.11

Security

  • Resolve CodeQL findings for clear-text logging and exception exposure in Arr diagnostics and instance warnings.

0.6.10

UI and columns

  • Add Sonarr series expanders with richer episode grids and per-season extras.
  • Add new Sonarr/Radarr metadata and playback columns/chips with improved mixed-value handling and match-status display.
  • Improve table layout and readability (Title/Path caps, numeric alignment, width stabilization, scroll behavior).
  • Lock Radarr column widths during batched renders to prevent resize flashes.
  • Keep Genres and Last Search cells on a single line in the table.
  • Add keyboard navigation for table rows and Sonarr season lists (arrow keys + enter/expand).
  • Refine keyboard navigation so Enter refreshes rows and left/right control Sonarr expansions.
  • Sync keyboard selection with hover and auto-focus the table on load.
  • Add episode-level keyboard navigation, season-level extras toggle on Enter, and animated Sonarr season/episode expanders.
  • Clamp Radarr text columns and preserve scroll anchors on chip toggles to prevent row shifts.
  • Fix Radarr columns widening after rapid chip/sort interactions.
  • Keep Radarr column widths consistent when filters drop below batched-render thresholds.
  • Expose Arr/Tautulli timeouts and worker settings in setup advanced options.
  • Refine Sonarr keyboard navigation within expanded seasons and speed up expansion animations.
  • Enable season extras when pressing Enter on a selected episode.
  • Allow Radarr lite hydration to complete even while Tautulli background matching is active.
  • Fix Sonarr column toggles not enabling shared columns unless Show all is used.
  • Widen the Genres column cap so labels are less truncated.
  • Add Show all toggles for long single-line Genres/Custom Formats values.
  • Brighten the Tautulli match completion flash in the status panel.
  • Increase chip group divider contrast per theme (lighter in dark mode, darker in light mode).
  • Refine refresh/status UX (per-row refresh controls, status pills/notices, tooltips).
  • Updated UI and styling (more see-through glass panels, Columns panel transparency, filter collapse control, background glow tweaks).
  • Animate filter/chip panel collapse to mirror the restore animation.
  • Disable table scroll snapping at the bottom so the last row stays visible.
  • Hide chips immediately during filter panel collapse to avoid odd text fade.
  • Darken the filter/chip panel glass in dark mode for better readability.
  • Refresh text input focus styling with a glass-like inner glow and unclipped ring.

Performance and reliability

  • Add Sonarr episode-file modes, caching, and Arr backoff to reduce load.
  • Improve rendering performance (batched renders, deferred heavy columns for Sonarr, lighter column visibility work, debounced filter renders, throttled series expansion scroll, deferred header cap work, lite status polling).
  • Defer Sonarr/Radarr wanted/recent grabbed stats on cold start and backfill them in the background.
  • Add Radarr wanted fetch parallelism (RADARR_WANTED_WORKERS) and optional multi-instance fetch workers (RADARR_INSTANCE_WORKERS).
  • Reduce Radarr moviefile fetch overhead by batching movie file lookups.
  • Speed up Radarr table renders by batching earlier and accelerating deferred hydration.
  • Begin Radarr large-table render refactor with a lighter first pass and deferred hydration for heavy columns.
  • Serve lite Radarr payloads on cold start with background hydration (SORTARR_RADARR_LITE_FIRST).
  • Scope Arr circuit breakers by endpoint group so history timeouts do not block episode file calls.
  • Allow partial results on instance failures with optional strict mode.

Security

  • Add CSRF protection, CSV formula neutralization, and basic auth for /api/version and /health.

Refresh and cache workflow

  • Improve per-row refresh messaging, and remove rows when Arr reports missing items.

0.6.9

Security

  • Redact credentialed URLs and identifiers from Arr/Tautulli warning logs.

0.6.8

Deployment and configuration

  • Default Docker image to a single Gunicorn worker with threads to keep cache/refresh state consistent.
  • Guard .env reloads with a lock to prevent concurrent config transitions.
  • Allow Arr timeouts to be disabled by setting SONARR_TIMEOUT_SECONDS/RADARR_TIMEOUT_SECONDS to 0.
  • Increase default Sonarr/Radarr request timeouts to 90 seconds for large or remote instances.

Refresh and cache workflow

  • Serialize Arr cache writes in background threads to avoid request stalls and racey disk writes.
  • Apply cache snapshot/atomic updates for Tautulli overlays and in-memory cache refreshes.
  • Snapshot Arr cache payloads before background saves to avoid concurrent mutation issues.
  • Add Refresh Current Tab to update only the active app cache.
  • Add Sonarr/Radarr refresh-all endpoints and UI buttons plus per-row refresh that also triggers Tautulli when configured.
  • Ensure per-row Radarr refresh targets a single movie by sending movieIds to the Radarr command API.
  • Reload just the refreshed series/movie after row refreshes with a short delay for Arr/Tautulli updates.
  • Only force the Tautulli index on per-row reloads when the item lacks keys.
  • Place the per-row refresh control in the Title column as a subtle refresh icon.
  • Show longer per-row refresh status messages without delaying the row reload.
  • Add Deep Tautulli Refresh to rebuild library media info and rerun matching from the UI.
  • Defer Tautulli overlays on cold cache loads and apply matching in the background for faster first paint.

Playback stats and matching

  • Prefer library play counts over history or episode aggregates to avoid double-counted show stats.
  • Log Tautulli index build timings for shows, movies, and history buckets.

Performance and rendering

  • Parallelize Sonarr episodefile fetches with the SONARR_EPISODEFILE_WORKERS cap.
  • Stabilize row keys for duplicate titles and add optional render perf logging/reset hooks for UI baselines.
  • Allow batched rendering on large interactive updates (filters, chips, sorting) while keeping small tables synchronous.
  • Stabilize Title column width on large tables to prevent widening as rows stream in.
  • Apply column visibility during batched renders so hidden columns don't inflate row height mid-load.
  • Skip redundant full-table column visibility passes after batched renders unless columns changed mid-render.
  • Time-slice batched rendering with a frame budget to reduce main-thread stalls on large tables.
  • Gate inactive-tab prefetch on cold-cache loads and defer it until the first render completes.
  • Enable gzip compression for JSON/CSV API payloads to reduce cold-start transfer time.
  • Cache per-row display values, defer hidden heavy columns, merge deferred hydration passes, and increase batch size to reduce render overhead.
  • Lazily compute light column display values when hidden and hydrate them when columns become visible.
  • Skip filter passes when no query is active and memoize sorted results to avoid repeat sorts on stable data.

UI and columns

  • Add grouped column toggles for Playback and Language columns.
  • Add Date Added column for Sonarr and Radarr views.
  • Hide Date Added by default (available via Columns).
  • Add Radarr bitrate column with estimated fallback when media info is missing.
  • Hold the Tautulli matching notice until the first table render (chips visible).
  • Increase row refresh icon size and contrast in light/dark themes.
  • Spin the row refresh icon while per-row refresh is pending.
  • Mark per-row refreshes as partial when Tautulli is skipped or pending so the notice reflects missing playback data.
  • Stabilize Match Status pill width to reduce column jitter during row refreshes.
  • Restore filled Match Status pill backgrounds for clearer status emphasis.
  • Add purple/cyan pill styling for Future release and Not on disk statuses.
  • Lock column widths during batched renders to reduce post-sort jitter.
  • Clear stale column width locks between rapid sorts.
  • Add subtle per-column dividers (toggle by setting --col-divider-color).
  • Center table headers and data cells (keep Title, Path, Audio Codec left-aligned).
  • Animate and dim rows while per-row refresh is pending.
  • Clamp Audio Codec cell content to keep the column from expanding.
  • Trigger a one-time post-load re-render to stabilize initial column widths.
  • Re-run the column-width stabilization pass after tab or instance chip switches.
  • Add optional render debug flags to disable batching, deferred columns, width locks, or stabilization.
  • Disable deferred heavy-column hydration by default (toggleable via render flags).

Diagnostics

  • Log Arr JSON decode failures with response snippets for faster diagnosis.
  • Add sanitized X-Sortarr-Error headers when Arr fetches fail so the UI can surface hints.
  • Add optional per-item refresh timing output (timing=1) for row refresh diagnosis.
  • Add detailed Tautulli fetch timing breakdowns to the per-item timing output.

0.6.7

  • Align app version metadata with the 0.6.7 release.

0.6.6

  • Avoid logging instance labels during cold-start fetch/match steps to keep logs free of sensitive data.
  • Replace the trailing-parenthetical title cleanup regex with a safe string parser to avoid polynomial ReDoS.

0.6.5

  • Show live Tautulli refresh progress with processed/total counts and last update time in the status row
  • Refresh both tabs after Tautulli matching completes so data appears without manual tab swaps
  • Include disk-only caches in Tautulli match progress to avoid 0-to-full jumps
  • Replace the Status pill label with live progress and smooth pill transitions; remove redundant Last Updated from the toolbar
  • Keep the cold-cache notice visible while background refreshes run and restore Sonarr column ordering
  • Yield a frame before rendering large fetches and avoid per-batch column visibility passes for smoother table loads
  • Cache per-row sort keys and increase batch sizes for very large tables to reduce refresh overhead
  • Defer hidden-column cell rendering on large tables and hydrate them after the initial render
  • Skip reapplying Tautulli stats to cached rows when the index timestamp is unchanged and add a lite status poller
  • Reapply Tautulli match overlay when cached rows are missing match fields to avoid pending-only counts
  • Serve cached rows immediately on refresh requests and update Arr caches in a background thread when possible
  • Reduce Tautulli index build and match overhead with cached title keys and lazy key generation
  • Slow chip reveal animation for smoother transitions
  • Tune light-theme surfaces (background, toolbars, data, progress) to reduce glare
  • Add a subtle purple tint to the top toolbar in light mode
  • Keep chips visible during refreshes after the first load
  • After Fetch New Data, perform a one-shot background refresh to clear stale mismatch badges
  • Enforce unlimited Tautulli metadata lookups and clear caches on upgrade to prevent history bucket gaps
  • Backfill history items from strict title+year mappings to keep ID buckets current without false matches
  • Move performance tuning fields into the Advanced section of setup
  • Hide Cache seconds from setup (env-only)
  • Document ENV_FILE_PATH, PORT, and SORTARR_LOG_LEVEL env vars in README.

0.6.4

  • Hide Tautulli playback columns in CSV exports unless Tautulli is configured
  • Show cold-start and Tautulli matching notices together during background refresh
  • Keep Tautulli history merges from lowering play counts, users, or watch time totals
  • Clear Tautulli refresh lock and marker files on version upgrade
  • Refresh Sonarr and Radarr screenshots

0.6.3

  • Parallelize Tautulli metadata lookups and periodically flush the metadata cache to disk
  • Clear stale Tautulli refresh locks to prevent matching from getting stuck after a crash
  • Avoid title-only Tautulli matches when release year is present to reduce cross-title collisions
  • Show Total (GiB) by default and reorder Sonarr columns to Episodes, Avg / Ep, Total
  • Shorten Tautulli placeholders so columns stay tighter during background matching
  • Switch table layout to auto sizing and reserve scrollbar gutter for consistent column widths during loads
  • Left-align all table columns for consistency

0.6.1

  • Document that Sortarr.env should be treated as a secret

0.6.0

  • Refresh base image to python:3.14-slim and upgrade pip to address CVE findings
  • Surface Tautulli match status with a mismatch badge, filter, and CSV fields
  • Default Tautulli lookup and fetch limits to unlimited for full cold-start coverage
  • On first run after upgrade, clear caches and drop legacy Tautulli default env values
  • Run Tautulli matching in the background and show a progress notice in the UI
  • Auto-refresh while Tautulli matching completes and keep the loading indicator active
  • Raise default Tautulli timeout and fetch budget to allow longer first loads

0.5.15

  • Add a per-table CSV columns toggle in the Columns menu, separate from Advanced filters
  • Security: redact sensitive paths and avoid leaking connection error details in logs

0.5.13

  • Expose Tautulli metadata lookup and timeout controls in setup and the Unraid template
  • Add a Settings button in the toolbar to reopen setup

0.5.12

  • Display watch time columns as hh:mm instead of decimal hours
  • Add watch vs content hours playback column with ratio sorting and filters
  • Improve Tautulli matching with relaxed title variants (parentheses, &, colon/dash, possessive prefixes, 3D tokens)
  • Request Tautulli library GUIDs/external IDs when available to improve ID matching
  • Use Tautulli metadata lookups to resolve external IDs when GUIDs are Plex-only
  • Cache Tautulli metadata IDs to disk with configurable lookup limits for faster loads
  • Persist Sonarr/Radarr caches to disk and refresh them only via Fetch New Data
  • Fail open when Tautulli data is unavailable, warn in the UI, and cap Tautulli fetch time
  • Increase initial load headroom (Gunicorn timeout + higher default Tautulli budgets) and surface a first-load notice
  • Support PUID/PGID in Docker entrypoint and add defaults to the Unraid template
  • Validate Sonarr/Radarr connections during setup before saving
  • Validate Tautulli connection during setup when configured
  • Add per-instance test buttons with inline setup errors
  • Add advanced UI columns for CSV-only fields, include TMDB ID in Sonarr CSV exports, and surface Content Hours in the Sonarr columns