Added playlist sync

This commit is contained in:
Jeroen De Meerleer 2020-02-16 02:18:07 +01:00
parent 61677a6c6f
commit 0e5102a160

View File

@ -8,14 +8,17 @@
#/ Syncronises music from one folder to another. #/ Syncronises music from one folder to another.
#/ #/
#/ 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)
#/ -j, --jobs <nproc> Number of processes to use in multi-threading (default: nproc - 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
#/ -p, --playlists Enable playlist sync
#/ -m, --mapping=DIR1,DIR2 Add mappings for playlists from DIR1 to DIR2
#/ -w, --windows-format Use crlf and backslashes for playlists
#/ #/
#/ Log levels: #/ Log levels:
#/ 0 | Verbose #/ 0 | Verbose
@ -50,6 +53,10 @@ 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 )
listmapping[0]=''
listmapping[1]=''
windowspaths=false
playlists=false
CheckDeps() { CheckDeps() {
if [[ $1 == 2 ]]; then if [[ $1 == 2 ]]; then
@ -110,12 +117,27 @@ CheckDeps() {
if [[ ! $(parallel -h 2>/dev/null) ]]; then if [[ ! $(parallel -h 2>/dev/null) ]]; then
VerboseOutput 5 "\`parallel -h\` failed" VerboseOutput 5 "\`parallel -h\` failed"
VerboseOutput 5 "Sorry, It seems that parallel is not installed on your system" VerboseOutput 5 "Sorry, It seems that parallel is not installed on your system"
VerboseOutput 5 "Please install gnu-parallel and env_parallel from your repositories and make sure it is available in your \$PATH" VerboseOutput 5 "Please install gnu-parallel from your repositories and make sure it is available in your \$PATH"
VerboseOutput 5 "Otherwise disable multithreading" VerboseOutput 5 "Otherwise disable multithreading"
ExecTime ExecTime
exit 1 exit 1
fi fi
VerboseOutput 0 "\`parallel -h \` succeeded" VerboseOutput 0 "\`parallel -h\` succeeded"
fi
# Check playlist requirement
if [[ $playlists == true ]]; then
if [[ $windowspaths == true ]]; then
if [[ ! $(unix2dos --version 2>/dev/null) ]]; then
VerboseOutput 5 "\`unix2dos --version\` failed"
VerboseOutput 5 "Sorry, It seems that unix2dos is not installed on your system"
VerboseOutput 5 "Please install unix2dos from your repositories and make sure it is available in your \$PATH"
VerboseOutput 5 "Otherwise disable windows-format playlists"
ExecTime
exit 1
fi
fi
VerboseOutput 0 "\`unix2dos --version\` succeeded"
fi fi
fi fi
VerboseOutput 1 "Dependency test OK" VerboseOutput 1 "Dependency test OK"
@ -124,8 +146,8 @@ CheckDeps() {
GetOptions() { GetOptions() {
# https://stackoverflow.com/a/29754866 # https://stackoverflow.com/a/29754866
OPTIONS=s:d:t:c::a::v::hj:: OPTIONS=s:d:t:c::a::v::hj::pwm:
LONGOPTS=source:,dest:,temp:,convert::,resize-art::,verbose::,help,jobs:: LONGOPTS=source:,dest:,temp:,convert::,resize-art::,verbose::,help,jobs::,playlists,windows-format,mapping:
# -use ! and PIPESTATUS to get exit code with errexit set # -use ! and PIPESTATUS to get exit code with errexit set
# -temporarily store output to be able to check for errors # -temporarily store output to be able to check for errors
@ -200,6 +222,26 @@ GetOptions() {
shift 2 shift 2
VerboseOutput 1 "Multithreading will use ${jobcount} threads" VerboseOutput 1 "Multithreading will use ${jobcount} threads"
;; ;;
-p|--playlists)
VerboseOutput 0 "--playlists given"
playlists=true
shift
VerboseOutput 1 "Playlist sync enabled"
;;
-w|--windows-format)
VerboseOutput 0 "--windows given"
windowspaths=true
shift
VerboseOutput 1 "Windows format playlists enabled"
;;
-m|--mapping)
VerboseOutput 0 "--mapping given"
listmappingparam=(${2//,/ })
listmapping[0]=${listmappingparam[0]:-""}
listmapping[1]=${listmappingparam[1]:-""}
shift 2
VerboseOutput 1 "Playlist mappings enabled source=${listmapping[0]} dest=${listmapping[1]}"
;;
--) --)
shift shift
break break
@ -276,22 +318,22 @@ CreateFileList() {
origfile="${file#"$1/"}" origfile="${file#"$1/"}"
relfile=$(echo ${origfile} | sed -e 's/\(\.\)*$//g' | tr -s ' ') 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 ${3}${origfile}"
if [[ -d "${1}/$origfile" ]]; then if [[ -d "${1}/$origfile" ]]; then
VerboseOutput 0 "${origfile} is folder" VerboseOutput 0 "${origfile} is folder"
newdir="${3}/$origfile" newdir="${3}$origfile"
newdir=${newdir#"/"} newdir=${newdir#"/"}
VerboseOutput 1 "Entering $newdir" VerboseOutput 1 "Entering $newdir"
CreateFileList "${1}/$origfile" "${2}/$relfile" "$newdir" CreateFileList "${1}/$origfile/" "${2}/$relfile/" "$newdir/"
elif [[ "${1}/$origfile" != *".m3u" ]] && [[ "${1}/$origfile" -nt "${2}/$mp3file" ]]; then elif [[ "${1}/$origfile" != *".m3u" ]] && [[ "${1}/$origfile" -nt "${2}/$mp3file" ]]; then
echo ${3}/$origfile >> /tmp/music-sync-filelist echo ${3}$origfile >> /tmp/music-sync-filelist
VerboseOutput 0 "${origfile} is newer in source" VerboseOutput 0 "${origfile} is newer in source"
VerboseOutput 2 "Added: ${3}/${origfile}" VerboseOutput 2 "Added: ${3}${origfile}"
elif [[ $playlists == true ]] && [[ "${1}/$origfile" == *".m3u" ]]; then
echo ${3}$origfile >> /tmp/music-sync-filelist
VerboseOutput 0 "${origfile} is newer in source"
VerboseOutput 2 "Added playlist: ${3}${origfile}"
fi fi
if [[ "${1}/$origfile" == *".m3u" ]]; then
VerboseOutput 0 "${origfile} is playlist"
fi
done done
} }
@ -319,12 +361,6 @@ Execute() {
else else
for line in $(cat "/tmp/music-sync-filelist") for line in $(cat "/tmp/music-sync-filelist")
do do
curline=$(expr ${curline} + 1)
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 "Progress: $curline / $total (${percentage%00}%)"
ProcessFile $line ProcessFile $line
done done
fi fi
@ -339,11 +375,51 @@ ProcessFile() {
VerboseOutput 2 "Current File: $line" VerboseOutput 2 "Current File: $line"
VerboseOutput 2 "Progress: $curline / $total (${percentage%00}%)" VerboseOutput 2 "Progress: $curline / $total (${percentage%00}%)"
if [[ $convert == true ]]; then if [[ $convert == true ]]; then
if [[ $line == *".m3u" ]]; then
ConvertPlaylist "$line"
else
ConvertFile "$line" ConvertFile "$line"
fi fi
fi
CopyFile "$line" CopyFile "$line"
} }
ConvertPlaylist() {
line=${1}
if [[ ! -f "${source}/$line" ]]; then
VerboseOutput 5 "Source-file ${source}/$line Unreachable"
ExecTime
exit 3
fi
if [[ ! -d $(dirname "$temp/$line") ]]; then
VerboseOutput 0 "Creating folder $temp/${line%/*}"
mkdir -p "$temp/${line%/*}";
fi;
if [[ -f "$temp/$line" ]]; then
rm $temp/$line
fi
search=${listmapping[0]}
replace=${listmapping[1]}
VerboseOutput 0 "Creating playlist $temp/$line"
for item in $(cat "$source/$line")
do
mp3item=$(echo $item | sed -e 's/\.*\//\//g'| tr -s ' ')
if [[ $windowspaths == true ]]; then
echo "${mp3item/$search/$replace}" | sed -e 's,\/,\\,g' >> $temp/$line
else
echo "${mp3item/$search/$replace}" >> $temp/$line
fi
done
if [[ $windowspaths == true ]]; then
VerboseOutput 0 "Converting lf to crlf"
unix2dos $temp/$line 1>/dev/null 2>/dev/null
fi
VerboseOutput 1 "Converted: $line"
}
ConvertFile() { ConvertFile() {
line=${1} line=${1}
if [[ ! -f "${source}/$line" ]]; then if [[ ! -f "${source}/$line" ]]; then
@ -352,12 +428,12 @@ ConvertFile() {
exit 3 exit 3
fi fi
if [[ "$temp/$line" = */* ]]; then if [[ ! -d $(dirname "$temp/$line") ]]; then
VerboseOutput 0 "Creating folder $temp/${line%/*}" VerboseOutput 0 "Creating folder $temp/${line%/*}"
mkdir -p "$temp/${line%/*}"; mkdir -p "$temp/${line%/*}";
fi; fi;
mp3line=$(echo "$line" | sed -e 's/.flac/.mp3/') mp3line=$(echo "$line" | sed -e 's/.flac/.mp3/')
if [[ ! -f "$temp/$mp3line" || "${source}/$mp3line" -nt "$temp/$mp3line" ]]; then if [[ "${source}/$line" -nt "$temp/$mp3line" ]]; then
if [[ $line != *".mp3" ]]; then if [[ $line != *".mp3" ]]; then
VerboseOutput 3 "${line} will be converted to mp3-file ${mp3line}" VerboseOutput 3 "${line} will be converted to mp3-file ${mp3line}"
fi fi
@ -409,7 +485,7 @@ CopyFile() {
destline=$(echo $mp3line | sed -e 's/\.*\//\//g'| tr -s ' ') destline=$(echo $mp3line | sed -e 's/\.*\//\//g'| tr -s ' ')
VerboseOutput 1 "Copying: $line" VerboseOutput 1 "Copying: $line"
if [[ "$dest/$line" = */* ]]; then if [[ ! -d $(dirname "$dest/$line") ]]; then
VerboseOutput 0 "Creating folder $dest/${line%/*}" VerboseOutput 0 "Creating folder $dest/${line%/*}"
mkdir -p "$dest/${destline%/*}"; mkdir -p "$dest/${destline%/*}";
fi; fi;