feat: slskd reconnect guard in downloaders_reset, mass v2 sync

- downloaders_reset: connection check block before slskd API sections;
  triggers PUT /api/v0/server reconnect if disconnected, polls 60s,
  gates Stuck Searches and Dead Transfer Records on SLSKD_CONNECTED
- Sync all modified/new/deleted files from v2 refactor across Docker_Essentials,
  Media, Monitors, Partnership, Rsync, Tools, Transcodes, unRAID_Essentials,
  common.sh, master confs, and new Manual/README docs
This commit is contained in:
Gmer4Lfe
2026-05-19 20:00:10 -04:00
parent 5cb16d4b18
commit e13f2fa14f
81 changed files with 12164 additions and 10656 deletions
+61 -51
View File
@@ -2,77 +2,87 @@
# ==============================================================================================
# ================================= Radarr Cleanup =============================================
# ==============================================================================================
# Removes orphaned movie files from the library that Radarr no longer tracks.
# Uses the Radarr API to build a complete list of tracked movie file paths then compares
# against what exists on disk — anything untracked and older than RADARR_ORPHAN_AGE
# days is considered an orphan and deleted.
#
# ── FILE CLASSIFICATION ───────────────────────────────────────────────────────────────────────
# TRACKED — Radarr API knows about this exact file path → leave it alone
# PROTECTED — matches RADARR_PROTECTED_PATTERNS → never delete (artwork, subtitles, .nfo)
# ORPHAN — video file, not tracked, older than RADARR_ORPHAN_AGE days → delete
# PURPOSE
# ─────────────────────────────────────────────────────────────────────────────
# Delete orphaned movie files not tracked by Radarr. Queries the API for all
# tracked movie file paths, walks the library on disk, and removes anything
# untracked that is old enough to be past the import window. Triggers an Emby
# library clean after each deletion run so ghost entries disappear immediately.
#
# ==============================================================================================
# OPERATIONAL MODEL
# ==============================================================================================
#
# Every file encountered on disk is classified into one of five categories:
#
# TRACKED — Radarr API knows this exact path → leave it alone
# PROTECTED — matches RADARR_PROTECTED_PATTERNS → never delete
# ORPHAN — video file, not tracked, older than RADARR_ORPHAN_AGE → delete
# JUNK — not a video extension, not protected → delete regardless of age
# RECENT — not tracked, under RADARR_ORPHAN_AGE days old → skip (may be mid-import)
# RECENT — not tracked, under RADARR_ORPHAN_AGE → skip (may be mid-import)
#
# ── WHY PROTECTED PATTERNS MATTER ─────────────────────────────────────────────────────────────
# Radarr generates movie artwork (*.jpg), metadata (*.nfo) and manages subtitles (*.srt,
# *.sub, *.ass) but does NOT include these in its tracked file API response.
# Without protection these would be classified as orphans and deleted — breaking
# Radarr and Emby metadata display.
# Radarr generates movie artwork (*.jpg), metadata (*.nfo), and manages subtitles
# (*.srt, *.sub, *.ass) but does NOT include these in its tracked file API response.
# Without PROTECTED classification these would be deleted — breaking Radarr and
# Emby metadata display.
#
# ── SAFETY LAYERS — ALL MUST PASS BEFORE ANY FILE IS TOUCHED ─────────────────────────────────
# 1. Container must be running and not starting/unhealthy
# 2. API must be reachable
# 3. API version must match tested major version in master.conf
# 4. Movie count must be > 0
# 5. Tracked file count must be > 0
# 6. Deletion size must be < RADARR_MAX_DELETE_GB — or --i-know-what-im-doing required
# After deletions: notify_emby_scan() triggers Emby "Clean Missing Files" task.
# Emby removes ghost entries immediately — no user-facing file-not-found errors.
#
# ── POST-DELETION ─────────────────────────────────────────────────────────────────────────────
# After files are deleted notify_emby_scan() triggers Emby "Clean Missing Files" task.
# Emby immediately removes ghost entries — no user-facing file-not-found errors.
# ==============================================================================================
# OPERATIONAL SAFEGUARDS
# ==============================================================================================
#
# ── OVERRIDE FLAGS ────────────────────────────────────────────────────────────────────────────
# --i-know-what-im-doing required when deletion exceeds RADARR_MAX_DELETE_GB
# --skip-strike-list bypasses RADARR_ORPHAN_AGE age check
# NUCLEAR MODE — both active: age + size bypass, deletes on first pass
# ⚠️ User accepts full responsibility — no recovery possible after deletion
# Six gates — ALL must pass before any file is touched:
# 1. Container running and not starting/unhealthy
# 2. API reachable
# 3. API version matches RADARR_VERSION_MAJOR in master.conf
# 4. Movie count > 0
# 5. Tracked file count > 0
# 6. Deletion size < RADARR_MAX_DELETE_GB — or --i-know-what-im-doing required
#
# ── HOST AWARENESS ────────────────────────────────────────────────────────────────────────────
# HOST1 Radarr manages Movies. HOST2 Radarr manages Anime_Movies.
# detect_hosts() sets MY_ID and aliases RADARR_URL, RADARR_API_KEY, RADARR_MOVIES_ROOT.
# No manual HOST1/HOST2 comparisons — MY_ID routes correctly on any server.
#
# ── SAFEGUARDS ────────────────────────────────────────────────────────────────────────────────
# acquire_lock "wait" — large scans take time, wait for previous run to finish
# jq + curl validation — exits if either tool missing
# DOCKER_TIMEOUT — container checks protected against daemon hangs
# 6 safety layers — all must pass before any file is touched
# notify_emby_scan() — triggers Emby clean after deletion
# validate_unraid_cmd — notify script validated before use
# Silent by default — orphans/junk warn(), clean library logs silently
#
# ── CONFIGURATION (master_host*.conf) ─────────────────────────────────────────────────────────
# ==============================================================================================
# CONFIGURATION
# ==============================================================================================
#
# master_host*.conf
#
# HOST*_RADARR_URL / HOST*_RADARR_API_KEY / HOST*_RADARR_MOVIES_ROOT
# HOST*_RADARR_PATH_MAP — container path → host path translation
# All aliased by detect_hosts() — script uses unprefixed names
#
# ── CONFIGURATION (master.conf) ───────────────────────────────────────────────────────────────
# RADARR_ORPHAN_AGE — days before untracked file eligible for deletion
# RADARR_MAX_DELETE_GB — require --i-know-what-im-doing above this
# RADARR_EXTENSIONS — video file extensions considered for orphan classification
# RADARR_PROTECTED_PATTERNS — file patterns never deleted
# RADARR_VERSION_MAJOR — expected Radarr major version for API safety check
# RADARR_IMPORT_SCAN_TIMEOUT — seconds to wait for pre-flight import scan (default 600)
# ARR_CLEANUP_STATS — stats file path (read by coffee report)
# master.conf
#
# ── USAGE ─────────────────────────────────────────────────────────────────────────────────────
# radarr_cleanup.sh — normal run
# radarr_cleanup.sh --dry-run — preview, no deletions
# radarr_cleanup.sh --log — verbose output
# radarr_cleanup.sh --status — show config and exit
# radarr_cleanup.sh --i-know-what-im-doing — bypass size threshold
# RADARR_ORPHAN_AGE — days before untracked file eligible for deletion
# RADARR_MAX_DELETE_GB — require --i-know-what-im-doing above this
# RADARR_EXTENSIONS — video file extensions for orphan classification
# RADARR_PROTECTED_PATTERNS — file patterns never deleted
# RADARR_VERSION_MAJOR — expected Radarr major version for API safety check
# RADARR_IMPORT_SCAN_TIMEOUT — seconds to wait for pre-flight import scan (default 600)
# ARR_CLEANUP_STATS — stats file path (read by coffee report)
#
# ==============================================================================================
# RUNTIME MODES
# ==============================================================================================
#
# radarr_cleanup.sh — normal run
# radarr_cleanup.sh --dry-run — preview, no deletions
# radarr_cleanup.sh --log — verbose output
# radarr_cleanup.sh --status — show config and exit
# radarr_cleanup.sh --i-know-what-im-doing — bypass size threshold
# radarr_cleanup.sh --i-know-what-im-doing --skip-strike-list — NUCLEAR MODE
#
# NUCLEAR MODE: both flags bypass age check AND size threshold. User accepts full
# responsibility — the flag name is long and annoying by design.
#
# ==============================================================================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"