bash-music-sync/music-sync.sh

253 lines
5.6 KiB
Bash
Raw Normal View History

2018-11-30 10:48:04 +01:00
#!/bin/bash
2018-11-30 16:26:58 +01:00
begin=$(date +"%s")
2018-11-30 10:48:04 +01:00
# saner programming env: these switches turn some bugs into errors
set -o errexit -o pipefail -o noclobber -o nounset
source="-"
dest="-"
2018-11-30 16:12:50 +01:00
verbose=2
2018-11-30 10:48:04 +01:00
help=false
2018-11-30 17:50:37 +01:00
CheckDeps() {
# Check getopt
2018-11-30 10:48:04 +01:00
! getopt --test > /dev/null
if [[ ${PIPESTATUS[0]} -ne 4 ]]; then
2018-11-30 16:12:50 +01:00
VerboseOutput 5 "\`getopt --test\` failed"
2018-11-30 16:56:15 +01:00
VerboseOutput 5 "Sorry, It seems that your shell is not supported"
VerboseOutput 5 "If you're using MacOS or another unix-like system, please install GNU getopt"
2018-11-30 17:36:54 +01:00
ExecTime
2018-11-30 10:48:04 +01:00
exit 1
fi
2018-11-30 17:50:37 +01:00
# Check lame
if [[ ! $(lame --version 2>/dev/null) ]]; then
VerboseOutput 5 "\`lame --version\` failed"
VerboseOutput 5 "Sorry, It seems that lame is not installed on your system"
VerboseOutput 5 "Please install lame from your repositories and make sure it is available in your \$PATH"
ExecTime
exit 1
fi
}
GetOptions() {
# https://stackoverflow.com/a/29754866
2018-11-30 11:27:32 +01:00
# Parsing style without -s or -d
source=${*: -2:1}
dest=${*: -1:1}
2018-11-30 10:48:04 +01:00
2018-11-30 16:12:50 +01:00
OPTIONS=s:d:v::h
LONGOPTS=source:,dest:,verbose::,help
2018-11-30 10:48:04 +01:00
# -use ! and PIPESTATUS to get exit code with errexit set
# -temporarily store output to be able to check for errors
# -activate quoting/enhanced mode (e.g. by writing out “--options”)
# -pass arguments only via -- "$@" to separate them correctly
! PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTS --name "$0" -- "$@")
if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
# e.g. return value is 1
# then getopt has complained about wrong arguments to stdout
Usage
exit 2
fi
# read getopts output this way to handle the quoting right:
eval set -- "$PARSED"
# now enjoy the options in order and nicely split until we see --
while true; do
case "$1" in
-v|--verbose)
2018-11-30 16:12:50 +01:00
verbose=2
if [[ $2 != "" ]]; then
verbose=${2}
shift
fi
2018-11-30 10:48:04 +01:00
shift
;;
-h|--help)
help=true
shift
;;
-s|--source)
source="$2"
shift 2
;;
-d|--dest)
dest="$2"
shift 2
;;
--)
shift
break
;;
*)
2018-11-30 16:56:15 +01:00
VerboseOutput 5 "Programming error"
2018-11-30 10:48:04 +01:00
return 3
;;
esac
done
2018-11-30 14:42:20 +01:00
if [[ $dest == "" ]] || [[ $source == "" ]]; then
help=true
fi
2018-11-30 10:48:04 +01:00
}
2018-11-30 10:58:16 +01:00
Usage() {
2018-11-30 11:27:32 +01:00
echo ""
2018-11-30 10:58:16 +01:00
echo "Usage:"
2018-11-30 11:27:32 +01:00
echo "music-sync <options> -s|--source <source> -d|--dest <destination>"
echo "music-sync <options> <source> <destination>"
2018-11-30 10:58:16 +01:00
echo ""
echo "Syncronises music from one folder to another."
echo ""
echo "Options:"
echo " -s, --source <source> The source folder of the music"
echo " -d, --dest <destination> The destionation folder of the music"
2018-11-30 16:12:50 +01:00
echo " -v, --verbose <0-6> Set log level"
2018-11-30 10:58:16 +01:00
echo " -h, --help Display this help text"
2018-11-30 17:36:54 +01:00
echo ""
2018-11-30 16:12:50 +01:00
echo "Log levels:"
echo " 0 | Verbose"
echo " 1 | Debug"
echo " 2 | Info (Default)"
echo " 3 | Warning"
echo " 4 | Error"
echo " 5 | Fatal"
echo " 6 | No logging"
2018-11-30 11:05:31 +01:00
echo ""
2018-11-30 17:36:54 +01:00
echo "Exit Codes:"
echo " 1 Dependencies not met"
echo " 2 Invalid Argument"
echo " 3 Source Unreachable"
echo " 4 Destination Unreachable"
echo ""
2018-11-30 10:58:16 +01:00
}
2018-11-30 10:48:04 +01:00
VerboseOutput() {
2018-11-30 16:12:50 +01:00
level=""
if [[ $verbose -le $1 ]]; then
case "$1" in
0)
2018-11-30 16:56:15 +01:00
level="\033[1;36mVerbose\033[0m"
2018-11-30 16:12:50 +01:00
;;
1)
2018-11-30 16:56:15 +01:00
level="\033[1;34m Debug \033[0m"
2018-11-30 16:12:50 +01:00
;;
2)
2018-11-30 16:56:15 +01:00
level="\033[1;37m Info \033[0m"
2018-11-30 16:12:50 +01:00
;;
3)
2018-11-30 16:56:15 +01:00
level="\033[1;33mWarning\033[0m"
2018-11-30 16:12:50 +01:00
;;
4)
2018-11-30 16:56:15 +01:00
level="\033[1;31m Error \033[0m"
2018-11-30 16:12:50 +01:00
;;
5)
2018-11-30 16:56:15 +01:00
level="\033[1;30m Fatal \033[0m"
2018-11-30 16:12:50 +01:00
;;
esac
2018-11-30 16:56:15 +01:00
echo -e "[$level] $2" >&2
2018-11-30 10:48:04 +01:00
fi
}
2018-11-30 13:02:34 +01:00
CreateFileList() {
# ${1} /mnt/hdd/Example-Artist/Example-Album
# ${2} /mnt/mtp/Example-Artist/Example-Album
2018-11-30 14:57:08 +01:00
# ${3} Example-Artist/Example-Album
2018-11-30 13:02:34 +01:00
IFS=""
sourcepath="${1}/*"
for file in $sourcepath; do
relfile="${file#"$1/"}"
if [[ -d "${1}/$relfile" ]]; then
newdir="${3}/$relfile"
newdir=${newdir#"/"}
2018-11-30 16:12:50 +01:00
VerboseOutput 1 "Entering $newdir"
2018-11-30 13:02:34 +01:00
CreateFileList "${1}/$relfile" "${2}/$relfile" "$newdir"
2018-11-30 13:49:53 +01:00
elif [[ ! -f "${2}/$relfile" || "${1}/$relfile" -nt "${2}/$relfile" ]]; then
2018-11-30 13:02:34 +01:00
echo ${3}/$relfile >> /tmp/music-sync-filelist
2018-11-30 16:12:50 +01:00
VerboseOutput 2 "Added: ${3}/${relfile}"
2018-11-30 13:02:34 +01:00
fi
done
}
2018-11-30 13:28:29 +01:00
ConvertFiles() {
mkdir -p /tmp/converted
while read -r line
do
2018-11-30 17:36:54 +01:00
if [[ ! -f "${source}/$file" ]]; then
VerboseOutput 5 "Source-file ${source}/$file Unreachable"
ExecTime
exit 3
fi
2018-11-30 16:12:50 +01:00
VerboseOutput 1 "Converting: $line"
2018-11-30 13:28:29 +01:00
if [[ "/tmp/converted/$line" = */* ]]; then
mkdir -p "/tmp/converted/${line%/*}";
fi;
2018-11-30 15:45:02 +01:00
if [[ ! -f "/tmp/converted/$line" || "${source}/$file" -nt "/tmp/converted/$line" ]]; then
lame -b 192 $source/$line /tmp/converted/$line 1>/dev/null 2>/dev/null
2018-11-30 16:12:50 +01:00
VerboseOutput 2 "Converted: $line"
2018-11-30 15:45:02 +01:00
else
2018-11-30 16:12:50 +01:00
VerboseOutput 3 "$line already converted"
2018-11-30 15:45:02 +01:00
fi;
2018-11-30 13:28:29 +01:00
done < "/tmp/music-sync-filelist"
}
2018-11-30 13:41:26 +01:00
CopyFiles() {
while read -r line
do
if [[ ! -f "$dest" ]]; then
2018-11-30 17:36:54 +01:00
VerboseOutput 5 "Destination unreachable"
ExecTime
exit 4
fi
if [[ ! -f "$line" ]]; then
VerboseOutput 5 "Source-file ${source}/$file Unreachable"
ExecTime
exit 3
fi
2018-11-30 16:12:50 +01:00
VerboseOutput 1 "Copying: $line"
2018-11-30 13:41:26 +01:00
if [[ "$dest/$line" = */* ]]; then
mkdir -p "$dest/${line%/*}";
fi;
2018-11-30 14:52:51 +01:00
cp -f $source/$line $dest/$line 1>/dev/null 2>/dev/null
2018-11-30 13:41:26 +01:00
done < "/tmp/music-sync-filelist"
2018-11-30 16:12:50 +01:00
VerboseOutput 2 "Copied: $line"
2018-11-30 13:41:26 +01:00
}
2018-11-30 13:42:00 +01:00
CleanUp() {
2018-11-30 16:12:50 +01:00
VerboseOutput 1 "Cleaning Up"
2018-11-30 13:42:00 +01:00
rm "/tmp/music-sync-filelist"
2018-11-30 13:45:34 +01:00
rm -rf "/tmp/converted"
2018-11-30 16:12:50 +01:00
VerboseOutput 1 "Done"
2018-11-30 13:42:00 +01:00
}
2018-11-30 17:36:54 +01:00
ExecTime() {
termin=$(date +"%s")
difftimelps=$(($termin-$begin))
VerboseOutput 1 "$(($difftimelps / 60)) minutes and $(($difftimelps % 60)) seconds elapsed for Script Execution."
}
2018-11-30 17:50:37 +01:00
CheckDeps
2018-11-30 10:48:04 +01:00
GetOptions $@
2018-11-30 14:42:20 +01:00
if [[ $help == true ]]; then
2018-11-30 10:58:16 +01:00
Usage
2018-11-30 11:27:32 +01:00
exit
2018-11-30 10:58:16 +01:00
fi
2018-11-30 15:45:02 +01:00
if [[ -f /tmp/music-sync-filelist ]]; then
rm /tmp/music-sync-filelist
fi
2018-11-30 13:28:29 +01:00
CreateFileList $source $dest ""
2018-11-30 13:49:53 +01:00
if [[ ! -f /tmp/music-sync-filelist ]]; then
2018-11-30 16:56:15 +01:00
VerboseOutput 2 "Nothing to do!"
2018-11-30 13:49:53 +01:00
exit 0
fi
2018-11-30 13:41:26 +01:00
ConvertFiles
2018-11-30 13:42:00 +01:00
CopyFiles
2018-11-30 16:26:58 +01:00
CleanUp
2018-11-30 17:36:54 +01:00
ExecTime