175 lines
3.7 KiB
Bash
175 lines
3.7 KiB
Bash
#!/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 ]]
|