Skip to content

Instantly share code, notes, and snippets.

@s-shin
Last active August 6, 2018 18:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save s-shin/a4756cc1c22bbfb85b0ad2b2aa8f4810 to your computer and use it in GitHub Desktop.
Save s-shin/a4756cc1c22bbfb85b0ad2b2aa8f4810 to your computer and use it in GitHub Desktop.
Archive albums to specified directory in iTunes media directory.
#!/bin/bash
set -eu
: ${ITUNES_MEDIA_DIR:="${HOME}/Music/iTunes/iTunes Media"}
usage() {
cat <<EOT
Usage: $0 [options] [<re>]
Options:
-o <output_dir> output directory
-v exclude filter
Environments:
ITUNES_MEDIA_DIR="${ITUNES_MEDIA_DIR}"
EOT
}
log() { echo -ne "$(date +"%F %T") $*"; }
log.d() { log "[DEBUG] $*"; }
log.i() { log "[INFO] $*"; }
log.w() { log "[WARN] $*"; }
log.e() { log "[ERROR] $*"; }
logln() { log "$*\n"; }
logln.d() { log.d "$*\n"; }
logln.i() { log.i "$*\n"; }
logln.w() { log.w "$*\n"; }
logln.e() { log.e "$*\n"; }
abort() { >&2 log_e "abort: $*"; exit 1; }
# shellcheck disable=SC2120
confirm() {
local msg="${1:-Continue?}";
if (($# > 0)); then shift; fi
local default="${1:-n}"
log "[CONFIRM] $msg "
case "$default" in
y ) echo -n "[Y/n] ";;
n ) echo -n "[y/N] ";;
* ) abort "confirm: invalid argument";;
esac
local yn
read -r yn
case "${yn:=$default}" in
Y* | y* ) return 0;;
* ) return 1;;
esac
}
opt_nargs=0
opt_output_dir=.
opt_re=""
opt_if_or_unless=if
while (($# > 0)); do
case "$1" in
-h | --help ) usage; exit 1;;
-o ) opt_output_dir="$2"; shift;;
-v ) opt_if_or_unless=unless;;
* )
case $((++opt_nargs)) in
1 ) opt_re="$1";;
2 ) abort "too many arguments"
esac
;;
esac
shift
done
abs_music_dir="$(cd "${ITUNES_MEDIA_DIR}/Music"; pwd)"
abs_output_dir="$(cd "$opt_output_dir"; pwd)"
targets="$(cd "$abs_music_dir"; find . -type d -mindepth 2 \
| perl -ne "print $opt_if_or_unless /$opt_re/")"
logln.i "Archive targets:"
echo "$targets"
confirm
IFS_BK="$IFS"
IFS=$'\n'
for dir in $targets; do
logln.i "Processing $dir..."
artist="$(echo "$dir" | perl -ple 's#./([^/]+)/([^/]+)#$1#')"
album="$(echo "$dir" | perl -ple 's#./([^/]+)/([^/]+)#$2#')"
out_artist_dir="${abs_output_dir}/${artist}"
out_album_archive="${out_artist_dir}/${album}.tar"
mkdir -p "$out_artist_dir"
if [[ -f "$out_album_archive" ]]; then
logln.i '=> skipped (already exists)'
continue
fi
(cd "${abs_music_dir}/${artist}"; tar cvf "$out_album_archive" "${album}")
done
IFS="$IFS_BK"
logln.i 'Done!'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment