From 48d5fb91affd489356fde65eb0ff845cff541f34 Mon Sep 17 00:00:00 2001 From: ayakael Date: Mon, 19 Mar 2018 15:09:06 -0400 Subject: [PATCH] Initial commit - migration from music repo to own repo --- src/clean_target | 18 +++++++++++++ src/cmd_deploy | 28 ++++++++++++++++++++ src/cmd_exclude | 28 ++++++++++++++++++++ src/cmd_init | 20 ++++++++++++++ src/deploy_imageid | 60 ++++++++++++++++++++++++++++++++++++++++++ src/env | 13 +++++++++ src/is_not_excluded | 21 +++++++++++++++ src/parser | 54 +++++++++++++++++++++++++++++++++++++ src/print_deployed_ids | 13 +++++++++ src/print_meta | 27 +++++++++++++++++++ src/print_meta_field | 14 ++++++++++ src/print_target_dir | 25 ++++++++++++++++++ src/split_flac | 16 +++++++++++ 13 files changed, 337 insertions(+) create mode 100644 src/clean_target create mode 100644 src/cmd_deploy create mode 100644 src/cmd_exclude create mode 100644 src/cmd_init create mode 100644 src/deploy_imageid create mode 100644 src/env create mode 100644 src/is_not_excluded create mode 100644 src/parser create mode 100644 src/print_deployed_ids create mode 100644 src/print_meta create mode 100644 src/print_meta_field create mode 100644 src/print_target_dir create mode 100644 src/split_flac diff --git a/src/clean_target b/src/clean_target new file mode 100644 index 0000000..caeeeff --- /dev/null +++ b/src/clean_target @@ -0,0 +1,18 @@ +#!/bin/bash + +### +# Cleans target of all FLAC files that are owned by IMAGEID that exist in TARGET directory +### + +clean_target() { + local TARGET="${1}" + local IMAGEID="${2}" + local MANIFEST="${3}" + + for old_file in $(grep ${IMAGEID} ${MANIFEST} | cut -d'=' -f1); do + rm ${TARGET}/${old_file} + done + sed -i "/${IMAGEID}/d" ${MANIFEST} + find ${TARGET}/* -empty -type d -delete >/dev/null 2>&1 +} + diff --git a/src/cmd_deploy b/src/cmd_deploy new file mode 100644 index 0000000..dd07a36 --- /dev/null +++ b/src/cmd_deploy @@ -0,0 +1,28 @@ +#! /bin/bash + +### +# Deploys image ID using deploy_imageid function +### + +cmd_deploy() { + local TARGET="${1}"; shift + local imageidList=(${@}) + local MANIFEST="${TARGET}/${MANIFEST}" + local LAST_COMMIT="${TARGET}/${LAST_COMMIT}" + local EXCLUDE="${TARGET}/${EXCLUDE}" + if [[ ! -f "${MANIFEST}" ]] || [[ ! -f "${LAST_COMMIT}" ]] || [[ ! -f "${EXCLUDE}" ]]; then return 1; fi + + + for imageid in ${imageidList[@]}; do + _msg ECHO "Cleaning ${imageid} of ${TARGET}" + clean ${TARGET} ${imageid} ${MANIFEST} >${STDERR} 2>&1 + [[ $? -ne 0 ]] && local ERRORS=true + if [[ -f "${imageid}.tags" ]] && is_not_excluded ${imageid} ${EXCLUDE}; then + deploy ${imageid} ${TARGET} ${MANIFEST} + [[ $? -ne 0 ]] && local ERRORS=true + fi + done + [[ ${ERRORS} ]] && return 2 + +} + diff --git a/src/cmd_exclude b/src/cmd_exclude new file mode 100644 index 0000000..f993038 --- /dev/null +++ b/src/cmd_exclude @@ -0,0 +1,28 @@ +#!/bin/bash + +### +# Command used to ADD or DELete an exception rule in OPT_EXCLUDE_FILE +### + +cmd_exclude() { + local TARGET="${1}" + local EXCLUDE="${TARGET}/${EXCLUDE}" + local CMD="${2}"; shift 2 + local fieldList=("${@}") + + case ${CMD} in + add) + printf "%s\n" ${fieldList[@]} >> ${EXCLUDE} + ;; + + del) + for field in ${fieldList[@]}; do + sed -i "/${field}/d" ${EXCLUDE} + done + ;; + + ls) + cat ${EXCLUDE} + ;; + esac +} diff --git a/src/cmd_init b/src/cmd_init new file mode 100644 index 0000000..a3f34ad --- /dev/null +++ b/src/cmd_init @@ -0,0 +1,20 @@ +#!/bin/bash + +### +# Command initializes TARGET directory by creating OPT_FILE_MANIFEST and OPT_FILE_EXCLUDE +# OPT_FILE_COMMIT +### + +cmd_init() { + local TARGET="${1}" + local MANIFEST="${TARGET}/${MANIFEST}" + local LAST_COMMIT="${TARGET}/${LAST_COMMIT}" + local EXCLUDE="${TARGET}/${EXCLUDE}" + + [[ -z "$(ls -A "${TARGET}")" ]] || return 1 + touch "${MANIFEST}" + touch "${EXCLUDE}" + echo "COMMIT=$(git rev-list HEAD | tail -n 1)" > ${LAST_COMMIT} + [[ $? -eq 0 ]] && return 0 || return 2 +} + diff --git a/src/deploy_imageid b/src/deploy_imageid new file mode 100644 index 0000000..76c4847 --- /dev/null +++ b/src/deploy_imageid @@ -0,0 +1,60 @@ +#!/bin/bash + +### +# Deploys IMAGEID to TARGET and then updates MANIFEST file +## + + +deploy_imageid() { + local IMAGEID="${1}" + local TARGET="${2}" + local MANIFEST="${3}" + local TOTALTRACKS="$(grep -e TITLE ${IMAGEID}.tags | wc -l)" + + if [[ ! -e "${IMAGEID}.flac" ]]; then + _msg EXEC "Downloading data for ${IMAGEID}" + git annex get ${IMAGEID}.* >${STDERR} 2>&1 + [[ $? -ne 0 ]] && _msg WARN || _msg OK + local DELETE=true + fi + + _msg EXEC "Generating data for ${IMAGEID}" + gen_flac ${IMAGEID}.flac ${IMAGEID}.cue >${STDERR} 2>&1 + local EXIT_CODE=$? + [[ ${EXIT_CODE} -eq 0 ]] && _msg OK || _msg WARN + + _msg EXEC "Parsing metadata for ${IMAGEID}" + local COUNT=1 + while [[ ${COUNT} -le ${TOTALTRACKS} ]]; do + metaList[${COUNT}]="$(gen_meta ${IMAGEID}.tags ${COUNT})" + local COUNT=$(( ${COUNT} + 1 )) + done + _msg OK + + _msg EXEC "Applying metadata for ${IMAGEID}" + local COUNT=1 + while [[ ${COUNT} -le ${TOTALTRACKS} ]]; do + awk 'BEGIN {RS=";"}{print $0}' <<< ${metaList[${COUNT}]} | head -n -1 | metaflac --import-tags-from=- --import-picture-from="${IMAGEID}.jpg" $(printf 'split-track%02d.flac' ${COUNT}) + [[ $? -ne 0 ]] && local GEN_META_ERR=true + local COUNT=$(( ${COUNT} + 1 )) + done + [[ ${GEN_META_ERR} ]] && _msg WARN || _msg OK + + _msg EXEC "Deploying ${IMAGEID} to ${TARGET}" + local COUNT=1 + while [[ ${COUNT} -le ${TOTALTRACKS} ]]; do + local DIR=$(gen_dir ${metaList[${COUNT}]} | sed s'|:|_|g') + mkdir -p "${TARGET}/$(dirname "${DIR}")" + mv $(printf 'split-track%02d.flac' ${COUNT}) "${TARGET}/${DIR}.flac" + echo "${DIR}.flac=${IMAGEID};" >> ${MANIFEST} + local COUNT=$(( ${COUNT} + 1 )) + done + _msg OK + + if [[ ${DELETE} ]]; then + _msg EXEC "Dropping data for ${IMAGEID}" + git annex drop ${IMAGEID}.* >${STDERR} 2>&1 + _msg OK + fi +} + diff --git a/src/env b/src/env new file mode 100644 index 0000000..9476553 --- /dev/null +++ b/src/env @@ -0,0 +1,13 @@ +#!/bin/bash + +### +# Sets environment variables necessary for the functioning of this script +### + +source /usr/lib/bash/bunc +IFS=' +' +MANIFEST=".manifest" +LAST_COMMIT=".last_commit" +EXCLUDE=".exclude" + diff --git a/src/is_not_excluded b/src/is_not_excluded new file mode 100644 index 0000000..9f89ac0 --- /dev/null +++ b/src/is_not_excluded @@ -0,0 +1,21 @@ +#!/bin/bash + +### +# Returns true if IMAGEID is not excluded from the OPT_EXCLUDE_FILE. +### + +is_not_excluded() { + local IMAGEID="${1}" + local EXCLUDE="${2}" + local excludeList=($(cat ${EXCLUDE})) + + [[ -z ${excludeList[@]} ]] && return 0 + + for exclude in ${excludeList[@]}; do + local FIELD=$(echo ${exclude} | cut -d'=' -f1) + local VALUE=$(echo ${exclude} | cut -d'=' -f2) + [[ -z "$(grep -i -l "\"${FIELD}\" : \"${VALUE}\"" ${IMAGEID}.tags)" ]] || return 1 + done + return 0 +} + diff --git a/src/parser b/src/parser new file mode 100644 index 0000000..cb04d3d --- /dev/null +++ b/src/parser @@ -0,0 +1,54 @@ +#! + +### +# Parses arguments and commands from shell +### + +case "${1}" in + exclude) + shift + cmd_exclude ${@} + ;; + + init) + shift + cmd_init ${@} + ;; + + deploy) + shift + TARGET="${1}"; shift + imageidList=($(printf '%s\n' ${@} | sed 's/\(.*\)\..*/\1/')) + cmd_deploy ${TARGET} ${imageidList[@]} + ;; + + update) + shift + TARGET="${1}"; shift + LAST_COMMIT="${TARGET}/${LAST_COMMIT}" + NEW_COMMIT=$(git rev-parse HEAD) + OLD_COMMIT=$(grep COMMIT "${LAST_COMMIT}" | cut -d'=' -f2) + imageidList=($(sed 's/\(.*\)\..*/\1/' <<< $(git diff --name-only ${NEW_COMMIT} ${OLD_COMMIT}) | awk '!seen[$0]++' | grep SHA256)) + echo $LAST_COMMIT + echo $NEW_COMMIT + echo $OLD_COMMIT + echo ${imageidList[@]} + + cmd_deploy ${TARGET} ${imageidList[@]} + case $? in + 0) + _msg ECHO "Update completed succesfully" + sed -i "s/COMMIT=.*/COMMIT=${NEW_COMMIT}/" ${LAST_COMMIT} + ;; + + 1) + _msg ECHO "Missing exclude, manifest or exclude file. Please make sure you init" + ;; + + 2) + _msg ECHO "Update completed with errors. Please review and deploy problematic images manually." + sed -i "s/COMMIT=.*/COMMIT=${NEW_COMMIT}/" ${LAST_COMMIT} + ;; + esac +esac + diff --git a/src/print_deployed_ids b/src/print_deployed_ids new file mode 100644 index 0000000..4f0a72c --- /dev/null +++ b/src/print_deployed_ids @@ -0,0 +1,13 @@ +#!/bin/bash + +### +# Prints IDs that are already deployed by parsing the IMAGEID field in all of the FLAC files +# that are present in the TARGET directory. +### + +print_deployed_ids() { + local TARGET="${@}" + for flac in $(find "${TARGET}" -name '*.flac' -not -path '*/\.*' -printf "%P\t"); do + echo "${flac}=$(metaflac --list ${TARGET}/${flac} | grep IMAGEID | cut -d= -f2);" + done +} diff --git a/src/print_meta b/src/print_meta new file mode 100644 index 0000000..98a016a --- /dev/null +++ b/src/print_meta @@ -0,0 +1,27 @@ +#!/bin/bash + +### +# Prints metadata of specified TRACKNUMBER, from textfile following the MTAG specification. Outputs as standard FIELD=VALUE that can then be pipped into metaflac. +### + + +print_meta() { + local MTAG=${1} + local TRACKNUMBER="${2}" + local TAGS=$(cat ${MTAG} | sed -e 's/^[[:space:]]*\"//') + local tagList=($(echo ${TAGS} | awk 'BEGIN {RS="\", ";FS="\" : \""}{if($1!~"{"){print $1}}' | awk '!seen[$0]++')) + + for tag in ${tagList[@]}; do + local COUNT=1 + while [[ ${COUNT} -le ${TRACKNUMBER} ]]; do + local PRTVAR=$(print_meta_track ${COUNT} ${tag} ${TAGS}) + [[ ! -z ${PRTVAR} ]] && local CURVAR=${PRTVAR} + local COUNT=$(( ${COUNT} + 1 )) + done + echo -n "${tag}=${CURVAR};" + unset CURVAR + unset PRTVAR + done + echo -n "IMAGEID=$(sed 's|.tags||g' <<< ${MTAG})" +} + diff --git a/src/print_meta_field b/src/print_meta_field new file mode 100644 index 0000000..0430e6e --- /dev/null +++ b/src/print_meta_field @@ -0,0 +1,14 @@ +#!/bin/bash + +### +# Prints VALUE of FIELD, for specific TRACK NUMBER out of a JSON string. Expects to be used +# by print_meta() +### + +print_meta_field() { + local TRACK_NO="${1}" + local FIELD="${2}"; shift 2 + local TAGS="${@}" + + awk -v track="${TRACK_NO}" 'BEGIN {RS="\" * }"}{if(NR==track){print $0}}' <<< ${TAGS} | awk -v field="${FIELD}" 'BEGIN {RS="\", ";FS="\" : \"";}{if($1==field){print $2}}' +} diff --git a/src/print_target_dir b/src/print_target_dir new file mode 100644 index 0000000..cc17e1e --- /dev/null +++ b/src/print_target_dir @@ -0,0 +1,25 @@ +#!/bin/bash + +### +# Prints output dir based on provided metadata TAGS. Expects input from print_meta function. +### + +print_target_dir() { + local TAGS="${@}" + local tagList=(GENRE COMPOSER ALBUM ARTIST PERFORMER DATE DISCNUMBER TOTALDISCS TRACKNUMBER TITLE) + + for tag in ${tagList[@]}; do + CURTAG="$(awk -v field=${tag} 'BEGIN{RS=";";FS="="}{if($1==field){printf $2}}' <<< ${TAGS})" + eval local ${tag}='${CURTAG}' + done + + if [[ "${GENRE}" == "Classical" ]]; then + echo -n "${GENRE}/${COMPOSER}/${ALBUM}/${ARTIST}/${DATE} - ${PERFORMER}/" + else + echo -n "${GENRE}/${ARTIST}/${DATE} - ${ALBUM}/" + fi + [[ ${TOTALDISCS} -gt 1 ]] && echo -n "${DISCNUMBER}." + printf "%02d" ${TRACKNUMBER} + echo -n " - $(sed 's|/|-|g' <<< ${TITLE} | sed 's|?||g')" +} + diff --git a/src/split_flac b/src/split_flac new file mode 100644 index 0000000..789411f --- /dev/null +++ b/src/split_flac @@ -0,0 +1,16 @@ +#!/bin/bash + +### +# Splits specified FLAC image into multiple flac files using a text file formatted under the +# CUE specification +### + +split_flac() { + local FLAC="${1}" + local CUE="${2}" + + [[ -z "$(cuebreakpoints ${CUE} 2>/dev/null)" ]] && { cat ${FLAC} > split-track01.flac; return 0; } + cuebreakpoints ${CUE} 2>/dev/null | shntool split ${FLAC} -o flac -O always + [[ $? -ne 0 ]] && { cuebreakpoints ${CUE} 2>/dev/null | sed s/$/0/ | shntool split ${FLAC} -o flac -O always; return 2; } || return 0 +} +