Stop treating the absolute path as a file's identity so a base-path change
(host binary→docker remap, moved media folder, remount) no longer makes the
server duplicate and orphan library rows.
- fingerprint.go: ComputeFingerprint = sha256(size ‖ first 1MiB ‖ last 1MiB),
a stable content identity that survives rename/move/base-path change. Cached
in LibraryItem and reused on incremental scans when size+mtime are unchanged.
- sync: send fingerprint + rel_path (relative to the scan root) + agent_id in
the library-sync request, so the server can move a row in place and scope
stale-cleanup per agent.
- daemon: force a FULL re-scan (with a user-facing WARNING) when the scan root
changed since the last cache, so the server re-maps by fingerprint instead of
duplicating. basePathChanged compares filepath.Clean'd roots.
- daemon: relocateUnreachable self-heals a stream request whose path is under an
old root but whose file still exists under a current allowed root, so playback
works immediately without waiting for the re-scan. Conservative: requires a
3-segment tail and re-checks containment after resolving symlinks so it can
neither serve the wrong file nor escape the allowed dirs.
See docs/plans/unarr-path-resilience.md in the web repo.
ffprobe already runs on every scanned file; now we capture its stderr and
assess integrity from it. assessIntegrity flags a file "damaged" on the
markers that mean the container/bitstream is unusable: invalid_data,
ebml_corrupt, moov_missing, bitstream_corrupt, plus no_duration (a video
stream with non-positive duration = a truncated/incomplete download).
The verdict rides on MediaInfo.Integrity (IntegrityInfo{Damaged,Reason}),
maps onto LibrarySyncItem.{Integrity,IntegrityReason}, and syncs to the web
so a damaged file can be surfaced at rest instead of only blowing up at
playback.
Bumps the scan cache version (1 → 2) so existing entries re-probe once, and
the scanner re-probes any cached entry that has no integrity verdict yet.
- Migration wizard from Sonarr/Radarr/Prowlarr (unarr migrate) [pre-beta]
- Auto-detect instances via Docker, config files, port scan, Prowlarr
- Import wanted list (monitored+missing movies/series)
- Import download history and blocklist to avoid re-downloading
- Extract debrid tokens from *arr download clients
- Quality profile mapping to preferred_quality config
- DISTINCT ON PostgreSQL query for optimal torrent selection
- JSON export with --dry-run --json (text to stderr, JSON to stdout)
- Media server detection (Plex/Jellyfin/Emby) in unarr init
- Detects library paths and offers them as download directory options
- Debrid auto-configuration in unarr init
- Scans *arr instances for debrid tokens
- Validates and saves via API if user confirms
- New preferred_quality setting in config (2160p/1080p/720p)
- Library scan command (unarr scan) with ffprobe metadata extraction