diff --git a/home/bin/sync-music b/home/bin/sync-music old mode 100644 new mode 100755 index 7facbfc..3b65dd1 --- a/home/bin/sync-music +++ b/home/bin/sync-music @@ -54,6 +54,11 @@ if [ ! -d "$MOUNT_POINT" ]; then fi # --- 2. import every (finished) audio file in ~/Music --- +# NOTE: We do NOT clear the beets DB. Files are imported as singletons +# (--singletons) so beets never matches them against existing albums in the +# library, which is what previously made it delete the prior tracks of an +# album via the 'R' (remove old) prompt. The DB lives at +# $LIBRARY_DIR/beets/beets_library.db (per ~/.config/beets/config.yaml). log "sync-music: scanning $WATCH_DIR -> $LIBRARY_DIR" shopt -s nullglob nocaseglob @@ -80,17 +85,35 @@ for f in "${files[@]}"; do fi bn=$(basename "$f") - log " importing: $bn" - # stdin from /dev/null so beets never blocks waiting for a prompt - out=$("$BEET" import --noautotag --move --quiet "$f" &1) - rc=$? - if [ $rc -eq 0 ]; then - if [ -f "$f" ]; then - log " already in library (skipped, left in place): $bn" - else - log " moved into library: $bn" - fi + + # Pre-check: has beets already imported this file? Match by path or title. + existing="$(beet ls --path "$f" 2>/dev/null || true)" + stripped="$(echo "$bn" | sed 's/\.flac$//; s/\.mp3$//')" + if [ -n "$existing" ] || [ -n "$(beet ls "$stripped" 2>/dev/null || true)" ]; then + log " already in library (skipped): $bn" ok=$((ok + 1)) + continue + fi + + log " importing: $bn" + # Import as a singleton so beets never offers to "remove old" and delete + # other tracks from the same album. Reads confirm from stdin; with no + # matches there is no prompt, and if one does appear 'S' (=skip new) is the + # safe default that never deletes anything. + out=$(printf 'S\n' | "$BEET" import --noautotag --move --singletons "$f" 2>&1) + rc=$? + if [ $rc -eq 0 ] && [ ! -f "$f" ]; then + log " moved into library: $bn" + ok=$((ok + 1)) + elif [ $rc -eq 0 ]; then + # Import succeeded but source still exists — beets kept new file (didn't remove old) + if echo "$out" | grep -qi 'keep'; then + log " kept existing, source remains: $bn" + ok=$((ok + 1)) + else + log " IMPORTED but source still present (rc=0): $bn :: $(printf '%s' "$out" | head -c 200)" + failed=$((failed + 1)) + fi else log " FAILED (rc=$rc): $bn :: $(printf '%s' "$out" | head -c 200)" failed=$((failed + 1))