From a8e54b3a410e5b8e4a63c5f469fff7d8b2f880f9 Mon Sep 17 00:00:00 2001 From: Honey Date: Fri, 5 Jun 2026 00:40:52 +0200 Subject: [PATCH] feat: add --copy mode to reorganize-music.sh for safe migration Co-Authored-By: Claude Sonnet 4.6 --- scripts/reorganize-music.sh | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/scripts/reorganize-music.sh b/scripts/reorganize-music.sh index 9b1f44d..3c851c9 100644 --- a/scripts/reorganize-music.sh +++ b/scripts/reorganize-music.sh @@ -10,11 +10,12 @@ # backend/lib/ytdlp.js and backend/lib/metadata.js. # # Usage: -# ./reorganize-music.sh [--move] [--clean] +# ./reorganize-music.sh [--copy] [--move] [--clean] # # Root of the old genre-folder tree (searched recursively) # Music root to write into (can be the same as source) -# --move Actually move files (default: dry-run preview only) +# --copy Copy files to new location (originals kept — safe default) +# --move Move files to new location (originals removed) # --clean After moving, remove empty directories under # # Requires: ffprobe (part of ffmpeg) @@ -29,9 +30,11 @@ fi SOURCE="$(realpath "$1")" DEST="$(realpath "$2")" +DO_COPY=false DO_MOVE=false DO_CLEAN=false for arg in "${@:3}"; do + [[ "$arg" == "--copy" ]] && DO_COPY=true [[ "$arg" == "--move" ]] && DO_MOVE=true [[ "$arg" == "--clean" ]] && DO_CLEAN=true done @@ -71,9 +74,11 @@ echo "NovaSonic Music Reorganiser" echo "Source : $SOURCE" echo "Dest : $DEST" if $DO_MOVE; then - echo "Mode : MOVE (files will be moved)" + echo "Mode : MOVE (files will be moved, originals removed)" +elif $DO_COPY; then + echo "Mode : COPY (files will be copied, originals kept)" else - echo "Mode : DRY-RUN (nothing will change — add --move to execute)" + echo "Mode : DRY-RUN (nothing will change — add --copy or --move to execute)" fi echo "──────────────────────────────────────────────────────────────────────" @@ -151,6 +156,13 @@ while IFS= read -r -d '' file; do printf ' ERROR moving: %s\n' "$file" >&2 ERRORS=$((ERRORS + 1)) fi + elif $DO_COPY; then + if mkdir -p "$target_dir" && cp -- "$file" "$target"; then + MOVED=$((MOVED + 1)) + else + printf ' ERROR copying: %s\n' "$file" >&2 + ERRORS=$((ERRORS + 1)) + fi else MOVED=$((MOVED + 1)) fi @@ -162,7 +174,7 @@ done < <(find "$SOURCE" -type f \( \ \) -print0 | sort -z) # ── Remove empty source dirs (optional) ────────────────────────────────────── -if $DO_MOVE && $DO_CLEAN; then +if $DO_MOVE && $DO_CLEAN; then # --clean only applies to --move (copy keeps originals) echo "" echo "Cleaning empty directories under $SOURCE …" find "$SOURCE" -mindepth 1 -type d -empty -delete 2>/dev/null && \ @@ -173,8 +185,10 @@ fi echo "──────────────────────────────────────────────────────────────────────" if $DO_MOVE; then echo "Done: $MOVED moved, $SKIPPED skipped, $ERRORS errors" +elif $DO_COPY; then + echo "Done: $MOVED copied, $SKIPPED skipped, $ERRORS errors" else - echo "Dry-run: $MOVED would be moved, $SKIPPED already correct or conflicting" + echo "Dry-run: $MOVED would be processed, $SKIPPED already correct or conflicting" echo "" - echo "Re-run with --move to execute. Add --clean to also remove empty source dirs." + echo "Re-run with --copy to copy (safe) or --move to move. Add --clean to remove empty source dirs after --move." fi