diff --git a/README.MD b/README.MD index b4f36da..83ec5f5 100644 --- a/README.MD +++ b/README.MD @@ -2,3 +2,27 @@ (c) 2018 Jeroen De Meerleer Script to sync music from one folder to another + +## Usage: + +``` +music-sync -s|--source -d|--dest +music-sync + +Syncronises music from one folder to another. + +Options: + -s, --source The source folder of the music + -d, --dest The destionation folder of the music + -v, --verbose Enable verbose output + -h, --help Display this help text +``` + +## Licence +Copyright 2018 Jeroen De Meerleer + +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: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/music-sync.sh b/music-sync.sh new file mode 100755 index 0000000..ff117a8 --- /dev/null +++ b/music-sync.sh @@ -0,0 +1,165 @@ +#!/bin/bash + +# saner programming env: these switches turn some bugs into errors +set -o errexit -o pipefail -o noclobber -o nounset +source="-" +dest="-" +verbose=true +help=false + +GetOptions() { + + # https://stackoverflow.com/a/29754866 + ! getopt --test > /dev/null + if [[ ${PIPESTATUS[0]} -ne 4 ]]; then + VerboseOutput "Fatal" "\`getopt --test\` failed" + echo "Sorry, It seems that your shell is not supported" + echo "If you're using mac or another unix-like system, please install GNU getopt" + exit 1 + fi + + # Parsing style without -s or -d + source=${*: -2:1} + dest=${*: -1:1} + + OPTIONS=s:d:vh + LONGOPTS=source:,dest:,verbose,help + + # -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 getopt’s output this way to handle the quoting right: + eval set -- "$PARSED" + + verbose=false + # now enjoy the options in order and nicely split until we see -- + while true; do + case "$1" in + -v|--verbose) + verbose=true + shift + ;; + -h|--help) + help=true + shift + ;; + -s|--source) + source="$2" + shift 2 + ;; + -d|--dest) + dest="$2" + shift 2 + ;; + --) + shift + break + ;; + *) + echo "Programming error" + return 3 + ;; + esac + done + + if [[ $dest == "" ]] || [[ $source == "" ]]; then + help=true + fi +} + +Usage() { + echo "" + echo "Usage:" + echo "music-sync -s|--source -d|--dest " + echo "music-sync " + echo "" + echo "Syncronises music from one folder to another." + echo "" + echo "Options:" + echo " -s, --source The source folder of the music" + echo " -d, --dest The destionation folder of the music" + echo " -v, --verbose Enable verbose output" + echo " -h, --help Display this help text" + echo "" +} + +VerboseOutput() { + if [[ "$verbose" = true ]]; then + echo "[$1] $2" >&2 + fi +} + +CreateFileList() { + # ${1} /mnt/hdd/Example-Artist/Example-Album + # ${2} /mnt/mtp/Example-Artist/Example-Album + # ${3} Example-Artist/Example-Album/ + IFS="" + sourcepath="${1}/*" + for file in $sourcepath; do + relfile="${file#"$1/"}" + if [[ -d "${1}/$relfile" ]]; then + newdir="${3}/$relfile" + newdir=${newdir#"/"} + VerboseOutput "Info" "Entering $newdir" + CreateFileList "${1}/$relfile" "${2}/$relfile" "$newdir" + elif [[ ! -f "${2}/$relfile" || "${1}/$relfile" -nt "${2}/$relfile" ]]; then + echo ${3}/$relfile >> /tmp/music-sync-filelist + VerboseOutput "Info" "Added: ${3}/${relfile}" + fi + done +} + +ConvertFiles() { + mkdir -p /tmp/converted + while read -r line + do + VerboseOutput "Info" "Converting $line" + if [[ "/tmp/converted/$line" = */* ]]; then + mkdir -p "/tmp/converted/${line%/*}"; + fi; + lame -b 192 $source/$line /tmp/converted/$line 1>/dev/null 2>/dev/null + VerboseOutput "Info" "Converted $line" + done < "/tmp/music-sync-filelist" +} + +CopyFiles() { + while read -r line + do + VerboseOutput "Info" "Copy $line" + if [[ "$dest/$line" = */* ]]; then + mkdir -p "$dest/${line%/*}"; + fi; + cp -f $source/$line $dest/$line 1>/dev/null 2>/dev/null + done < "/tmp/music-sync-filelist" + VerboseOutput "Info" "Copied $line" +} + +CleanUp() { + VerboseOutput "Info" "Cleaning Up" + rm "/tmp/music-sync-filelist" + rm -rf "/tmp/converted" + VerboseOutput "Info" "Done" +} + +GetOptions $@ +if [[ $help == true ]]; then + Usage + exit +fi +CreateFileList $source $dest "" +if [[ ! -f /tmp/music-sync-filelist ]]; then + VerboseOutput "Info" "Nothing to do!" + exit 0 +fi +ConvertFiles +CopyFiles +CleanUp \ No newline at end of file