• v2.1.0 55ab4e61aa

    V2.1.0 Stable

    patrick19368 released this 2026-03-30 11:32:33 -04:00 | 0 commits to main since this release

    v2.1.0 brings episode-level archive and restore, live restore progress, automatic re-add to Sonarr/Radarr on restore, and a reworked dashboard. A large batch of fixes across the archive/restore pipeline, Python 3.13 compatibility, and database migration reliability.

    Added

    • Restore progress bar showing file count, bytes copied, and import stage live in the modal. Copy runs in the background so the modal can be closed.
    • Restore re-adds movies and TV shows to Radarr/Sonarr by TMDB ID before scanning so ARR picks them up properly instead of requiring a manual import.
    • Archive modal checks the database before copying — skips items already archived and shows a list with an option to remove them from Sonarr/Radarr.
    • Restore modal blocks if the movie is already active in Radarr or if the source drive is cold.
    • Episode-level diff for archive and restore. Only missing episodes are copied in either direction instead of entire seasons.
    • GET /api/v3/archive/episode-diff — per-season episode breakdown comparing Sonarr against what is on the archive drive.
    • GET /api/v3/archive/media-check — DB check to determine if a movie or show is already archived.
    • GET /api/v3/restore/movie-check — DB check to determine if a movie is already active in Radarr.
    • POST /api/v3/archive/remove-from-arr — removes an already-archived item from Sonarr/Radarr without touching files.
    • Merge duplicate media is now a scheduled task running daily and available on demand from the Tasks page.
    • Tasks page shows live per-task status via SSE.

    Fixed

    • Restore was sending undefined as dest_root due to selectFolder overwriting data-path with an undefined second argument.
    • Season diff was failing with TypeError because _archive_has_episodes returns a dict keyed by season, not a flat set.
    • Sonarr episode lookup now uses GET /api/v3/episode instead of parsing S01E01 from filenames.
    • Re-adding movies to Radarr was failing with 400 due to missing qualityProfileId. Now fetches the first available quality profile before posting.
    • Restore showed all episodes as missing when sonarr_id was null. Now falls back to a title search against the Sonarr series list.
    • DownloadedMoviesScan replaced with a re-add then RescanMovie flow for restored movies.
    • Stuck restore queue rows from interrupted copies now cleared on startup.
    • Root folder query timeout raised to 30 seconds for slow Radarr instances.
    • Root folder paths not accessible on the Catalogarr host are flagged as mount_required and excluded from the destination picker.
    • Archive and restore checks now use the database as source of truth. Physical path checks removed.
    • Archive cold drive check uses a LIKE path match so subpaths are caught correctly.
    • Scan and enrich now runs on the copied folder before removing the item from Sonarr/Radarr.
    • gevent updated to 24.11.1 for Python 3.13 compatibility.
    • gunicorn updated to 23.0.0 for Python 3.13 compatibility.
    • Episode numbers above E99 no longer create separate media entries per episode.
    • Database migration guard was silently skipping column additions on existing installs.
    • Connector INSERT referenced a username column that didn't exist on older databases.

    Changed

    • Dashboard layout — Connectors and System are side by side, Drive Health and Scan Workers each get their own full-width row.
    • System card now shows instance name, runtime, OS, version, and drive health warnings.
    • Drive Health cards truncate long paths and show the drive label if set.
    • Templates cleaned of emojis and AI-generated section decorators.
    • Drive cold/online toggle now available directly in Settings under the Drives section.
    Downloads
  • V2.0.0 27d2687db5

    V2.0.0 Stable

    patrick19368 released this 2026-03-20 20:13:20 -04:00 | 20 commits to main since this release

    v2.0.0

    Complete rewrite of Catalogerr (now Catalogarr). Not backwards compatible with v1.x databases or configs.

    Auth

    • Redis-backed sessions replace API key auth in the frontend
    • HttpOnly cookies, 8-hour sliding TTL
    • require_auth middleware for page routes, require_api_key for API routes

    Archive / Restore

    • Archive active media to local drive — copies full folder tree including NFO and artwork, removes from Sonarr/Radarr, optionally deletes source
    • Restore archived media to Sonarr/Radarr root folder with automatic rescan trigger
    • Season-level restore for TV — diffs archive seasons against Sonarr episode files before showing picker
    • Drive cold/online status — blocks restores on cold drives, auto-detects offline paths

    Metadata

    • NFO reader — parses Kodi/Jellyfin/Plex .nfo files and copies local artwork before any network call
    • Shoko connector for anime — set SHOKO_URL + SHOKO_API_KEY, flag paths as anime in config
    • Enrichment waterfall: NFO → Sonarr/Radarr → TMDB
    • All API keys read at call time, not module import — env changes apply without restart

    Tasks

    • merge_duplicate_media — merges per-episode media rows caused by bad filename parsing, runs daily and on demand
    • All tasks have max_instances=1 and coalesce=True
    • Tasks page shows live per-task status via SSE

    Active Catalog

    • Multi-select with archive modal
    • Poster click = select, title click = detail page

    Bug Fixes

    • X-Api-Key was sent as query param to Sonarr/Radarr instead of header — enrichment was silently failing
    • load_dotenv missing override=True.env values ignored when vars existed in shell environment
    • ZIP restore path traversal vulnerability
    • POST /drives, PUT /drives, DELETE /drives, POST /scan had no authentication
    • connector_media and related tables referenced but never created in schema
    • TV show ID hash collisions on identical cleaned titles
    • tasks/stream crashing with queue.Empty instead of yielding keep-alive
    • Episode regex \d{1,2} only matched E01-E99 — episodes 100+ indexed as separate shows
    • Database migrations gated on condition that silently skipped on existing installs
    • Connector INSERT referenced username column that didn't exist in pre-migration DBs
    • gunicorn==20.1.023.0.0 (Python 3.13 compat, pkg_resources removed)
    • gevent==23.9.124.11.1 (Python 3.13 compat, Cython long build failure)

    Breaking Changes

    • Session auth replaces API key frontend auth — existing sessions invalid after upgrade
    • Run python3 admin.py after upgrade to ensure schema migrations apply
    • gunicorn.conf.py replaces old service file flags — update systemd unit if self-hosting
    Downloads