Skip to content

Instantly share code, notes, and snippets.

@dshoreman
Created June 14, 2022 03:45
Show Gist options
  • Save dshoreman/b7b89e6070537bcc6a31e94135c0800d to your computer and use it in GitHub Desktop.
Save dshoreman/b7b89e6070537bcc6a31e94135c0800d to your computer and use it in GitHub Desktop.
A script to scan multiple music sources with mp3check, moving only error-free albums/artists to the library.
#!/usr/bin/env bash
ROOT=/vault/media
PREFIX=music-from-
TARGET=$ROOT/music
COLLECTIONS=(main)
main() {
for collection in "${COLLECTIONS[@]}"; do
echo -e "\n Processing $collection/"
cd "$ROOT/$PREFIX$collection" || { err "Missing collection '$collection'"; continue; }
for artist in *; do
cd "$ROOT/$PREFIX$collection" || { err "Collection disappeared!"; return 1; }
if [[ ! -d "$artist" ]]; then
skip top "$artist" "not a directory"
elif [[ -d "$TARGET/$collection" ]]; then
run_partial "$collection" "$artist"
else
run_full "$collection" "$artist"
fi
sleep 0.5
done
done
}
run_full() {
local collection="$1" artist="$2"
if is_unsupported "$artist"; then
warn "top" "$artist" "found unsupported files"
elif fails_check "$artist"; then
warn "top" "$artist" "failed mp3check"
else
mv "$artist" "$TARGET/" || { err "Failed moving files"; return 1; }
pass "top" "$artist" "Checks passed! All albums relocated"
return
fi
info "Falling back to partial mode..."
run_partial "$collection" "$artist"
}
run_partial(){
local collection="$1" artist="$2" album
cd "$ROOT/$PREFIX$collection/$artist" || { err "cd to artist dir failed"; return 1; }
(( 0 < $(find . -mindepth 1 -maxdepth 1 -type d | wc -l) )) || \
{ skip nest "" "No albums!"; return 1; }
for album in *; do
if is_unsupported "$album"; then
err nest "$album" "unsupported files"
elif fails_check "$album"; then
err nest "$album" "files have errors"
elif [[ -d "$TARGET/$artist/$album" ]]; then
err nest "$album" "album exists already!"
# rsync -aAXH "$album" "$TARGET/$artist" || echo "Failed moving files"
else
[[ -d "$TARGET/$artist" ]] || mkdir -p "$TARGET/$artist"
pass nest "$album"
mv "$album" "$TARGET/$artist/" || { err "Failed moving files"; continue; }
fi
done
}
fails_check() {
! mp3check -BEerGoqsS -m1 -A m4a,mp3,Mp3,MP3 "$1"
}
is_unsupported() {
local badfiles
badfiles="$(find "$1" -type f \
! -iname '*.mp3' ! -iname '*.m4a' \
! -iname '*.jpg' ! -iname '*.jpeg' ! -iname '*.bmp')"
[[ $badfiles != "" ]]
}
colourise() {
local args=() type="$1" title="" pos="$2" title="$3" tree=""; shift
case $type in
info) esc=36; lbl=" "; pos="info"; title="$*" ;;
pass) esc=32; lbl="SUCCESS";;
skip) esc=33; lbl="SKIPPED";;
warn) esc=33; lbl="WARNING";;
err) esc=31; lbl="[ERROR]";;
esac
case "$pos" in
top) tree="├─"; shift 2 ;;
info) tree="│ │ "; shift 2 ;;
nest) tree="│ ├─"; shift 2 ;;
esac
if [[ $type == "info" ]]; then
printf " \e[%dm[%s]\e[0m %s\e[%dm└ %s\e[0m\n" $esc "$lbl" "$tree" $esc "$title"
else
printf " \e[%dm[%s]\e[0m %s %-95s \e[%dm%s\e[0m\n" $esc "$lbl" "$tree" "$title/" $esc "$*"
fi
}
info() { colourise "info" "$*"; }
pass() { colourise "pass" "$@"; }
skip() { colourise "skip" "$@"; }
warn() { colourise "warn" "$@"; }
err() { colourise "err" "$@"; }
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment