Compare commits

...

6 Commits

2 changed files with 88 additions and 78 deletions

View File

@ -1,45 +1,47 @@
# Bash Music sync # Bash Music sync
(c) 2018-2019 Jeroen De Meerleer <me@jeroened.be> (c) 2018-2020 Jeroen De Meerleer <me@jeroened.be>
Script to sync music from one folder to another Script to sync music from one folder to another
## Usage: ## Usage:
``` ```
music-sync <options> -s|--source <source> -d|--dest <destination> Syncronises music from one folder to another.
music-sync <options> <source> <destination>
Syncronises music from one folder to another. Usage:
music-sync <options> -s|--source <source> -d|--dest <destination>
music-sync <options> <source> <destination>
Options: Options:
-s, --source <source> The source folder of the music -s, --source <source> The source folder of the music
-d, --dest <destination> The destination folder of the music -d, --dest <destination> The destination folder of the music
-t, --temp <folder> The temporary cache for converted files (default: /tmp/converted) -t, --temp <folder> The temporary cache for converted files (default: /tmp/converted)
-c, --convert <bitrate> Convert files to a given bitrate in kbps before syncing (default: 192) -c, --convert <bitrate> Convert files to a given bitrate in kbps before syncing (default: 192)
-a, --resize-art <width> Resize album-art before syncing (default width: 200) -a, --resize-art <width> Resize album-art before syncing (default width: 200)
-v, --verbose <0-6> Set log level (default: 2) -j, --jobs <nproc> Number of processes to use in multi-threading (default: nproc - 2)
-h, --help Display this help text -v, --verbose <0-6> Set log level (default: 2)
-h, --help Display this help text
Log levels: Log levels:
0 | Verbose 0 | Verbose
1 | Debug 1 | Debug
2 | Info 2 | Info
3 | Warning 3 | Warning
4 | Error 4 | Error
5 | Fatal 5 | Fatal
6 | Silence 6 | Silence
Exit Codes: Exit Codes:
1 Dependencies not met 1 Dependencies not met
2 Invalid Argument 2 Invalid Argument
3 Source Unreachable 3 Source Unreachable
4 Destination Unreachable 4 Destination Unreachable
5 Command failed 5 Command failed
``` ```
## Licence ## Licence
Copyright 2018-2019 Jeroen De Meerleer <me@jeroened.be> Copyright 2018-2020 Jeroen De Meerleer <me@jeroened.be>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View File

@ -13,7 +13,7 @@
#/ -t, --temp <folder> The temporary cache for converted files (default: /tmp/converted) #/ -t, --temp <folder> The temporary cache for converted files (default: /tmp/converted)
#/ -c, --convert <bitrate> Convert files to a given bitrate in kbps before syncing (default: 192) #/ -c, --convert <bitrate> Convert files to a given bitrate in kbps before syncing (default: 192)
#/ -a, --resize-art <width> Resize album-art before syncing (default width: 200) #/ -a, --resize-art <width> Resize album-art before syncing (default width: 200)
#/ -j, --jobs <nproc> Number of processes to use in multi-threading (default: CPU_CORES - 2) #/ -j, --jobs <nproc> Number of processes to use in multi-threading (default: nproc - 2)
#/ -v, --verbose <0-6> Set log level (default: 2) #/ -v, --verbose <0-6> Set log level (default: 2)
#/ -h, --help Display this help text #/ -h, --help Display this help text
#/ #/
@ -46,13 +46,13 @@ help=false
temp="/tmp/converted" temp="/tmp/converted"
convertart=false convertart=false
coverartsize=200 coverartsize=200
jobcount="-2" jobcount=$(expr $(nproc) - 2)
multithread=false multithread=false
script_name=$(basename "${0}") script_name=$(basename "${0}")
script_dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) script_dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
CheckDeps() { CheckDeps() {
if [[ $1 == 0 ]]; then if [[ $1 == 2 ]]; then
# Check getopt # Check getopt
! getopt --test > /dev/null ! getopt --test > /dev/null
if [[ ${PIPESTATUS[0]} -ne 4 ]]; then if [[ ${PIPESTATUS[0]} -ne 4 ]]; then
@ -67,48 +67,56 @@ CheckDeps() {
if [[ $1 == 1 ]]; then if [[ $1 == 1 ]]; then
# Check ffmpeg # Check ffmpeg
if [[ $convert == true && ! $(ffmpeg -h 2>/dev/null) ]]; then if [[ $convert == true ]]; then
VerboseOutput 5 "\`ffmpeg -h\` failed" if [[ ! $(ffmpeg -h 2>/dev/null) ]]; then
VerboseOutput 5 "Sorry, It seems that ffmpeg is not installed on your system" VerboseOutput 5 "\`ffmpeg -h\` failed"
VerboseOutput 5 "Please install ffmpeg from your repositories and make sure it is available in your \$PATH" VerboseOutput 5 "Sorry, It seems that ffmpeg is not installed on your system"
VerboseOutput 5 "Otherwise disable conversion" VerboseOutput 5 "Please install ffmpeg from your repositories and make sure it is available in your \$PATH"
ExecTime VerboseOutput 5 "Otherwise disable conversion"
exit 1 ExecTime
exit 1
fi
VerboseOutput 0 "\`ffmpeg -h\` succeeded"
fi fi
VerboseOutput 0 "\`ffmpeg -h\` succeeded"
# Check EyeD3 # Check EyeD3
if [[ $convertart == true && ! $(eyeD3 --version 2>/dev/null) ]]; then if [[ $convertart == true ]]; then
VerboseOutput 5 "\`eyeD3 --version\` failed" if [[ ! $(eyeD3 --version 2>/dev/null) ]]; then
VerboseOutput 5 "Sorry, It seems that eyeD3 is not installed on your system" VerboseOutput 5 "\`eyeD3 --version\` failed"
VerboseOutput 5 "Please install eyeD3 from your repositories and make sure it is available in your \$PATH" VerboseOutput 5 "Sorry, It seems that eyeD3 is not installed on your system"
VerboseOutput 5 "Otherwise disable albumart conversion" VerboseOutput 5 "Please install eyeD3 from your repositories and make sure it is available in your \$PATH"
ExecTime VerboseOutput 5 "Otherwise disable albumart conversion"
exit 1 ExecTime
exit 1
fi
VerboseOutput 0 "\`eyeD3 --version\` succeeded"
fi fi
VerboseOutput 0 "\`eyeD3 --version\` succeeded"
# Check ImageMagick # Check ImageMagick
if [[ $convertart == true && ! $(convert --version 2>/dev/null) ]]; then if [[ $convertart == true ]]; then
VerboseOutput 5 "\`convert --version\` failed" if [[ ! $(convert --version 2>/dev/null) ]]; then
VerboseOutput 5 "Sorry, It seems that ImageMagick is not installed on your system" VerboseOutput 5 "\`convert --version\` failed"
VerboseOutput 5 "Please install ImageMagick from your repositories and make sure it is available in your \$PATH" VerboseOutput 5 "Sorry, It seems that ImageMagick is not installed on your system"
VerboseOutput 5 "Otherwise disable albumart conversion" VerboseOutput 5 "Please install ImageMagick from your repositories and make sure it is available in your \$PATH"
ExecTime VerboseOutput 5 "Otherwise disable albumart conversion"
exit 1 ExecTime
exit 1
fi
VerboseOutput 0 "\`convert --version\` succeeded"
fi fi
VerboseOutput 0 "\`convert --version\` succeeded"
# Check Gnu parallel # Check Gnu parallel
if [[ $multithread == true && ! $(parallel -h 2>/dev/null) ]]; then if [[ $multithread == true ]]; then
VerboseOutput 5 "\`parallel -h\` failed" if [[ ! $(parallel -h 2>/dev/null) ]]; then
VerboseOutput 5 "Sorry, It seems that parallel is not installed on your system" VerboseOutput 5 "\`parallel -h\` failed"
VerboseOutput 5 "Please install gnu-parallel and env_parallel from your repositories and make sure it is available in your \$PATH" VerboseOutput 5 "Sorry, It seems that parallel is not installed on your system"
VerboseOutput 5 "Otherwise disable multithreading" VerboseOutput 5 "Please install gnu-parallel and env_parallel from your repositories and make sure it is available in your \$PATH"
ExecTime VerboseOutput 5 "Otherwise disable multithreading"
exit 1 ExecTime
exit 1
fi
VerboseOutput 0 "\`parallel -h \` succeeded"
fi fi
VerboseOutput 0 "\`parallel -h \` succeeded"
fi fi
VerboseOutput 1 "Dependency test OK" VerboseOutput 1 "Dependency test OK"
} }
@ -141,9 +149,8 @@ GetOptions() {
verbose=2 verbose=2
if [[ $2 != "" ]]; then if [[ $2 != "" ]]; then
verbose=${2} verbose=${2}
shift
fi fi
shift shift 2
;; ;;
-h|--help) -h|--help)
help=true help=true
@ -173,10 +180,9 @@ GetOptions() {
bitrate=192 bitrate=192
if [[ $2 != "" ]]; then if [[ $2 != "" ]]; then
bitrate=${2} bitrate=${2}
shift
fi fi
VerboseOutput 1 "Converted bitrate is ${bitrate}" VerboseOutput 1 "Converted bitrate is ${bitrate}"
shift shift 2
;; ;;
-a|--resize-art) -a|--resize-art)
VerboseOutput 0 "--resize-art given" VerboseOutput 0 "--resize-art given"
@ -184,21 +190,19 @@ GetOptions() {
coverartsize=200 coverartsize=200
if [[ $2 != "" ]]; then if [[ $2 != "" ]]; then
coverartsize=${2} coverartsize=${2}
shift
fi fi
shift shift 2
VerboseOutput 1 "Album art will ${coverartsize}px wide" VerboseOutput 1 "Album art will ${coverartsize}px wide"
;; ;;
-j|--jobs) -j|--jobs)
VerboseOutput 0 "--jobs given" VerboseOutput 0 "--jobs given"
multithread=true multithread=true
jobcount="-2" jobcount=$(expr $(nproc) - 2)
if [[ $2 != "" ]]; then if [[ $2 != "" ]]; then
jobcount=${2} jobcount=${2}
shift
fi fi
shift shift 2
VerboseOutput 1 "multithreading will use ${jobcount} threads" VerboseOutput 1 "Multithreading will use ${jobcount} threads"
;; ;;
--) --)
shift shift
@ -274,7 +278,7 @@ CreateFileList() {
sourcepath="${sourcepath/\]/\\\]}" sourcepath="${sourcepath/\]/\\\]}"
for file in $sourcepath; do for file in $sourcepath; do
origfile="${file#"$1/"}" origfile="${file#"$1/"}"
relfile=$(echo ${origfile} | sed -e 's/\(\.\)*$//g') relfile=$(echo ${origfile} | sed -e 's/\(\.\)*$//g' | tr -s ' ')
mp3file=$(echo "${relfile}" | sed -e 's/.flac/.mp3/') mp3file=$(echo "${relfile}" | sed -e 's/.flac/.mp3/')
VerboseOutput 0 "Checking ${origfile}" VerboseOutput 0 "Checking ${origfile}"
if [[ -d "${1}/$origfile" ]]; then if [[ -d "${1}/$origfile" ]]; then
@ -315,11 +319,10 @@ Execute() {
export verbose export verbose
export coverartsize export coverartsize
export begin export begin
parallel --jobs ${jobcount} --line-buffer --arg-file "/tmp/music-sync-filelist" ProcessFile parallel --jobs ${jobcount} --will-cite --line-buffer --arg-file "/tmp/music-sync-filelist" ProcessFile
else else
for line in $(cat "/tmp/music-sync-filelist") for line in $(cat "/tmp/music-sync-filelist")
do do
curline=$(expr ${curline} + 1) curline=$(expr ${curline} + 1)
total=$(cat /tmp/music-sync-filelist | wc -l) total=$(cat /tmp/music-sync-filelist | wc -l)
percentage=$(echo "scale=4;${curline}/${total}" | bc) percentage=$(echo "scale=4;${curline}/${total}" | bc)
@ -333,7 +336,12 @@ Execute() {
} }
ProcessFile() { ProcessFile() {
line=${1} line=${1}
curline="$(grep -n "$line" /tmp/music-sync-filelist | head -n 1 | cut -d: -f1)"
total=$(cat /tmp/music-sync-filelist | wc -l)
percentage=$(echo "scale=4;${curline}/${total}" | bc)
percentage=$(echo "scale=2;${percentage}*100" | bc)
VerboseOutput 2 "Current File: $line" VerboseOutput 2 "Current File: $line"
VerboseOutput 2 "Progress: $curline / $total (${percentage%00}%)"
if [[ $convert == true ]]; then if [[ $convert == true ]]; then
ConvertFile "$line" ConvertFile "$line"
fi fi
@ -402,7 +410,7 @@ CopyFile() {
exit 3 exit 3
fi fi
destline=$(echo $mp3line | sed -e 's/\.*\//\//g') destline=$(echo $mp3line | sed -e 's/\.*\//\//g'| tr -s ' ')
VerboseOutput 1 "Copying: $line" VerboseOutput 1 "Copying: $line"
if [[ "$dest/$line" = */* ]]; then if [[ "$dest/$line" = */* ]]; then
@ -410,7 +418,7 @@ CopyFile() {
mkdir -p "$dest/${destline%/*}"; mkdir -p "$dest/${destline%/*}";
fi; fi;
cp -f "$temp/$mp3line" "$dest/${destline}" 1>/dev/null 2>/dev/null cp -fv "$temp/$mp3line" "$dest/${destline}" 1>/dev/null 2>/dev/null
VerboseOutput 1 "Copied: $line" VerboseOutput 1 "Copied: $line"
} }
@ -446,7 +454,7 @@ ExitHandler() {
trap 'ExitHandler' SIGINT trap 'ExitHandler' SIGINT
trap 'ErrorHandler $BASH_COMMAND' ERR trap 'ErrorHandler $BASH_COMMAND' ERR
CheckDeps 0 CheckDeps 2
GetOptions $@ GetOptions $@
CheckDeps 1 CheckDeps 1
if [[ $help == true ]]; then if [[ $help == true ]]; then