dam/git2git.sh

286 lines
10 KiB
Bash

#!/bin/bash
source /usr/lib/bash/bunc
IFS='
'
sec2min() {
local secList=("${@}")
for sec in ${secList[@]}; do
MIN=$(($sec%3600/60))
SEC=$(($sec%60))
[[ ${sec} -ge 3600 ]] && MIN=$(( ${MIN} + 60 ))
printf '%02d:%02d:%02d\n' ${MIN} ${SEC} 00
done
}
med_convert() {
local EXT="${1}"; shift 1
local fileList=("${@}")
for file in ${fileList[@]}; do
local FILE_EXT="$(echo "${file}" | sed 's|.*\.||')"
ffmpeg -loglevel 24 -y -i "${file}" "$(echo ${file} | sed "s|${FILE_EXT}|${EXT}|")" >${STDERR} 2>&1
[[ $? -ne 0 ]] && local ERROR=true
done
[[ ${ERROR} ]] && return 1 || return 0
}
file_name() {
local SOURCE="${1}"
local SHA256="${2}"
echo "SHA256-${SOURCE}--${SHA256}"
}
cdcount() {
local FOLDER="${1}"
local tracknoList=($(find "${1}"/* -type f -follow -not -name '*cover*' -not -name '*.pdf' -printf '%f\n' | cut -d' ' -f1))
for trackno in ${tracknoList[@]}; do
if [[ ${trackno} == *.* ]]; then
local CDCOUNT=$(echo ${trackno} | cut -d. -f1)
else
local CDCOUNT=1
fi
done
echo ${CDCOUNT}
}
ismp3() {
local fileList=("${@}")
for file in ${fileList[@]}; do
local FILE_EXT="$(echo "${file}" | sed 's|.*\.||')"
[[ "${FILE_EXT}" == "mp3" ]] && local MP3=0 || local MP3=1
done
[[ ${MP3} -eq 0 ]] && return 0 || return 1
}
addbom() {
local fileList=("${@}")
for file in ${fileList[@]}; do
sed -i '1s/^\(\xef\xbb\xbf\)\?/\xef\xbb\xbf/' "${file}"
done
return 0
}
gen_breaklist() {
local fileList=("${@}")
local breakList=(0:00:00)
if shntool cue ${fileList[@]} >/dev/null 2>&1; then
shntool cue ${fileList[@]} > joined.cue
local breakList=(${breakList[@]} $(cuebreakpoints joined.cue | sed 's|\.|:|g'))
rm joined.cue
else
local durList=($(soxi -D "${fileList[@]}"))
local breaksecList=(0)
local COUNT=0
while [[ $(( ${COUNT} + 1 )) -lt ${#durList[@]} ]]; do
local breaksecList=(${breaksecList[@]} $(awk "BEGIN {printf ${breaksecList[-1]} + ${durList[${COUNT}]}}" ))
local COUNT=$(( ${COUNT} + 1 ))
done
local breaksecList=($(printf "%s\n" ${breaksecList[@]} | sed 's|\..*||g'))
local breakList=($(sec2min ${breaksecList[@]}))
fi
printf '%s\n' ${breakList[@]}
}
gen_image() {
local fileList=("${@}")
if [[ ${#fileList[@]} -eq 1 ]]; then
cat ${fileList[@]} > joined.flac
else
shntool join -O always ${fileList[@]} -o flac
if [[ $? -ne 0 ]]; then
med_convert wav ${fileList[@]}
[[ $? -ne 0 ]] && { echo "Image generation failed with fatal errors"; return 1; }
echo ${fileList[@]}
fileList=($(printf '%s\n' ${fileList[@]} | sed 's|flac|wav|'))
echo ${fileList[@]}
shntool join -O always ${fileList[@]} -o flac
[[ $? -ne 0 ]] && { echo "Image generation failed with fatal errors"; return 1; }
echo "Image generated with non-fatal error"; return 2
fi
fi
echo "Image generated with no errors"; return 0
}
gen_cue() {
local FILE_NAME="${1}"
local METADATA="${2}"; shift 2
local fileList=("${@}")
# Metadata Parsing
metadataList=($(echo ${METADATA} | sed 's|;| |g'))
for metadata in ${metadataList[@]}; do
eval local ${metadata}
done
for file in ${fileList[@]}; do
local trackList=(${trackList[@]} $(echo ${file} | sed 's|.*/||' | awk 'BEGIN{ FS="-"; OFS=":"}{$1=""}{print $0}' | sed 's|: ||'))
done
# Generates breaklist
breakList=($(gen_breaklist ${fileList[@]}))
[[ ! -z "${META_DATE+x}" ]] && echo "REM DATE ${META_DATE}"
[[ ! -z "${META_COMPOSER+x}" ]] && echo "PERFORMER \"${META_COMPOSER}\""
[[ ! -z "${META_CONDUCTOR+x}" ]] && echo "REM CONDUCTOR \"${META_CONDUCTOR}\""
[[ ! -z "${META_ORCHESTRA+x}" ]] && echo "REM ORCHESTRA \"${META_ORCHESTRA}\""
[[ ! -z "${META_ARTIST+x}" ]] && echo "PERFORMER \"${META_ARTIST}\""
[[ ! -z "${META_ALBUM+x}" ]] && echo "TITLE \"${META_ALBUM}\""
echo "FILE \"${FILE_NAME}.flac\" WAVE"
local COUNT=0
while [[ ${COUNT} -lt ${#breakList[@]} ]]; do
[[ ${COUNT} -le 8 ]] && local TRACK_NO="0$(( ${COUNT} + 1 ))" || local TRACK_NO="$(( ${COUNT} + 1 ))"
echo " TRACK ${TRACK_NO} AUDIO"
echo " TITLE \"${trackList[${COUNT}]}\""
echo " INDEX 01 ${breakList[${COUNT}]}"
local COUNT=$(( ${COUNT} + 1 ))
done
return 0
}
gen_mtag() {
local FILE_NAME="${1}"
local METADATA="${2}"; shift 2
local fileList=("${@}")
# Metadata Parsing
metadataList=($(echo ${METADATA} | sed 's|;| |g'))
for metadata in ${metadataList[@]}; do
eval local ${metadata}
done
for file in ${fileList[@]}; do
local trackList=(${trackList[@]} $(echo ${file} | sed 's|.*/||' | awk 'BEGIN {FS="-"; OFS=":"}{$1=""}{print $0}' | sed 's|: ||'))
done
echo "["
local COUNT=0
while [[ ${COUNT} -lt ${#trackList[@]} ]]; do
[[ ${COUNT} -ne 0 ]] && echo " },"
echo " {"
echo " \"@\" : \"${FILE_NAME}.cue|$(( ${COUNT} + 1 ))\","
if [[ ${COUNT} -eq 0 ]]; then
[[ ! -z "${META_ALBUM+x}" ]] && echo " \"ALBUM\" : \"${META_ALBUM}\","
[[ ! -z "${META_ARTIST+x}" ]] && echo " \"ARTIST\" : \"${META_ARTIST}\","
[[ ! -z "${META_ALBUMARTIST+x}" ]] && echo " \"ALBUMARTIST\" : \"${META_ALBUMARTIST}\","
[[ ! -z "${META_COMPOSER+x}" ]] && echo " \"COMPOSER\" : \"${META_COMPOSER}\","
[[ ! -z "${META_CONDUCTOR+x}" ]] && echo " \"CONDUCTOR\" : \"${META_CONDUCTOR}\","
[[ ! -z "${META_ORCHESTRA+x}" ]] && echo " \"ORCHESTRA\" : \"${META_ORCHESTRA}\","
[[ ! -z "${META_DATE+x}" ]] && echo " \"DATE\" : \"${META_DATE}\","
[[ ! -z "${META_GENRE+x}" ]] && echo " \"GENRE\" : \"${META_GENRE}\","
[[ ! -z "${META_DISCNUM+x}" ]] && echo " \"DISCNUMBER\" : \"${META_DISCNUM}\","
[[ ! -z "${META_DISCTOT+x}" ]] && echo " \"TOTALDISCS\" : \"${META_DISCTOT}\","
echo " \"TOTALTRACKS\" : \"${#trackList[@]}\","
echo " \"BATCHNUMBER\" : \"0\","
fi
echo " \"TITLE\" : \"${trackList[${COUNT}]}\","
echo " \"TRACKNUMBER\" : \"$(( ${COUNT} + 1 ))\""
local COUNT=$(( ${COUNT} + 1 ))
done
echo " }"
echo "]"
return 0
}
gen_metadata() {
local FOLDER="${1}"
local DISC_NO="${2}"
local META_DISCTOT="${3}"
local META_GENRE=$(echo ${FOLDER} | cut -d/ -f1)
echo -n "META_GENRE=\"${META_GENRE}\";"
echo -n "META_DISCTOT=${META_DISCTOT};"
echo -n "META_DISCNUM=${DISC_NO};"
if [[ "${META_GENRE}" == "Classical" ]] && [[ "$(echo ${FOLDER} | cut -d/ -f5 | cut -d- -f2 | sed 's| ||')" != "" ]]; then
echo -n "META_COMPOSER=\"$(echo ${FOLDER} | cut -d/ -f2)\";"
echo -n "META_ALBUM=\"$(echo ${FOLDER} | cut -d/ -f3)\";"
echo -n "META_CONDUCTR=\"$(echo ${FOLDER} | cut -d/ -f4)\";"
echo -n "META_DATE=\"$(echo ${FOLDER} | cut -d/ -f5 | cut -d- -f1 | rev | sed 's| ||' | rev)\";"
echo -n "META_ORCHESTRA=\"$(echo ${FOLDER} | cut -d/ -f5 | cut -d- -f2 | sed 's| ||')\";"
elif [[ "${META_GENRE}" == "Soundtrack" ]]; then
echo -n "META_ALBUM=\"$(echo ${FOLDER} | cut -d/ -f2)\""
else
echo -n "META_ARTIST=\"$(echo ${FOLDER} | cut -d/ -f2)\";"
echo -n "META_DATE=\"$(echo ${FOLDER} | cut -d/ -f3 | cut -d- -f1 | rev | sed 's| ||' | rev)\";"
echo -n "META_ALBUM=\"$(echo ${FOLDER} | cut -d/ -f3 | sed 's|.*\ -\ ||')\";"
fi
return 0
}
gen_cover() {
local FOLDER="${1}"
[[ -f "${FOLDER}/full_cover.tiff" ]] && local IMAGE="full_cover.tiff" || local IMAGE="cover.jpg"
convert "${FOLDER}/${IMAGE}" jpeg:-
return 0
}
gen() {
local ROOT="${1}"
local SUBFOL="${2}"
local FOLDER="${ROOT}/${SUBFOL}"
local CDCOUNT="$(cdcount "${FOLDER}")"
local COUNT=1
local SOURCE=FLAC
while [[ ${COUNT} -le ${CDCOUNT} ]]; do
# Generates file list depending on CD count
if [[ "${CDCOUNT}" == 1 ]]; then
local fileList=($(find "${FOLDER}"/* \( -name '*.flac' -or -name '*.mp3' -or -name '*.wav' \) -printf '%p\t'))
else
local fileList=($(find "${FOLDER}"/${COUNT}.* \( -name '*.flac' -or -name '*.mp3' \) -printf '%p\t'))
fi
if ismp3 ${fileList[@]}; then
_msg EXEC "Converting MP3 files to FLAC"
med_convert flac ${fileList[@]} >${STDERR} 2>&1
[[ $? -eq 0 ]] && _msg OK || _msg WARN
local SOURCE=MP3
fi
[[ "${SOURCE}" == "MP3" ]] && local fileList=($(printf "%s\t" ${fileList[@]} | sed 's|mp3|flac|g'))
# Generates image
_msg EXEC "Generating data for ${FOLDER} disk ${COUNT} of ${CDCOUNT}"
gen_image ${fileList[@]} >${STDERR} 2>&1
local EXIT="$?"
if [[ ${EXIT} -eq 0 ]]; then
_msg OK
elif [[ ${EXIT} -eq 2 ]]; then
_msg WARN
else
_msg FAIL
local COUNT=$(( ${COUNT} + 1 ))
continue
fi
# Determines file name based on image's CHKSUM and acts accordingly
metaflac --remove-all --dont-use-padding joined.flac
local SHA256=$(sha256sum joined.flac | cut -d' ' -f1)
local FILE_NAME=$(file_name ${SOURCE} ${SHA256})
mv joined.flac ${FILE_NAME}.flac
# Generates METADATA, CUE and MTAG
_msg EXEC "Generating metadata for ${FOLDER} disk ${COUNT} of ${CDCOUNT}"
local METADATA="$(gen_metadata "${SUBFOL}" ${COUNT} ${CDCOUNT})"
gen_cue "${FILE_NAME}" ${METADATA} ${fileList[@]} > ${FILE_NAME}.cue
[[ $? -ne 0 ]] && _msg WARN
addbom ${FILE_NAME}.cue
gen_mtag "${FILE_NAME}" ${METADATA} ${fileList[@]} > ${FILE_NAME}.tags
[[ $? -ne 0 ]] && _msg WARN
addbom ${FILE_NAME}.tags
gen_cover "${FOLDER}" > ${FILE_NAME}.jpg
[[ $? -ne 0 ]] && _msg WARN || _msg OK
local COUNT=$(( ${COUNT} + 1 ))
done
}
ROOT="${1}"; shift 1
dirList=("${@}")
for dir in ${dirList[@]}; do
folderList=($(find ${ROOT}/${dir} -name '*cover*' -printf '%h\n' | awk '!seen[$0]++' | sed "s|${ROOT}/||g"))
for folder in ${folderList[@]}; do
gen ${ROOT} "${folder}"
#echo ${folder}
done
done