feat: Add batch runner and priority list
This commit is contained in:
1 parent
568795e364
commit
ec23bf6d2d
3 files changed
+304
No files matched your search
@@ -0,0 +1,174 @@
|
||||
#!/usr/bin/env bash
|
||||
set -uo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
./batch.sh scan LIST.txt [--base '/source/base']
|
||||
./batch.sh recover LIST.txt [--base '/source/base']
|
||||
|
||||
Examples:
|
||||
./batch.sh scan priority.txt
|
||||
./batch.sh recover priority.txt
|
||||
./batch.sh scan priority.txt --base '/Media'
|
||||
./batch.sh recover priority.txt --base '/Media'
|
||||
EOF
|
||||
}
|
||||
|
||||
if [[ $# -lt 2 || $# -gt 4 ]]; then
|
||||
usage >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
MODE="$1"
|
||||
LIST_FILE="$2"
|
||||
shift 2
|
||||
|
||||
BASE=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--base)
|
||||
[[ $# -ge 2 ]] || { echo "ERROR: --base requires a path." >&2; exit 2; }
|
||||
BASE="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: Unknown argument: $1" >&2
|
||||
usage >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
case "$MODE" in
|
||||
scan|recover) ;;
|
||||
*) echo "ERROR: mode must be 'scan' or 'recover'." >&2; exit 2 ;;
|
||||
esac
|
||||
|
||||
[[ -f "$LIST_FILE" ]] || { echo "ERROR: list file not found: $LIST_FILE" >&2; exit 1; }
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
WORKER="$SCRIPT_DIR/${MODE}.sh"
|
||||
|
||||
[[ -x "$WORKER" ]] || {
|
||||
echo "ERROR: expected executable worker beside batch.sh: $WORKER" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [[ -n "$BASE" ]]; then
|
||||
[[ "$BASE" == /* ]] || BASE="/$BASE"
|
||||
BASE="${BASE%/}"
|
||||
fi
|
||||
|
||||
if [[ -d /mnt/recovery && -w /mnt/recovery ]]; then
|
||||
LOG_DIR="/mnt/recovery"
|
||||
else
|
||||
LOG_DIR="$(cd -- "$(dirname -- "$LIST_FILE")" && pwd)"
|
||||
fi
|
||||
|
||||
STAMP="$(date '+%Y%m%d-%H%M%S')"
|
||||
LIST_BASENAME="$(basename -- "$LIST_FILE")"
|
||||
LIST_STEM="${LIST_BASENAME%.*}"
|
||||
LOG_FILE="$LOG_DIR/batch-${MODE}-${LIST_STEM}-${STAMP}.log"
|
||||
SUMMARY_FILE="$LOG_DIR/batch-${MODE}-${LIST_STEM}-${STAMP}-summary.txt"
|
||||
|
||||
declare -A SEEN=()
|
||||
|
||||
total=0
|
||||
ok=0
|
||||
failed=0
|
||||
ignored=0
|
||||
|
||||
{
|
||||
echo "Generic Plex Salvage Batch"
|
||||
echo "=========================="
|
||||
echo "Mode: $MODE"
|
||||
echo "List: $LIST_FILE"
|
||||
echo "Base: ${BASE:-<none>}"
|
||||
echo "Started: $(date -Is)"
|
||||
echo
|
||||
} | tee -a "$LOG_FILE"
|
||||
|
||||
while IFS= read -r raw || [[ -n "$raw" ]]; do
|
||||
line="${raw%$'\r'}"
|
||||
line="${line#"${line%%[![:space:]]*}"}"
|
||||
line="${line%"${line##*[![:space:]]}"}"
|
||||
|
||||
if [[ -z "$line" || "$line" == \#* ]]; then
|
||||
((ignored+=1))
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$line" == /* ]]; then
|
||||
source_path="$line"
|
||||
else
|
||||
if [[ -z "$BASE" ]]; then
|
||||
((total+=1))
|
||||
((failed+=1))
|
||||
echo "FAILED: relative entry requires --base: $line" | tee -a "$LOG_FILE"
|
||||
continue
|
||||
fi
|
||||
source_path="$BASE/$line"
|
||||
fi
|
||||
|
||||
while [[ "$source_path" == *"//"* ]]; do
|
||||
source_path="${source_path//\/\//\/}"
|
||||
done
|
||||
|
||||
if [[ -n "${SEEN[$source_path]+x}" ]]; then
|
||||
((ignored+=1))
|
||||
echo "SKIP duplicate: $source_path" | tee -a "$LOG_FILE"
|
||||
continue
|
||||
fi
|
||||
SEEN["$source_path"]=1
|
||||
|
||||
((total+=1))
|
||||
|
||||
{
|
||||
echo "----------------------------------------------------------------"
|
||||
echo "[$total] ${MODE^^}: $source_path"
|
||||
echo "Started: $(date -Is)"
|
||||
} | tee -a "$LOG_FILE"
|
||||
|
||||
set +e
|
||||
"$WORKER" "$source_path" 2>&1 | tee -a "$LOG_FILE"
|
||||
rc=${PIPESTATUS[0]}
|
||||
set -e
|
||||
|
||||
if [[ $rc -eq 0 ]]; then
|
||||
((ok+=1))
|
||||
echo "RESULT: OK ($source_path)" | tee -a "$LOG_FILE"
|
||||
else
|
||||
((failed+=1))
|
||||
echo "RESULT: FAILED rc=$rc ($source_path)" | tee -a "$LOG_FILE"
|
||||
fi
|
||||
|
||||
echo "Finished: $(date -Is)" | tee -a "$LOG_FILE"
|
||||
echo | tee -a "$LOG_FILE"
|
||||
done < "$LIST_FILE"
|
||||
|
||||
{
|
||||
echo "GENERIC PLEX SALVAGE BATCH SUMMARY"
|
||||
echo "=================================="
|
||||
echo "Mode: $MODE"
|
||||
echo "List: $LIST_FILE"
|
||||
echo "Base: ${BASE:-<none>}"
|
||||
echo "Completed: $(date -Is)"
|
||||
echo
|
||||
echo "Processed: $total"
|
||||
echo "Succeeded: $ok"
|
||||
echo "Failed: $failed"
|
||||
echo "Ignored: $ignored"
|
||||
echo
|
||||
echo "Full log: $LOG_FILE"
|
||||
} | tee "$SUMMARY_FILE"
|
||||
|
||||
echo
|
||||
echo "Summary: $SUMMARY_FILE"
|
||||
|
||||
[[ $failed -eq 0 ]]
|
||||
Reference in new issue
Block a user