From d943c8df8b93be4bcd14389525319ecb45220c5c Mon Sep 17 00:00:00 2001 From: fabs Date: Fri, 11 Dec 2020 23:00:54 +0100 Subject: [PATCH] original --- music_tagmove | 23 ++++++ music_tagmove_lib | 194 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 217 insertions(+) create mode 100755 music_tagmove create mode 100644 music_tagmove_lib diff --git a/music_tagmove b/music_tagmove new file mode 100755 index 0000000..9f3b864 --- /dev/null +++ b/music_tagmove @@ -0,0 +1,23 @@ +#!/bin/bash + +scr_dir=$(dirname "$0") + +source "$scr_dir/music_tagmove_lib" + + + +source_dir="$1" +dest_root="$2" + +cuesplit_all +tagmove + +error yanigga +error dududu + +if print_error_stack; then + exit 1 +else + exit 0 +fi + diff --git a/music_tagmove_lib b/music_tagmove_lib new file mode 100644 index 0000000..d91cc49 --- /dev/null +++ b/music_tagmove_lib @@ -0,0 +1,194 @@ +#!/bin/zsh +source bashcols + +if [[ -z $DIRECTORY_FORMAT ]]; then + DIRECTORY_FORMAT='$artist/$date $album' +fi + +if [[ -z $FILE_FORMAT ]]; then + FILE_FORMAT='$track $title' +fi + + +global_errf= +local_errf= + +declare -a global_error_stack=() + +function print_error_stack { + if [[ -n $global_errf ]]; then + >&2 red echo "ERROR STACK:" + for error_line in "${global_error_stack[@]}"; do + >&2 printf "%s\n" "$error_line" + done + true + else + >&2 green echo "EMPTY ERROR STACK" + fi + false +} + +function info { + printf "%s %s\n" $(colthis cyan "[info]") "$*" +} + +function error { + >&2 cyan echo -e "\n::: ENTER ERROR" + print_error_stack + global_errf=1 + local_errf=1 + current_error_line=$(printf "%s %s" $(colthis red "[error]") "$*") + global_error_stack+=( "$current_error_line" ) + >&2 printf "%s %s\n" $(colthis green "[CURRENT]") "$current_error_line" + + print_error_stack + >&2 cyan echo "::: EXIT ERROR" +} + +function clr_errf { + local_errf= +} + +function read_tag { + clr_errf + local tag="$1" + local file="$2" + local result=$(ffprobe -loglevel error -show_entries format_tags="$tag" -of default=noprint_wrappers=1:nokey=1 "$file") + if [[ $? -ne 0 ]]; then + error "Reading tag \"$tag\" from \"$file\" failed (ffprobe failed)" + return + fi + if [[ -z $result ]]; then + error "Reading tag \"$tag\" from \"$file\" failed (result empty)" + fi + echo "$result" +} + +function cuesplit_single { + clr_errf + + local cue_file="$1" + local image_dir=$(dirname "$1") + + green echo ":: ENTERING DIRECTORY \"$image_dir\"" + cd "$image_dir" || ( + error "Could not enter directory \"$image_dir\"" + return + ) + + #shopt -s nullglob + local arr_flac=(*.flac) + local arr_cue=(*.cue) + + if [[ ${#arr_flac[@]} -eq 0 ]]; then + error "No flac files found in directory \"$image_dir\"" + fi + + if [[ ${#arr_cue[@]} -eq 0 ]]; then + error "No cue files found in directory \"$image_dir\"" + fi + + if [[ -n $local_errf ]]; then + error "Aborting target \"$image_dir\"" + return + fi + + if [[ ${#arr_flac[@]} -gt 1 ]]; then + error "Multiple flac files found in directory \"$image_dir\":" + for flac_file in "${arr_flac[@]}"; do + echo -e "\t$flac_file" + done + fi + + if [[ ${#arr_cue[@]} -gt 1 ]]; then + error "Multiple cue files found in directory \"$image_dir\":" + for cue_file in "${arr_cue[@]}"; do + echo -e "\t$cue_file" + done + fi + + local flac=${arr_flac[0]} + local cue=${arr_cue[0]} + + + #### Make sure the cue file ends with a newline + #### cuebreakpoints can't handle it otherwise + echo >> "$cue" + + if cuebreakpoints "$cue" | shnsplit -o flac "$flac" || \ + cuebreakpoints "$cue" | sed 's/$/0/' | shnsplit -o flac "$flac"; then + info "Tagging target \"$image_dir\"" + if cuetag.sh "$cue" split-*.flac; then + info "Renaming source files" + mv "$cue" "$cue.ignore" + mv "$flac" "$flac.ignore" + else + error "Tagging failed for target \"$image_dir\"" + fi + else + error "Splitting failed for target \"$image_dir\"" + fi + + cd - &>/dev/null +} + +function cuesplit_all { + find "$source_dir" -type f -name "*.cue" | while read -r cue_file; do + cuesplit_single "$cue_file" + done +} + +function mv_wrap { + echo "mv" "$@" +} + +function tagmove_single { + file_name="$1" + artist=$(read_tag artist "$file_name") + date=$(read_tag date "$file_name") + album=$(read_tag album "$file_name") + track=$(read_tag track "$file_name") + title=$(read_tag title "$file_name") + + if [[ -n $local_errf ]]; then + error "Error reading tags for file \"$file_name\"" + return + else + if [[ $global_errf ]]; then + error "Global error flag set, not performing move on file \"$file_name\"" + return + fi + fi + + if [[ -z $artist ]] || \ + [[ -z $date ]] || \ + [[ -z $album ]] || \ + [[ -z $track ]] || \ + [[ -z $title ]]; then + error "At least one tag is empty for file \"$file_name\"" + return + fi + + # Set fixed width for track number + track=$(printf "%02d" "$track") + + eval "dest_directory=\"$DIRECTORY_FORMAT\"" + eval "dest_file=\"$FILE_FORMAT\"" + + mkdir -p "$dest_root/$dest_directory" + mv_wrap "$file_name" "$dest_root/$dest_directory/$dest_file.${filename##*.}" +} + + +function tagmove { + if [[ -n $global_errf ]]; then + error "Encountered errors before executing tagmove, aborting. Resolve errors and rerun" + return + fi + + find "$source_dir" -type f | while read -r file; do + if [[ $(file -b --mime-type "$file") =~ ^audio/ ]]; then + tagmove_single "$file" + fi + done +}