Media echo/log audit pass — 11 scripts + Manual

Remove setup banners from all 8 scripts that had them (discovery scripts
use comment-only setup sections). Move per-item/detail echoes to log in
arr_sync, lidarr_missing_art, lidarr/radarr/sonarr_cleanup (scan progress,
API query status, root/orphan config lines), and per-title lines in
radarr_tmdb_removed / sonarr_tvdb_removed. Fix log→echo on clean-status
summary lines in arrs_failed_stalled_recovery, media_cleaner, and both
removed-title scripts. Add output tiers section to Manual-Media.md.
This commit is contained in:
Gmer4Lfe
2026-05-21 16:48:08 -04:00
parent c1c12cbe73
commit a4edeab5eb
11 changed files with 49 additions and 65 deletions
+17
View File
@@ -543,6 +543,23 @@ If ghosts persist:
---
## ━━━ OUTPUT TIERS ━━━
All scripts have two output levels controlled by `--log`.
Without `--log`, each script processes silently and always concludes with a summary
block: identity, duration, counts (files removed, items added, arrs cleaned), and a
status line. Warnings and errors are always visible.
With `--log`, per-item detail appears: individual titles being processed, API query
progress, per-node sync results, and per-file examination output. Use this when
debugging unexpected results or validating configuration before the first scheduled run.
Dry-run output follows the same tiers — `--dry-run` alone shows the summary of what
would happen; `--dry-run --log` shows the full per-item preview list.
---
## ━━━ FLAG REFERENCE ━━━
### media_shares_permissions.sh
+1 -4
View File
@@ -154,9 +154,6 @@ fi
# ==============================================================================================
# ━━━ Setup ━━━
# ==============================================================================================
echo ""
echo "━━━ $ICON_GEAR Setup ━━━"
if [[ "$EUID" -ne 0 ]]; then
error "Must be run as root"
exit 1
@@ -822,7 +819,7 @@ _sync_arr() {
fi
fi
echo " $node_name: +${#to_add_local[@]} local | +${#to_add_remote[@]} remote | $total_skipped blocklisted"
log " $node_name: +${#to_add_local[@]} local | +${#to_add_remote[@]} remote | $total_skipped blocklisted"
unset remote_ids
declare -A remote_ids
+1 -4
View File
@@ -92,9 +92,6 @@ parse_args "$@"
# ==============================================================================================
# ━━━ Setup ━━━
# ==============================================================================================
echo ""
echo "━━━ $ICON_GEAR Setup ━━━"
if [[ "$EUID" -ne 0 ]]; then
error "Must be run as root"
exit 1
@@ -451,7 +448,7 @@ elif [[ "$TOTAL_ACTIONED" -gt 0 ]]; then
notify "Arr recovery on $(hostname)$TOTAL_ACTIONED item(s) blocklisted and re-searched" \
"Arr Recovery" "warning"
else
log "$ICON_DONE Done — nothing to recover (all arrs clean)"
echo "$ICON_DONE Done — nothing to recover (all arrs clean)"
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
+5 -9
View File
@@ -136,9 +136,6 @@ fi
# ==============================================================================================
# ━━━ Setup ━━━
# ==============================================================================================
echo ""
echo "━━━ $ICON_GEAR Setup ━━━"
if [[ "$EUID" -ne 0 ]]; then
error "Must be run as root"
exit 1
@@ -347,7 +344,7 @@ SCAN_CMD_ID=$(echo "$SCAN_RESPONSE" | jq -r '.id // empty' 2>/dev/null)
if [[ -z "$SCAN_CMD_ID" ]]; then
warn "Could not trigger import scan — proceeding without pre-flight"
else
echo " Import scan queued (command ID: $SCAN_CMD_ID) — waiting for completion..."
log " Import scan queued (command ID: $SCAN_CMD_ID) — waiting for completion..."
POLL_TIMEOUT=${LIDARR_IMPORT_SCAN_TIMEOUT:-600}
POLLED=0
while [[ "$POLLED" -lt "$POLL_TIMEOUT" ]]; do
@@ -382,7 +379,7 @@ fi
# Safety Layer 3 — API version check
check_arr_version "$LIDARR_URL" "$LIDARR_API_KEY" "v1" "$LIDARR_VERSION_MAJOR" "Lidarr" || exit 1
echo " Querying Lidarr API..."
log " Querying Lidarr API..."
# Fetch all artists
ARTIST_RESPONSE=$(lidarr_api "artist") || {
@@ -443,7 +440,7 @@ if [[ "$TRACKED_COUNT" -eq 0 ]]; then
exit 1
fi
echo " $ARTIST_COUNT artists | $TRACKED_COUNT tracked files"
log " $ARTIST_COUNT artists | $TRACKED_COUNT tracked files"
# Safety Layer 6 — percentage drop vs last known count
if [[ -f "$LIDARR_TRACKED_COUNT_FILE" ]]; then
@@ -471,8 +468,7 @@ echo "$TRACKED_COUNT" > "$LIDARR_TRACKED_COUNT_FILE"
# ==============================================================================================
echo ""
echo "━━━ $ICON_CLEAN Scanning Music Root ━━━"
echo " Root: $LIDARR_MUSIC_ROOT | Orphan age: ${LIDARR_ORPHAN_AGE} days"
echo ""
log " Root: $LIDARR_MUSIC_ROOT | Orphan age: ${LIDARR_ORPHAN_AGE} days"
START=$(date +%s)
ORPHAN_COUNT=0
@@ -605,7 +601,7 @@ echo ""
if [[ "$DRY_RUN" == true ]]; then
warn "DRY RUN — no files deleted"
elif [[ "$TOTAL_REMOVED" -eq 0 ]]; then
log "$ICON_DONE Clean — nothing to remove"
echo "$ICON_DONE Clean — nothing to remove"
else
warn "$ICON_DONE Removed $TOTAL_REMOVED files (orphans: $ORPHAN_HUMAN junk: $JUNK_HUMAN)"
notify "Lidarr cleanup on $(hostname) — removed $TOTAL_REMOVED files (orphans: $ORPHAN_HUMAN junk: $JUNK_HUMAN)" "Lidarr Cleanup" "warning"
+8 -11
View File
@@ -76,9 +76,6 @@ parse_args "$@"
# ==============================================================================================
# ━━━ Setup ━━━
# ==============================================================================================
echo ""
echo "━━━ $ICON_GEAR Setup ━━━"
if [[ "$EUID" -ne 0 ]]; then
error "Must be run as root"
exit 1
@@ -110,7 +107,7 @@ if [[ -z "$LIDARR_URL" ]]; then
exit 0
fi
echo " $MY_ID ($LOCAL_SERVER_NAME) — tools OK"
log " $MY_ID ($LOCAL_SERVER_NAME) — tools OK"
# ==============================================================================================
# ━━━ Status ━━━
@@ -218,7 +215,7 @@ if ! curl_json "$LIDARR_URL/api/v1/system/status?apikey=$LIDARR_API_KEY" | jq -e
notify "lidarr_missing_art failed — Lidarr API unreachable on $(hostname)" "Lidarr Missing Art" "warning"
exit 1
fi
echo " Reachable — $LIDARR_URL"
log " Reachable — $LIDARR_URL"
START=$(date +%s)
@@ -238,7 +235,7 @@ echo "━━━ $ICON_SYNC Building Album Directory Map ━━━"
declare -A ALBUM_DIR_MAP
_artist_list=$(curl_json "$LIDARR_URL/api/v1/artist?apikey=$LIDARR_API_KEY")
_map_artist_count=$(echo "$_artist_list" | jq '. | length')
echo " Fetching track files for $_map_artist_count artists..."
log " Fetching track files for $_map_artist_count artists..."
while IFS= read -r _artist_id; do
[[ -z "$_artist_id" ]] && continue
@@ -250,7 +247,7 @@ while IFS= read -r _artist_id; do
done < <(echo "$_artist_list" | jq -r '.[].id')
unset _artist_list _map_artist_count _artist_id _album_id _track_path
echo " Mapped ${#ALBUM_DIR_MAP[@]} albums with local tracks"
log " Mapped ${#ALBUM_DIR_MAP[@]} albums with local tracks"
# ==============================================================================================
# ━━━ Albums ━━━
@@ -267,7 +264,7 @@ if [[ -z "$albums" || "$albums" == "null" ]]; then
fi
total_albums=$(echo "$albums" | jq '. | length')
echo " Processing $total_albums albums..."
log " Processing $total_albums albums..."
while IFS=$'\t' read -r mbid artist_name album_name album_id; do
raw_dir="${ALBUM_DIR_MAP[$album_id]:-}"
@@ -335,7 +332,7 @@ wait
ALBUM_FETCHED=$(wc -l < "$LIDARR_TMP/album_fetches" 2>/dev/null || echo 0)
ALBUM_FAILED=$(wc -l < "$LIDARR_TMP/album_fails" 2>/dev/null || echo 0)
ALBUM_MISSING=$(( ALBUMS_CHECKED - ALBUMS_COMPLETE ))
echo " Checked: $ALBUMS_CHECKED | Complete: $ALBUMS_COMPLETE | Needed art: $ALBUM_MISSING | Fetched: $ALBUM_FETCHED | Failed: $ALBUM_FAILED"
log " Checked: $ALBUMS_CHECKED | Complete: $ALBUMS_COMPLETE | Needed art: $ALBUM_MISSING | Fetched: $ALBUM_FETCHED | Failed: $ALBUM_FAILED"
# ==============================================================================================
# ━━━ Artists ━━━
@@ -352,7 +349,7 @@ if [[ -z "$artists" || "$artists" == "null" ]]; then
fi
total_artists=$(echo "$artists" | jq '. | length')
echo " Processing $total_artists artists..."
log " Processing $total_artists artists..."
while IFS=$'\t' read -r local_path mbid name; do
local_path=$(translate_path "$local_path")
@@ -430,7 +427,7 @@ wait
ARTIST_FETCHED=$(wc -l < "$LIDARR_TMP/artist_fetches" 2>/dev/null || echo 0)
ARTIST_FAILED=$(wc -l < "$LIDARR_TMP/artist_fails" 2>/dev/null || echo 0)
ARTIST_MISSING=$(( ARTISTS_CHECKED - ARTISTS_COMPLETE ))
echo " Checked: $ARTISTS_CHECKED | Complete: $ARTISTS_COMPLETE | Needed art: $ARTIST_MISSING | Fetched: $ARTIST_FETCHED | Failed: $ARTIST_FAILED"
log " Checked: $ARTISTS_CHECKED | Complete: $ARTISTS_COMPLETE | Needed art: $ARTIST_MISSING | Fetched: $ARTIST_FETCHED | Failed: $ARTIST_FAILED"
END=$(date +%s)
+1 -4
View File
@@ -88,9 +88,6 @@ parse_args "${RAW_ARGS[@]}"
# ==============================================================================================
# ━━━ Setup ━━━
# ==============================================================================================
echo ""
echo "━━━ $ICON_GEAR Setup ━━━"
if [[ "$EUID" -ne 0 ]]; then
error "Must be run as root"
exit 1
@@ -247,7 +244,7 @@ elif [[ ${#FAILED[@]} -gt 0 ]]; then
notify "Media cleaner ($PROFILE) failed on $(hostname)${FAILED[*]}" \
"Media Cleaner" "warning"
elif [[ "$TOTAL_REMOVED" -eq 0 ]]; then
log "$ICON_DONE Status: clean — nothing to remove"
echo "$ICON_DONE Status: clean — nothing to remove"
else
warn "$ICON_TRASH Removed: $TOTAL_REMOVED file(s)"
notify "Media cleaner ($PROFILE) on $(hostname)$TOTAL_REMOVED file(s) removed" \
-3
View File
@@ -65,9 +65,6 @@ parse_args "$@"
# ==============================================================================================
# ━━━ Setup ━━━
# ==============================================================================================
echo ""
echo "━━━ $ICON_GEAR Setup ━━━"
if [[ "$EUID" -ne 0 ]]; then
error "Must be run as root"
exit 1
+5 -9
View File
@@ -125,9 +125,6 @@ fi
# ==============================================================================================
# ━━━ Setup ━━━
# ==============================================================================================
echo ""
echo "━━━ $ICON_GEAR Setup ━━━"
if [[ "$EUID" -ne 0 ]]; then
error "Must be run as root"
exit 1
@@ -333,7 +330,7 @@ SCAN_CMD_ID=$(echo "$SCAN_RESPONSE" | jq -r '.id // empty' 2>/dev/null)
if [[ -z "$SCAN_CMD_ID" ]]; then
warn "Could not trigger import scan — proceeding without pre-flight"
else
echo " Import scan queued (command ID: $SCAN_CMD_ID) — waiting for completion..."
log " Import scan queued (command ID: $SCAN_CMD_ID) — waiting for completion..."
POLL_TIMEOUT=${RADARR_IMPORT_SCAN_TIMEOUT:-600}
POLLED=0
while [[ "$POLLED" -lt "$POLL_TIMEOUT" ]]; do
@@ -368,7 +365,7 @@ fi
# Safety Layer 3 — API version check
check_arr_version "$RADARR_URL" "$RADARR_API_KEY" "v3" "$RADARR_VERSION_MAJOR" "Radarr" || exit 1
echo " Querying Radarr API..."
log " Querying Radarr API..."
# Fetch all movies
MOVIES_RESPONSE=$(radarr_api "movie") || {
@@ -433,15 +430,14 @@ if [[ "$TRACKED_COUNT" -eq 0 ]]; then
exit 1
fi
echo " $MOVIE_COUNT movies | $TRACKED_COUNT tracked movie files"
log " $MOVIE_COUNT movies | $TRACKED_COUNT tracked movie files"
# ==============================================================================================
# ━━━ Scan Movies Root ━━━
# ==============================================================================================
echo ""
echo "━━━ $ICON_CLEAN Scanning Movies Root ━━━"
echo " Root: $RADARR_MOVIES_ROOT | Orphan age: ${RADARR_ORPHAN_AGE} days"
echo ""
log " Root: $RADARR_MOVIES_ROOT | Orphan age: ${RADARR_ORPHAN_AGE} days"
START=$(date +%s)
ORPHAN_COUNT=0
@@ -571,7 +567,7 @@ echo ""
if [[ "$DRY_RUN" == true ]]; then
warn "DRY RUN — no files deleted"
elif [[ "$TOTAL_REMOVED" -eq 0 ]]; then
log "$ICON_DONE Clean — nothing to remove"
echo "$ICON_DONE Clean — nothing to remove"
else
warn "$ICON_DONE Removed $TOTAL_REMOVED files (orphans: $ORPHAN_HUMAN junk: $JUNK_HUMAN)"
notify "Radarr cleanup on $(hostname) — removed $TOTAL_REMOVED files (orphans: $ORPHAN_HUMAN junk: $JUNK_HUMAN)" \
+3 -6
View File
@@ -76,9 +76,6 @@ parse_args "${FILTERED_ARGS[@]}"
# ==============================================================================================
# ━━━ Setup ━━━
# ==============================================================================================
echo ""
echo "━━━ $ICON_GEAR Setup ━━━"
if [[ "$EUID" -ne 0 ]]; then
error "Must be run as root"
exit 1
@@ -176,9 +173,9 @@ while IFS=$'\t' read -r id title year tmdb_id has_file file_size; do
SIZE_HUMAN=""
if [[ "$has_file" == "true" && "$file_size" -gt 0 ]]; then
SIZE_HUMAN=$(awk "BEGIN {printf \"%.1fGB\", $file_size / 1073741824}")
echo "$ICON_WARN $title ($year) [tmdbid $tmdb_id] — HAS FILE: $SIZE_HUMAN"
log "$ICON_WARN $title ($year) [tmdbid $tmdb_id] — HAS FILE: $SIZE_HUMAN"
else
echo "$ICON_TRASH $title ($year) [tmdbid $tmdb_id] — no file"
log "$ICON_TRASH $title ($year) [tmdbid $tmdb_id] — no file"
fi
if [[ "$DRY_RUN" == true ]]; then
@@ -242,7 +239,7 @@ echo "$ICON_TRASH Removed: ${#REMOVED[@]} of $DROPPED"
if [[ "$DRY_RUN" == true ]]; then
warn "DRY RUN — no changes made"
elif [[ ${#FAILED[@]} -eq 0 ]]; then
log "$ICON_DONE Status: done ✅"
echo "$ICON_DONE Status: done ✅"
else
warn "Status: ${#FAILED[@]} removal(s) failed"
fi
+5 -9
View File
@@ -125,9 +125,6 @@ fi
# ==============================================================================================
# ━━━ Setup ━━━
# ==============================================================================================
echo ""
echo "━━━ $ICON_GEAR Setup ━━━"
if [[ "$EUID" -ne 0 ]]; then
error "Must be run as root"
exit 1
@@ -333,7 +330,7 @@ SCAN_CMD_ID=$(echo "$SCAN_RESPONSE" | jq -r '.id // empty' 2>/dev/null)
if [[ -z "$SCAN_CMD_ID" ]]; then
warn "Could not trigger import scan — proceeding without pre-flight"
else
echo " Import scan queued (command ID: $SCAN_CMD_ID) — waiting for completion..."
log " Import scan queued (command ID: $SCAN_CMD_ID) — waiting for completion..."
POLL_TIMEOUT=${SONARR_IMPORT_SCAN_TIMEOUT:-600}
POLLED=0
while [[ "$POLLED" -lt "$POLL_TIMEOUT" ]]; do
@@ -368,7 +365,7 @@ fi
# Safety Layer 3 — API version check
check_arr_version "$SONARR_URL" "$SONARR_API_KEY" "v3" "$SONARR_VERSION_MAJOR" "Sonarr" || exit 1
echo " Querying Sonarr API..."
log " Querying Sonarr API..."
# Fetch all series
SERIES_RESPONSE=$(sonarr_api "series") || {
@@ -432,15 +429,14 @@ if [[ "$TRACKED_COUNT" -eq 0 ]]; then
exit 1
fi
echo " $SERIES_COUNT series | $TRACKED_COUNT tracked episode files"
log " $SERIES_COUNT series | $TRACKED_COUNT tracked episode files"
# ==============================================================================================
# ━━━ Scan TV Root ━━━
# ==============================================================================================
echo ""
echo "━━━ $ICON_CLEAN Scanning TV Root ━━━"
echo " Root: $SONARR_TV_ROOT | Orphan age: ${SONARR_ORPHAN_AGE} days"
echo ""
log " Root: $SONARR_TV_ROOT | Orphan age: ${SONARR_ORPHAN_AGE} days"
START=$(date +%s)
ORPHAN_COUNT=0
@@ -570,7 +566,7 @@ echo ""
if [[ "$DRY_RUN" == true ]]; then
warn "DRY RUN — no files deleted"
elif [[ "$TOTAL_REMOVED" -eq 0 ]]; then
log "$ICON_DONE Clean — nothing to remove"
echo "$ICON_DONE Clean — nothing to remove"
else
warn "$ICON_DONE Removed $TOTAL_REMOVED files (orphans: $ORPHAN_HUMAN junk: $JUNK_HUMAN)"
notify "Sonarr cleanup on $(hostname) — removed $TOTAL_REMOVED files (orphans: $ORPHAN_HUMAN junk: $JUNK_HUMAN)" \
+3 -6
View File
@@ -75,9 +75,6 @@ parse_args "${FILTERED_ARGS[@]}"
# ==============================================================================================
# ━━━ Setup ━━━
# ==============================================================================================
echo ""
echo "━━━ $ICON_GEAR Setup ━━━"
if [[ "$EUID" -ne 0 ]]; then
error "Must be run as root"
exit 1
@@ -178,9 +175,9 @@ while IFS=$'\t' read -r id title year tvdb_id episode_file_count size_on_disk; d
fi
if [[ "$episode_file_count" -gt 0 ]]; then
echo "$ICON_WARN $title ($year) [tvdbid $tvdb_id] — $episode_file_count episode files${SIZE_HUMAN:+, $SIZE_HUMAN}"
log "$ICON_WARN $title ($year) [tvdbid $tvdb_id] — $episode_file_count episode files${SIZE_HUMAN:+, $SIZE_HUMAN}"
else
echo "$ICON_TRASH $title ($year) [tvdbid $tvdb_id] — no files"
log "$ICON_TRASH $title ($year) [tvdbid $tvdb_id] — no files"
fi
if [[ "$DRY_RUN" == true ]]; then
@@ -244,7 +241,7 @@ echo "$ICON_TRASH Removed: ${#REMOVED[@]} of $DROPPED"
if [[ "$DRY_RUN" == true ]]; then
warn "DRY RUN — no changes made"
elif [[ ${#FAILED[@]} -eq 0 ]]; then
log "$ICON_DONE Status: done ✅"
echo "$ICON_DONE Status: done ✅"
else
warn "Status: ${#FAILED[@]} removal(s) failed"
fi