From b9dd571098cc76cf8fe7f2428ac7121e8d455e3f Mon Sep 17 00:00:00 2001 From: emily Date: Tue, 26 Nov 2024 22:01:19 +0100 Subject: [PATCH] Kill kill kill kill kill --- lidarr/Audio.service.bash | 1148 +++++++++++++++++-------------------- 1 file changed, 533 insertions(+), 615 deletions(-) diff --git a/lidarr/Audio.service.bash b/lidarr/Audio.service.bash index 32a6283..238b089 100644 --- a/lidarr/Audio.service.bash +++ b/lidarr/Audio.service.bash @@ -1,38 +1,59 @@ #!/usr/bin/with-contenv bash -scriptVersion="2.48" + +set -euo pipefail + +while [[ $# -gt 0 ]]; do + case $1 in + --state-dir) + STATE_DIR="$2" + shift + shift + ;; + --runtime-dir) + RUNTIME_DIR="$2" + shift + shift + ;; + *) + echo "Unknown option $1" + exit 1 + ;; + esac +done + scriptName="Audio" ### Import Settings -source /config/extended.conf +# shellcheck source=./extended.conf +source "${STATE_DIR}/lidarr-dl.conf" #### Import Functions -source /config/extended/functions +source ../universal/functions.bash AddTag () { log "adding arr-extended tag" - lidarrProcessIt=$(curl -s "$arrUrl/api/v1/tag" --header "X-Api-Key:"${arrApiKey} -H "Content-Type: application/json" --data-raw '{"label":"arr-extended"}') + lidarrProcessIt=$(curl -s "$arrUrl/api/v1/tag" --header "X-Api-Key:" "${arrApiKey}" -H "Content-Type: application/json" --data-raw '{"label":"arr-extended"}') } AddDownloadClient () { - downloadClientsData=$(curl -s "$arrUrl/api/v1/downloadclient" --header "X-Api-Key:"${arrApiKey} -H "Content-Type: application/json") - downloadClientCheck="$(echo $downloadClientsData | grep "Arr-Extended")" + downloadClientsData=$(curl -s "$arrUrl/api/v1/downloadclient" --header "X-Api-Key:" "${arrApiKey}" -H "Content-Type: application/json") + downloadClientCheck="$(echo "$downloadClientsData" | grep "Arr-Extended")" if [ -z "$downloadClientCheck" ]; then AddTag if [ ! -d "$importPath" ]; then mkdir -p "$importPath" - chmod 777 -R "$importPath" fi log "Adding download Client" - lidarrProcessIt=$(curl -s "$arrUrl/api/v1/downloadclient" --header "X-Api-Key:"${arrApiKey} -H "Content-Type: application/json" --data-raw "{\"enable\":true,\"protocol\":\"usenet\",\"priority\":10,\"removeCompletedDownloads\":true,\"removeFailedDownloads\":true,\"name\":\"Arr-Extended\",\"fields\":[{\"name\":\"nzbFolder\",\"value\":\"$importPath\"},{\"name\":\"watchFolder\",\"value\":\"$importPath\"}],\"implementationName\":\"Usenet Blackhole\",\"implementation\":\"UsenetBlackhole\",\"configContract\":\"UsenetBlackholeSettings\",\"infoLink\":\"https://wiki.servarr.com/lidarr/supported#usenetblackhole\",\"tags\":[]}") + lidarrProcessIt=$(curl -s "$arrUrl/api/v1/downloadclient" --header "X-Api-Key:" "${arrApiKey}" -H "Content-Type: application/json" --data-raw "{\"enable\":true,\"protocol\":\"usenet\",\"priority\":10,\"removeCompletedDownloads\":true,\"removeFailedDownloads\":true,\"name\":\"Arr-Extended\",\"fields\":[{\"name\":\"nzbFolder\",\"value\":\"$importPath\"},{\"name\":\"watchFolder\",\"value\":\"$importPath\"}],\"implementationName\":\"Usenet Blackhole\",\"implementation\":\"UsenetBlackhole\",\"configContract\":\"UsenetBlackholeSettings\",\"infoLink\":\"https://wiki.servarr.com/lidarr/supported#usenetblackhole\",\"tags\":[]}") fi } verifyConfig () { ### Import Settings - source /config/extended.conf + # shellcheck source=./extended.conf + source "${STATE_DIR}/lidarr-dl.conf" if [ "$enableAudio" != "true" ]; then log "Script is not enabled, enable by setting enableAudio to \"true\" by modifying the \"/config/extended.conf\" config file..." - log "Sleeping (infinity)" - sleep infinity + exit 0 fi if [ -z "$audioScriptInterval" ]; then @@ -80,32 +101,13 @@ Configuration () { sleepTimer=0.5 tidaldlFail=0 deemixFail=0 - log "-----------------------------------------------------------------------------" - log " |~) _ ._ _| _ ._ _ |\ |o._ o _ |~|_|_|" - log " |~\(_|| |(_|(_)| | || \||| |_|(_||~| | |<" - log " Presents: $scriptName ($scriptVersion)" - log " May the beats be with you!" - log "-----------------------------------------------------------------------------" - log "Donate: https://github.com/sponsors/RandomNinjaAtk" - log "Project: https://github.com/RandomNinjaAtk/arr-scripts" - log "Support: https://github.com/RandomNinjaAtk/arr-scripts/discussions" - log "-----------------------------------------------------------------------------" sleep 5 - log "" - log "Lift off in..."; sleep 0.5 - log "5"; sleep 1 - log "4"; sleep 1 - log "3"; sleep 1 - log "2"; sleep 1 - log "1"; sleep 1 - - - if [ ! -d /config/xdg ]; then - mkdir -p /config/xdg + if [ ! -d "${STATE_DIR}/xdg" ]; then + mkdir -p "${STATE_DIR}/xdg" fi - if [ -z $topLimit ]; then + if [ -z "$topLimit" ]; then topLimit=10 fi @@ -175,10 +177,10 @@ Configuration () { if [ $enableBeetsTagging = true ]; then log "Beets Tagging Enabled" log "Beets Matching Threshold ${beetsMatchPercentage}%" - beetsMatchPercentage=$(expr 100 - $beetsMatchPercentage ) - if cat /config/extended/beets-config.yaml | grep "strong_rec_thresh: 0.04" | read; then + beetsMatchPercentage=$((100 - beetsMatchPercentage )) + if grep "strong_rec_thresh: 0.04" "${STATE_DIR}/extended/beets-config.yaml" | read -r; then log "Configuring Beets Matching Threshold" - sed -i "s/strong_rec_thresh: 0.04/strong_rec_thresh: 0.${beetsMatchPercentage}/g" /config/extended/beets-config.yaml + sed -i "s/strong_rec_thresh: 0.04/strong_rec_thresh: 0.${beetsMatchPercentage}/g" "${STATE_DIR}/extended/beets-config.yaml" fi else log "Beets Tagging Disabled" @@ -195,11 +197,7 @@ Configuration () { } DownloadClientFreyr () { - timeout $downloadClientTimeOut freyr --no-bar --no-net-check -d $audioPath/incomplete deezer:album:$1 2>&1 | tee -a "/config/logs/$logFileName" - # Resolve issue 94 - if [ -d /root/.cache/FreyrCLI ]; then - rm -rf /root/.cache/FreyrCLI/* - fi + timeout $downloadClientTimeOut freyr --no-bar --no-net-check -d "$audioPath/incomplete" "deezer:album:$1" 2>&1 } DownloadFormat () { @@ -222,9 +220,7 @@ DownloadFormat () { log "ERROR :: Change audioBitrate to a low, high, or lossless..." log "ERROR :: Exiting..." NotifyWebhook "FatalError" "Invalid audioFormat and audioBitrate options set" - log "Script sleeping for $audioScriptInterval..." - sleep $audioScriptInterval - exit + exit 1 fi else bitrateError="false" @@ -246,9 +242,7 @@ DownloadFormat () { log "ERROR :: Change audioBitrate to a desired bitrate number, example: 192..." log "ERROR :: Exiting..." NotifyWebhook "FatalError" "audioBitrate options set" - log "Script sleeping for $audioScriptInterval..." - sleep $audioScriptInterval - exit + exit 1 fi case "$audioFormat" in @@ -281,45 +275,32 @@ DownloadFolderCleaner () { if [ -d "$audioPath/complete" ]; then log "Removing prevously completed downloads that failed to import..." # check for completed downloads older than 1 day - if find "$audioPath"/complete -mindepth 1 -type d -mtime +1 | read; then + if find "$audioPath/complete" -mindepth 1 -type d -mtime +1 | read -r; then # delete completed downloads older than 1 day, these most likely failed to import due to Lidarr failing to match - find "$audioPath"/complete -mindepth 1 -type d -mtime +1 -exec rm -rf "{}" \; &>/dev/null - fi - fi -} - -NotFoundFolderCleaner () { - # check for completed download folder - if [ -d /config/extended/logs/notfound ]; then - # check for notfound entries older than X days - if find /config/extended/logs/notfound -mindepth 1 -type f -mtime +$retryNotFound | read; then - log "Removing prevously notfound lidarr album ids older than $retryNotFound days to give them a retry..." - # delete ntofound entries older than X days - find /config/extended/logs/notfound -mindepth 1 -type f -mtime +$retryNotFound -delete + find "$audioPath/complete" -mindepth 1 -type d -mtime +1 -exec rm -rf "{}" \; &>/dev/null fi fi } TidalClientSetup () { log "TIDAL :: Verifying tidal-dl configuration" - touch /config/xdg/.tidal-dl.log - if [ -f /config/xdg/.tidal-dl.json ]; then - rm /config/xdg/.tidal-dl.json + touch "${STATE_DIR}/xdg/.tidal-dl.log" + if [ -f "${STATE_DIR}/xdg/.tidal-dl.json" ]; then + rm "${STATE_DIR}/xdg/.tidal-dl.json" fi - if [ ! -f /config/xdg/.tidal-dl.json ]; then + if [ ! -f "${STATE_DIR}/xdg/.tidal-dl.json" ]; then log "TIDAL :: No default config found, importing default config \"tidal.json\"" - if [ -f /config/extended/tidal-dl.json ]; then - cp /config/extended/tidal-dl.json /config/xdg/.tidal-dl.json - chmod 777 -R /config/xdg/ + if [ -f "${STATE_DIR}/extended/tidal-dl.json" ]; then + cp "${STATE_DIR}/extended/tidal-dl.json" "${STATE_DIR}/xdg/.tidal-dl.json" fi fi TidaldlStatusCheck - tidal-dl -o "$audioPath"/incomplete 2>&1 | tee -a "/config/logs/$logFileName" + tidal-dl -o "$audioPath/incomplete" 2>&1 DownloadFormat - if [ ! -f /config/xdg/.tidal-dl.token.json ]; then + if [ ! -f "${STATE_DIR}/xdg/.tidal-dl.token.json" ]; then TidaldlStatusCheck #log "TIDAL :: ERROR :: Downgrade tidal-dl for workaround..." #pip3 install tidal-dl==2022.3.4.2 --no-cache-dir &>/dev/null @@ -329,21 +310,19 @@ TidalClientSetup () { tidal-dl fi - if [ ! -d /config/extended/cache/tidal ]; then - mkdir -p /config/extended/cache/tidal - chmod 777 /config/extended/cache/tidal + if [ ! -d "${STATE_DIR}/extended/cache/tidal" ]; then + mkdir -p "${STATE_DIR}/extended/cache/tidal" fi - if [ -d /config/extended/cache/tidal ]; then + if [ -d "${STATE_DIR}/extended/cache/tidal" ]; then log "TIDAL :: Purging album list cache..." - rm /config/extended/cache/tidal/*-albums.json &>/dev/null + rm "${STATE_DIR}/extended/cache/tidal/*-albums.json" &>/dev/null fi if [ ! -d "$audioPath/incomplete" ]; then mkdir -p "$audioPath"/incomplete - chmod 777 "$audioPath"/incomplete else - rm -rf "$audioPath"/incomplete/* + rm -rf "$audioPath/incomplete/*" fi TidaldlStatusCheck @@ -353,16 +332,15 @@ TidalClientSetup () { } TidaldlStatusCheck () { - until false - do - running=no - if ps aux | grep "tidal-dl" | grep -v "grep" | read; then - running=yes - log "STATUS :: TIDAL-DL :: BUSY :: Pausing/waiting for all active tidal-dl tasks to end..." - sleep 2 - continue - fi - break + until false; do + running=no + if pgrep -f "tidal-dl" | read -r; then + running=yes + log "STATUS :: TIDAL-DL :: BUSY :: Pausing/waiting for all active tidal-dl tasks to end..." + sleep 2 + continue + fi + break done } @@ -370,37 +348,42 @@ TidalClientTest () { log "TIDAL :: tidal-dl client setup verification..." i=0 while [ $i -lt 3 ]; do - i=$(( $i + 1 )) + i=$(( i + 1 )) TidaldlStatusCheck - tidal-dl -q Normal -o "$audioPath"/incomplete -l "$tidalClientTestDownloadId" 2>&1 | tee -a "/config/logs/$logFileName" - downloadCount=$(find "$audioPath"/incomplete -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | wc -l) - if [ $downloadCount -le 0 ]; then + tidal-dl -q Normal -o "$audioPath/incomplete" -l "$tidalClientTestDownloadId" 2>&1 + downloadCount=$(find "$audioPath/incomplete" -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | wc -l) + if [ "$downloadCount" -le 0 ]; then continue else break fi done tidalClientTest="unknown" - if [ $downloadCount -le 0 ]; then - if [ -f /config/xdg/.tidal-dl.token.json ]; then - rm /config/xdg/.tidal-dl.token.json + if [ "$downloadCount" -le 0 ]; then + if [ -f "${STATE_DIR}/xdg/.tidal-dl.token.json" ]; then + rm "${STATE_DIR}/xdg/.tidal-dl.token.json" fi log "TIDAL :: ERROR :: Download failed" log "TIDAL :: ERROR :: You will need to re-authenticate on next script run..." log "TIDAL :: ERROR :: Exiting..." - rm -rf "$audioPath"/incomplete/* + rm -rf "$audioPath/incomplete/*" NotifyWebhook "Error" "TIDAL not authenticated but configured" tidalClientTest="failed" log "Script sleeping for $audioScriptInterval..." sleep $audioScriptInterval exit else - rm -rf "$audioPath"/incomplete/* + rm -rf "$audioPath/incomplete/*" log "TIDAL :: Successfully Verified" tidalClientTest="success" fi } +logDl () { + log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: \ + $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: $1" +} + DownloadProcess () { # Required Input Data @@ -412,107 +395,71 @@ DownloadProcess () { # Create Required Directories if [ ! -d "$audioPath/incomplete" ]; then - mkdir -p "$audioPath"/incomplete - chmod 777 "$audioPath"/incomplete + mkdir -p "$audioPath/incomplete" else - rm -rf "$audioPath"/incomplete/* + rm -rf "$audioPath/incomplete/*" fi if [ ! -d "$audioPath/complete" ]; then - mkdir -p "$audioPath"/complete - chmod 777 "$audioPath"/complete + mkdir -p "$audioPath/complete" else - rm -rf "$audioPath"/complete/* + rm -rf "$audioPath/complete/*" fi + - if [ ! -d "/config/extended/logs" ]; then - mkdir -p /config/extended/logs - chmod 777 /config/extended/logs - fi - - if [ ! -d "/config/extended/logs/downloaded" ]; then - mkdir -p /config/extended/logs/downloaded - chmod 777 /config/extended/logs/downloaded - fi - - if [ ! -d "/config/extended/logs/downloaded/deezer" ]; then - mkdir -p /config/extended/logs/downloaded/deezer - chmod 777 /config/extended/logs/downloaded/deezer - fi - - if [ ! -d "/config/extended/logs/downloaded/tidal" ]; then - mkdir -p /config/extended/logs/downloaded/tidal - chmod 777 /config/extended/logs/downloaded/tidal - fi - - if [ ! -d /config/extended/logs/downloaded/failed/deezer ]; then - mkdir -p /config/extended/logs/downloaded/failed/deezer - chmod 777 /config/extended/logs/downloaded/failed/deezer - fi - - if [ ! -d /config/extended/logs/downloaded/failed/tidal ]; then - mkdir -p /config/extended/logs/downloaded/failed/tidal - chmod 777 /config/extended/logs/downloaded/failed/tidal - fi + logPaths=( "deezer" "tidal" "failed/deezer" "failed/tidal" ) + for p in "${!logPaths[@]}"; do + if [ ! -d "${STATE_DIR}/extended/logs/downloaded/${logPaths[$p]}" ]; then + mkdir -p "${STATE_DIR}/extended/logs/downloaded/${logPaths[$p]}" + fi + done if [ ! -d "$importPath" ]; then mkdir -p "$importPath" - chmod 777 "$importPath" fi AddDownloadClient downloadedAlbumTitleClean="$(echo "$4" | sed -e "s%[^[:alpha:][:digit:]._' ]% %g" -e "s/ */ /g" | sed 's/^[.]*//' | sed 's/[.]*$//g' | sed 's/^ *//g' | sed 's/ *$//g')" - if find "$audioPath"/complete -type d -iname "$lidarrArtistNameSanitized-$downloadedAlbumTitleClean ($3)-*-$1-$2" | read; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: ERROR :: Previously Downloaded..." + if find "$audioPath/complete" -type d -iname "$lidarrArtistNameSanitized-$downloadedAlbumTitleClean ($3)-*-$1-$2" | read -r; then + logDl "ERROR :: Previously Downloaded..." return fi # check for log file - if [ "$2" == "DEEZER" ]; then - if [ -f /config/extended/logs/downloaded/deezer/$1 ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: ERROR :: Previously Downloaded ($1)..." - return - fi - if [ -f /config/extended/logs/downloaded/failed/deezer/$1 ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: ERROR :: Previously Attempted Download ($1)..." - return - fi - fi + + for i in "DEEZER" "TIDAL"; do + if [ "$2" == $i ]; then + if [ -f "${STATE_DIR}/extended/logs/downloaded/${i,,}/$1" ]; then + logDl "ERROR :: Previously Downloaded ($1)..." + return + fi + if [ -f "${STATE_DIR}/extended/logs/downloaded/failed/${i,,}/$1" ]; then + logDl "ERROR :: Previously Attempted Download ($1)..." + return + fi + fi + done - # check for log file - if [ "$2" == "TIDAL" ]; then - if [ -f /config/extended/logs/downloaded/tidal/$1 ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: ERROR :: Previously Downloaded ($1)..." - return - fi - if [ -f /config/extended/logs/downloaded/failed/tidal/$1 ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: ERROR :: Previously Attempted Download ($1)..." - return - fi - fi - - - downloadTry=0 until false do - downloadTry=$(( $downloadTry + 1 )) - if [ -f /temp-download ]; then - rm /temp-download + downloadTry=$(( downloadTry + 1 )) + if [ -f /tmp/temp-download ]; then + rm /tmp/temp-download sleep 0.1 fi - touch /temp-download + touch /tmp/temp-download sleep 0.1 - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Download Attempt number $downloadTry" + logDl "Download Attempt number $downloadTry" if [ "$2" == "DEEZER" ]; then - if [ -z $arlToken ]; then - DownloadClientFreyr $1 + if [ -z "$arlToken" ]; then + DownloadClientFreyr "$1" else - deemix -b $deemixQuality -p "$audioPath"/incomplete "https://www.deezer.com/album/$1" 2>&1 | tee -a "/config/logs/$logFileName" + deemix -b $deemixQuality -p "$audioPath"/incomplete "https://www.deezer.com/album/$1" 2>&1 fi if [ -d "/tmp/deemix-imgs" ]; then @@ -521,49 +468,43 @@ DownloadProcess () { # Verify Client Works... clientTestDlCount=$(find "$audioPath"/incomplete/ -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | wc -l) - if [ $clientTestDlCount -le 0 ]; then + if [ "$clientTestDlCount" -le 0 ]; then # Add +1 to failed attempts - deemixFail=$(( $deemixFail + 1)) + deemixFail=$(( deemixFail + 1)) else # Reset for successful download deemixFail=0 fi # If download failes X times, exit with error... - if [ $deemixFail -eq $failedDownloadAttemptThreshold ]; then - if [ -z $arlToken ]; then - rm -rf "$audioPath"/incomplete/* - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: All $failedDownloadAttemptThreshold Download Attempts failed, skipping..." - else - DeezerClientTest - if [ "$deezerClientTest" == "success" ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: All $failedDownloadAttemptThreshold Download Attempts failed, skipping..." - deemixFail=0 - fi + if [ $deemixFail -eq $failedDownloadAttemptThreshold ] && [ -z "$arlToken" ]; then + rm -rf "$audioPath"/incomplete/* + logDl "All $failedDownloadAttemptThreshold Download Attempts failed, skipping..." + else + DeezerClientTest + if [ "$deezerClientTest" == "success" ]; then + logDl "All $failedDownloadAttemptThreshold Download Attempts failed, skipping..." + deemixFail=0 fi fi fi - if [ "$2" == "DEEZER" ]; then - if [ $deemixFail -eq $failedDownloadAttemptThreshold ]; then - if [ -z $arlToken ]; then - DownloadClientFreyr $1 - else - deemix -b $deemixQuality -p "$audioPath"/incomplete "https://www.deezer.com/album/$1" 2>&1 | tee -a "/config/logs/$logFileName" - fi - fi - fi + if [ "$2" == "DEEZER" ] && [ $deemixFail -eq $failedDownloadAttemptThreshold ] && [ -z "$arlToken" ]; then + DownloadClientFreyr "$1" + else + deemix -b $deemixQuality -p "$audioPath"/incomplete "https://www.deezer.com/album/$1" 2>&1 + fi if [ "$2" == "TIDAL" ]; then TidaldlStatusCheck - tidal-dl -q $tidalQuality -o "$audioPath/incomplete" -l "$1" 2>&1 | tee -a "/config/logs/$logFileName" + tidal-dl -q $tidalQuality -o "$audioPath/incomplete" -l "$1" 2>&1 # Verify Client Works... clientTestDlCount=$(find "$audioPath"/incomplete/ -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | wc -l) - if [ $clientTestDlCount -le 0 ]; then + if [ "$clientTestDlCount" -le 0 ]; then # Add +1 to failed attempts - tidaldlFail=$(( $tidaldlFail + 1)) + tidaldlFail=$(( tidaldlFail + 1)) else # Reset for successful download tidaldlFail=0 @@ -571,29 +512,29 @@ DownloadProcess () { # If download failes X times, exit with error... if [ $tidaldlFail -eq $failedDownloadAttemptThreshold ]; then - TidalClientTest - if [ "$tidalClientTest" == "success" ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: All $failedDownloadAttemptThreshold Download Attempts failed, skipping..." + TidalClientTest + if [ "$tidalClientTest" == "success" ]; then + logDl "All $failedDownloadAttemptThreshold Download Attempts failed, skipping..." fi fi fi - find "$audioPath/incomplete" -type f -iname "*.flac" -newer "/temp-download" -print0 | while IFS= read -r -d '' file; do + find "$audioPath/incomplete" -type f -iname "*.flac" -newer "/tmp/temp-download" -print0 | while IFS= read -r -d '' file; do audioFlacVerification "$file" if [ "$verifiedFlacFile" == "0" ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Flac Verification :: $file :: Verified" + logDl "Flac Verification :: $file :: Verified" else - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Flac Verification :: $file :: ERROR :: Failed Verification" + logDl "Flac Verification :: $file :: ERROR :: Failed Verification" rm "$file" fi done downloadCount=$(find "$audioPath"/incomplete/ -type f -regex ".*/.*\.\(flac\|m4a\|mp3\)" | wc -l) if [ "$downloadCount" -ne "$5" ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: ERROR :: download failed, missing tracks..." + logDl "ERROR :: download failed, missing tracks..." completedVerification="false" else - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Success" + logDl "Success" completedVerification="true" fi @@ -605,13 +546,13 @@ DownloadProcess () { fi break else - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Retry Download in 1 second fix errors..." + logDl "Retry Download in 1 second fix errors..." sleep 1 fi done # Consolidate files to a single folder - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Consolidating files to single folder" + logDl "Consolidating files to single folder" find "$audioPath/incomplete" -type f -exec mv "{}" "$audioPath"/incomplete/ \; 2>/dev/null find $audioPath/incomplete/ -type d -mindepth 1 -maxdepth 1 -exec rm -rf {} \; 2>/dev/null @@ -623,34 +564,28 @@ DownloadProcess () { downloadCount=$(find "$audioPath"/incomplete/ -type f -regex ".*/.*\.\(flac\|m4a\|mp3\)" | wc -l) if [ "$downloadCount" -ne "$5" ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: ERROR :: All download Attempts failed..." - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Logging $1 as failed download..." + logDl "ERROR :: All download Attempts failed..." + logDl "Logging $1 as failed download..." - if [ "$2" == "DEEZER" ]; then - touch /config/extended/logs/downloaded/failed/deezer/$1 - fi - if [ "$2" == "TIDAL" ]; then - touch /config/extended/logs/downloaded/failed/tidal/$1 - fi + for awa in "DEEZER" "TIDAL"; do + [ "$2" == $awa ] \ + && touch "${STATE_DIR}/extended/logs/downloaded/failed/${awa,,}/$1" + done return fi # Log Completed Download - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Logging $1 as successfully downloaded..." - if [ "$2" == "DEEZER" ]; then - touch /config/extended/logs/downloaded/deezer/$1 - fi - if [ "$2" == "TIDAL" ]; then - touch /config/extended/logs/downloaded/tidal/$1 - fi + logDl "Logging $1 as successfully downloaded..." + for awa in "DEEZER" "TIDAL"; do + [ "$2" == $awa ] \ + && touch "${STATE_DIR}/extended/logs/downloaded/${awa,,}/$1" + done # Tag with beets if [ "$enableBeetsTagging" == "true" ]; then - if [ -f /config/extended/beets-error ]; then - rm /config/extended/beets-error - fi - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Processing files with beets..." + [ -f "${STATE_DIR}/extended/beets-error" ] && rm "${STATE_DIR}/extended/beets-error" + logDl "Processing files with beets..." ProcessWithBeets "$audioPath/incomplete" fi @@ -658,33 +593,30 @@ DownloadProcess () { find "$audioPath/incomplete" -type f -iname "*.flac" -print0 | while IFS= read -r -d '' file; do lrcFile="${file%.*}.lrc" if [ -f "$lrcFile" ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Embedding lyrics (lrc) into $file" + logDl "Embedding lyrics (lrc) into $file" metaflac --remove-tag=Lyrics "$file" metaflac --set-tag-from-file="Lyrics=$lrcFile" "$file" fi done if [ "$audioFormat" != "native" ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Converting Flac Audio to ${audioFormat^^} ($audioBitrateText)" - if [ "$audioFormat" == "opus" ]; then - options="-c:a libopus -b:a ${audioBitrate}k -application audio -vbr off" - extension="opus" - fi + logDl "Converting Flac Audio to ${audioFormat^^} ($audioBitrateText)" - if [ "$audioFormat" == "mp3" ]; then - options="-c:a libmp3lame -b:a ${audioBitrate}k" - extension="mp3" - fi + [ "$audioFormat" == "opus" ] \ + && options="-c:a libopus -b:a ${audioBitrate}k -application audio -vbr off" \ + && extension=$audioFormat - if [ "$audioFormat" == "aac" ]; then - options="-c:a aac -b:a ${audioBitrate}k -movflags faststart" - extension="m4a" - fi + [ "$audioFormat" == "mp3" ] \ + && options="-c:a libmp3lame -b:a ${audioBitrate}k" \ + && extension=$audioFormat - if [ "$audioFormat" == "alac" ]; then - options="-c:a alac -movflags faststart" - extension="m4a" - fi + [ "$audioFormat" == "aac" ] \ + && options="-c:a aac -b:a ${audioBitrate}k -movflags faststart" \ + && extension="m4a" + + [ "$audioFormat" == "alac" ] \ + && options="-c:a alac -movflags faststart" \ + && extension="m4a" find "$audioPath/incomplete" -type f -iname "*.flac" -print0 | while IFS= read -r -d '' audio; do file="${audio}" @@ -693,20 +625,20 @@ DownloadProcess () { filenamenoext="${filename%.*}" if [ "$audioFormat" == "opus" ]; then if opusenc --bitrate ${audioBitrate} --vbr --music "$file" "$foldername/${filenamenoext}.$extension"; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: $filename :: Conversion to $audioFormat ($audioBitrateText) successful" + logDl "$filename :: Conversion to $audioFormat ($audioBitrateText) successful" rm "$file" else - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: $filename :: ERROR :: Conversion Failed" + logDl "$filename :: ERROR :: Conversion Failed" rm "$foldername/${filenamenoext}.$extension" fi continue fi - if ffmpeg -loglevel warning -hide_banner -nostats -i "$file" -n -vn $options "$foldername/${filenamenoext}.$extension" < /dev/null; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: $filename :: Conversion to $audioFormat ($audioBitrateText) successful" + if ffmpeg -loglevel warning -hide_banner -nostats -i "$file" -n -vn "$options" "$foldername/${filenamenoext}.$extension" < /dev/null; then + logDl "$filename :: Conversion to $audioFormat ($audioBitrateText) successful" rm "$file" else - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: $filename :: ERROR :: Conversion Failed" + logDl "$filename :: ERROR :: Conversion Failed" rm "$foldername/${filenamenoext}.$extension" fi done @@ -716,10 +648,10 @@ DownloadProcess () { if [ "$enableReplaygainTags" == "true" ]; then AddReplaygainTags "$audioPath/incomplete" else - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Replaygain Tagging Disabled (set enableReplaygainTags=true to enable...)" + logDl "Replaygain Tagging Disabled (set enableReplaygainTags=true to enable...)" fi - albumquality="$(find "$audioPath"/incomplete/ -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | head -n 1 | egrep -i -E -o "\.{1}\w*$" | sed 's/\.//g')" + albumquality="$(find "$audioPath"/incomplete/ -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | head -n 1 | grep -i -E -o "\.{1}\w*$" | sed 's/\.//g')" downloadedAlbumFolder="${lidarrArtistNameSanitized}-${downloadedAlbumTitleClean:0:100} (${3})" find "$audioPath/incomplete" -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" -print0 | while IFS= read -r -d '' audio; do @@ -754,196 +686,168 @@ DownloadProcess () { ProcessWithBeets () { # Input # $1 Download Folder to process - if [ -f /config/extended/beets-library.blb ]; then - rm /config/extended/beets-library.blb - sleep 0.5 - fi - if [ -f /config/extended/beets.log ]; then - rm /config/extended/beets.log - sleep 0.5 - fi + for awa in "extended/beets-library.blb" "extended/beets.log" "beets-match"; do + [ -f "${STATE_DIR}/${awa}" ] \ + && rm "${STATE_DIR}/${awa}" \ + && sleep 0.5 + done - if [ -f "/config/beets-match" ]; then - rm "/config/beets-match" - sleep 0.5 - fi touch "/config/beets-match" sleep 0.5 - beet -c /config/extended/beets-config.yaml -l /config/extended/beets-library.blb -d "$1" import -qC "$1" - if [ $(find "$1" -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" -newer "/config/beets-match" | wc -l) -gt 0 ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: SUCCESS: Matched with beets!" - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: fixing track tags" + beet -c "${STATE_DIR}/extended/beets-config.yaml" \ + -l "${STATE_DIR}/extended/beets-library.blb" -d "$1" import -qC "$1" + + if [ "$(find "$1" -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" -newer "${STATE_DIR}/beets-match" | wc -l)" -gt 0 ]; then + + logDl "SUCCESS: Matched with beets!" + logDl "fixing track tags" + find "$audioPath/incomplete" -type f -iname "*.flac" -print0 | while IFS= read -r -d '' file; do getArtistCredit="$(ffprobe -loglevel 0 -print_format json -show_format -show_streams "$file" | jq -r ".format.tags.ARTIST_CREDIT" | sed "s/null//g" | sed "/^$/d")" # album artist - metaflac --remove-tag=ALBUMARTIST "$file" - metaflac --remove-tag=ALBUMARTIST_CREDIT "$file" - metaflac --remove-tag=ALBUM_ARTIST "$file" - metaflac --remove-tag="ALBUM ARTIST" "$file" - # artist - metaflac --remove-tag=ARTIST "$file" - metaflac --remove-tag=ARTIST_CREDIT "$file" - if [ ! -z "$getArtistCredit" ]; then - metaflac --set-tag=ARTIST="$getArtistCredit" "$file" + metaflac \ + --remove-tag=ALBUMARTIST --remove-tag=ALBUMARTIST_CREDIT --remove-tag=ALBUM_ARTIST \ + --remove-tag="ALBUM ARTIST" --remove-tag=ARTIST --remove-tag=ARTIST_CREDIT \ + --remove-tag=ARTISTSORT --remove-tag=COMPOSERSORT --remove-tag=ALBUMARTISTSORT \ + --remove-tag=MUSICBRAINZ_ARTISTID --remove-tag=MUSICBRAINZ_ALBUMARTISTID \ + "$file" + + metaflac \ + --set-tag=ALBUMARTIST="$lidarrArtistName" \ + --set-tag=MUSICBRAINZ_ARTISTID="$lidarrArtistForeignArtistId" \ + --set-tag=MUSICBRAINZ_ALBUMARTISTID="$lidarrArtistForeignArtistId" \ + "$file" + + if [ -n "$getArtistCredit" ]; then + metaflac --set-tag=ARTIST="$getArtistCredit" "$file" else metaflac --set-tag=ARTIST="$lidarrArtistName" "$file" fi - # sorts - metaflac --remove-tag=ARTISTSORT "$file" - metaflac --remove-tag=COMPOSERSORT "$file" - metaflac --remove-tag=ALBUMARTISTSORT "$file" - # lidarr - metaflac --set-tag=ALBUMARTIST="$lidarrArtistName" "$file" - # mbrainz - metaflac --remove-tag=MUSICBRAINZ_ARTISTID "$file" - metaflac --remove-tag=MUSICBRAINZ_ALBUMARTISTID "$file" - metaflac --set-tag=MUSICBRAINZ_ARTISTID="$lidarrArtistForeignArtistId" "$file" - metaflac --set-tag=MUSICBRAINZ_ALBUMARTISTID="$lidarrArtistForeignArtistId" "$file" - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: FIXED : $file" + + log "FIXED : $file" done else - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: ERROR :: Unable to match using beets to a musicbrainz release..." + log "ERROR :: Unable to match using beets to a musicbrainz release..." return fi - if [ -f "/config/beets-match" ]; then - rm "/config/beets-match" - sleep 0.1 - fi + [ -f "${STATE_DIR}/beets-match" ] \ + && rm "${STATE_DIR}/beets-match" \ + && sleep 0.1 # Get file metadata GetFile=$(find "$audioPath/incomplete" -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | head -n1) extension="${GetFile##*.}" + + ffprobeGet=$(ffprobe -hide_banner -loglevel fatal -show_error -show_format -show_streams \ + -show_programs -show_chapters -show_private_data -print_format json \ + "$GetFile" + ) + if [ "$extension" == "opus" ]; then - matchedTags=$(ffprobe -hide_banner -loglevel fatal -show_error -show_format -show_streams -show_programs -show_chapters -show_private_data -print_format json "$GetFile" | jq -r ".streams[].tags") + matchedTags=$(${ffprobeGet} | jq -r ".streams[].tags") else - matchedTags=$(ffprobe -hide_banner -loglevel fatal -show_error -show_format -show_streams -show_programs -show_chapters -show_private_data -print_format json "$GetFile" | jq -r ".format.tags") + matchedTags=$(${ffprobeGet} | jq -r ".format.tags") fi # Get Musicbrainz Release Group ID and Album Artist ID from tagged file if [ "$extension" == "flac" ] || [ "$extension" == "opus" ]; then - matchedTagsAlbumReleaseGroupId="$(echo $matchedTags | jq -r ".MUSICBRAINZ_RELEASEGROUPID")" - matchedTagsAlbumArtistId="$(echo $matchedTags | jq -r ".MUSICBRAINZ_ALBUMARTISTID")" + matchedTagsAlbumReleaseGroupId="$(echo "$matchedTags" | jq -r ".MUSICBRAINZ_RELEASEGROUPID")" + matchedTagsAlbumArtistId="$(echo "$matchedTags" | jq -r ".MUSICBRAINZ_ALBUMARTISTID")" elif [ "$extension" == "mp3" ] || [ "$extension" == "m4a" ]; then - matchedTagsAlbumReleaseGroupId="$(echo $matchedTags | jq -r '."MusicBrainz Release Group Id"')" - matchedLidarrAlbumArtistId="$(echo $matchedTags | jq -r '."MusicBrainz Ablum Artist Id"')" + matchedTagsAlbumReleaseGroupId="$(echo "$matchedTags" | jq -r '."MusicBrainz Release Group Id"')" + matchedLidarrAlbumArtistId="$(echo "$matchedTags" | jq -r '."MusicBrainz Ablum Artist Id"')" fi - if [ ! -d "/config/extended/logs/downloaded/musicbrainz_matched" ]; then - mkdir -p "/config/extended/logs/downloaded/musicbrainz_matched" - chmod 777 "/config/extended/logs/downloaded/musicbrainz_matched" - fi + [ ! -d "${STATE_DIR}/extended/logs/downloaded/musicbrainz_matched" ] \ + && mkdir -p "${STATE_DIR}/extended/logs/downloaded/musicbrainz_matched" - if [ ! -f "/config/extended/logs/downloaded/musicbrainz_matched/$matchedTagsAlbumReleaseGroupId" ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Marking MusicBrainz Release Group ($matchedTagsAlbumReleaseGroupId) as successfully downloaded..." - touch "/config/extended/logs/downloaded/musicbrainz_matched/$matchedTagsAlbumReleaseGroupId" - - fi + [ ! -f "${STATE_DIR}/extended/logs/downloaded/musicbrainz_matched/$matchedTagsAlbumReleaseGroupId" ] \ + && log "Marking MusicBrainz Release Group ($matchedTagsAlbumReleaseGroupId) as successfully downloaded..." \ + && touch "/config/extended/logs/downloaded/musicbrainz_matched/$matchedTagsAlbumReleaseGroupId" } DownloadQualityCheck () { - if [ "$requireQuality" == "true" ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Checking for unwanted files" + [ "$requireQuality" != "true" ] \ + && logDl "Skipping download quality check... (enable by setting: requireQuality=true)" \ + && return - if [ "$audioFormat" != "native" ]; then - if find "$1" -type f -regex ".*/.*\.\(opus\|m4a\|mp3\)"| read; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Unwanted files found!" - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Performing cleanup..." - rm "$1"/* - else - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: No unwanted files found!" - fi - fi - if [ "$audioFormat" == "native" ]; then - if [ "$audioBitrate" == "master" ]; then - if find "$1" -type f -regex ".*/.*\.\(opus\|m4a\|mp3\)"| read; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Unwanted files found!" - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Performing cleanup..." - rm "$1"/* - else - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: No unwanted files found!" - fi - elif [ "$audioBitrate" == "lossless" ]; then - if find "$1" -type f -regex ".*/.*\.\(opus\|m4a\|mp3\)"| read; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Unwanted files found!" - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Performing cleanup..." - rm "$1"/* - else - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: No unwanted files found!" - fi - elif [ "$2" == "DEEZER" ]; then - if find "$1" -type f -regex ".*/.*\.\(opus\|m4a\|flac\)"| read; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Unwanted files found!" - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Performing cleanup..." - rm "$1"/* - else - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: No unwanted files found!" - fi - elif [ "$2" == "TIDAL" ]; then - if find "$1" -type f -regex ".*/.*\.\(opus\|flac\|mp3\)"| read; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Unwanted files found!" - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Performing cleanup..." - rm "$1"/* - else - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: No unwanted files found!" - fi - fi - fi + logDl "Checking for unwanted files" + + local deezer + local tidal + local other + local notNative + notNative=$([ "$audioFormat" != "native" ] \ + && find "$1" -type f -regex ".*/.*\.\(opus\|m4a\|mp3\)" | read -r + ) + other=$([ "$audioBitrate" == "master" ] || [ "$audioBitrate" == "lossless" ] \ + && find "$1" -type f -regex ".*/.*\.\(opus\|m4a\|mp3\)" | read -r + ) + deezer=$([ "$2" == "DEEZER" ] \ + && find "$1" -type f -regex ".*/.*\.\(opus\|m4a\|flac\)" | read -r + ) + tidal=$([ "$2" == "TIDAL" ] \ + && find "$1" -type f -regex ".*/.*\.\(opus\|flac\|mp3\)" | read -r + ) + + if $notNative || $deezer || $tidal || $other; then + logDl "Unwanted files found!" + logDl "Performing cleanup..." + rm "$1"/* else - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Skipping download quality check... (enable by setting: requireQuality=true)" + logDl "No unwanted files found!" fi } AddReplaygainTags () { # Input Data # $1 Folder path to scan and add tags - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Adding Replaygain Tags using r128gain" + logDl "Adding Replaygain Tags using r128gain" r128gain -r -c 1 -a "$1" &>/dev/null } NotifyLidarrForImport () { - LidarrProcessIt=$(curl -s "$arrUrl/api/v1/command" --header "X-Api-Key:"${arrApiKey} -H "Content-Type: application/json" --data "{\"name\":\"DownloadedAlbumsScan\", \"path\":\"$1\"}") - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: LIDARR IMPORT NOTIFICATION SENT! :: $1" + curl -s "$arrUrl/api/v1/command" --header "X-Api-Key:" "${arrApiKey}" -H "Content-Type: application/json" --data "{\"name\":\"DownloadedAlbumsScan\", \"path\":\"$1\"}" + logDl "LIDARR IMPORT NOTIFICATION SENT! :: $1" } DeemixClientSetup () { log "DEEZER :: Verifying deemix configuration" - if [ ! -z "$arlToken" ]; then - arlToken="$(echo $arlToken | sed -e "s%[^[:alpha:][:digit:]]%%g" -e "s/ */ /g" | sed 's/^[.]*//' | sed 's/[.]*$//g' | sed 's/^ *//g' | sed 's/ *$//g')" + if [ -n "$arlToken" ]; then + arlToken="$(echo "$arlToken" | sed -e "s%[^[:alpha:][:digit:]]%%g" -e "s/ */ /g" | sed 's/^[.]*//' | sed 's/[.]*$//g' | sed 's/^ *//g' | sed 's/ *$//g')" # Create directories - mkdir -p /config/xdg/deemix - if [ -f "/config/xdg/deemix/.arl" ]; then - rm "/config/xdg/deemix/.arl" + mkdir -p "${STATE_DIR}/xdg/deemix" + if [ -f "${STATE_DIR}/xdg/deemix/.arl" ]; then + rm "${STATE_DIR}/xdg/deemix/.arl" fi - if [ ! -f "/config/xdg/deemix/.arl" ]; then - echo -n "$arlToken" > "/config/xdg/deemix/.arl" + if [ ! -f "${STATE_DIR}/xdg/deemix/.arl" ]; then + echo -n "$arlToken" > "/${STATE_DIR}/xdg/deemix/.arl" fi log "DEEZER :: ARL Token: Configured" else log "DEEZER :: ERROR :: arlToken setting invalid, currently set to: $arlToken" fi - if [ -f "/config/xdg/deemix/config.json" ]; then - rm /config/xdg/deemix/config.json + if [ -f "${STATE_DIR}/xdg/deemix/config.json" ]; then + rm "${STATE_DIR}/xdg/deemix/config.json" fi - if [ -f "/config/extended/deemix_config.json" ]; then + if [ -f "${STATE_DIR}/extended/deemix_config.json" ]; then log "DEEZER :: Configuring deemix client" - cp /config/extended/deemix_config.json /config/xdg/deemix/config.json - chmod 777 /config/xdg/deemix/config.json + cp "${STATE_DIR}/extended/deemix_config.json" "${STATE_DIR}/xdg/deemix/config.json" fi - if [ -d /config/extended/cache/deezer ]; then + if [ -d "${STATE_DIR}/extended/cache/deezer" ]; then log "DEEZER :: Purging album list cache..." - rm /config/extended/cache/deezer/*-albums.json &>/dev/null + rm "${STATE_DIR}/extended/cache/deezer/*-albums.json" &>/dev/null fi if [ ! -d "$audioPath/incomplete" ]; then mkdir -p "$audioPath"/incomplete - chmod 777 "$audioPath"/incomplete else rm -rf "$audioPath"/incomplete/* fi @@ -956,22 +860,20 @@ DeemixClientSetup () { DeezerClientTest () { log "DEEZER :: deemix client setup verification..." - deemix -b 128 -p $audioPath/incomplete "https://www.deezer.com/album/$deezerClientTestDownloadId" 2>&1 | tee -a "/config/logs/$logFileName" + deemix -b 128 -p $audioPath/incomplete "https://www.deezer.com/album/$deezerClientTestDownloadId" if [ -d "/tmp/deemix-imgs" ]; then rm -rf /tmp/deemix-imgs fi deezerClientTest="unknown" downloadCount=$(find $audioPath/incomplete/ -type f -regex ".*/.*\.\(flac\|opus\|m4a\|mp3\)" | wc -l) - if [ $downloadCount -le 0 ]; then + if [ "$downloadCount" -le 0 ]; then log "DEEZER :: ERROR :: Download failed" log "DEEZER :: ERROR :: Please review log for errors in client" log "DEEZER :: ERROR :: Try updating your ARL Token to possibly resolve the issue..." log "DEEZER :: ERROR :: Exiting..." rm -rf $audioPath/incomplete/* NotifyWebhook "Error" "DEEZER not authenticated but configured" - deezerClientTest="fail" - log "Script sleeping for $audioScriptInterval..." - sleep $audioScriptInterval + deezerClientTest="fail" exit else rm -rf $audioPath/incomplete/* @@ -982,13 +884,11 @@ DeezerClientTest () { } LidarrRootFolderCheck () { - if curl -s "$arrUrl/api/v1/rootFolder" -H "X-Api-Key: ${arrApiKey}" | sed '1q' | grep "\[\]" | read; then + if curl -s "$arrUrl/api/v1/rootFolder" -H "X-Api-Key: ${arrApiKey}" | sed '1q' | grep "\[\]" | read -r; then log "ERROR :: No root folder found" log "ERROR :: Configure root folder in Lidarr to continue..." log "ERROR :: Exiting..." NotifyWebhook "FatalError" "No root folder found" - log "Script sleeping for $audioScriptInterval..." - sleep $audioScriptInterval exit fi } @@ -996,27 +896,22 @@ LidarrRootFolderCheck () { GetMissingCutOffList () { # Remove previous search missing/cutoff list - if [ -d /config/extended/cache/lidarr/list ]; then - rm -rf /config/extended/cache/lidarr/list - sleep 0.1 - fi + [ -d "${STATE_DIR}/extended/cache/lidarr/list" ] \ + && rm -rf "${STATE_DIR}/extended/cache/lidarr/list" \ + && sleep 0.1 # Create list folder if does not exist - mkdir -p /config/extended/cache/lidarr/list + mkdir -p "${STATE_DIR}/extended/cache/lidarr/list" # Create notfound log folder if does not exist - if [ ! -d /config/extended/logs/notfound ]; then - mkdir -p /config/extended/logs/notfound - chmod 777 /config/extended/logs/notfound - fi + [ ! -d "${STATE_DIR}/extended/logs/notfound" ] \ + && mkdir -p "${STATE_DIR}/extended/logs/notfound" # Configure searchSort preferences based on settings if [ "$searchSort" == "date" ]; then searchOrder="releaseDate" searchDirection="descending" - fi - - if [ "$searchSort" == "album" ]; then + elif [ "$searchSort" == "album" ]; then searchOrder="albumType" searchDirection="ascending" fi @@ -1029,78 +924,98 @@ GetMissingCutOffList () { page=0 log "$lidarrMissingTotalRecords Missing Albums Found!" log "Getting Missing Album IDs" - if [ $lidarrMissingTotalRecords -ge 1 ]; then - offsetcount=$(( $lidarrMissingTotalRecords / $amountPerPull )) - for ((i=0;i<=$offsetcount;i++)); do - page=$(( $i + 1 )) - offset=$(( $i * $amountPerPull )) - dlnumber=$(( $offset + $amountPerPull )) + if [ "$lidarrMissingTotalRecords" -ge 1 ]; then + offsetcount=$(( lidarrMissingTotalRecords / amountPerPull )) + for ((i=0;i<=offsetcount;i++)); do + page=$(( i + 1 )) + offset=$(( i * amountPerPull )) + dlnumber=$(( offset + amountPerPull )) if [ "$dlnumber" -gt "$lidarrMissingTotalRecords" ]; then dlnumber="$lidarrMissingTotalRecords" fi log "$page :: missing :: Downloading page $page... ($offset - $dlnumber of $lidarrMissingTotalRecords Results)" - wget --timeout=0 -q -O - "$arrUrl/api/v1/wanted/missing?page=$page&pagesize=$amountPerPull&sortKey=$searchOrder&sortDirection=$searchDirection&apikey=${arrApiKey}" | jq -r '.records[].id' | sort > /config/extended/cache/tocheck.txt - log "$page :: missing :: Filtering Album IDs by removing previously searched Album IDs (/config/extended/logs/notfound/)" - ls /config/extended/logs/notfound/ | sed "s/--.*//" > /config/extended/cache/notfound.txt - for lidarrRecordId in $(comm -13 /config/extended/cache/notfound.txt /config/extended/cache/tocheck.txt); do - if [ ! -f /config/extended/logs/notfound/$lidarrRecordId--* ]; then - touch "/config/extended/cache/lidarr/list/${lidarrRecordId}-missing" - fi + wget --timeout=0 -q -O - \ + "$arrUrl/api/v1/wanted/missing?page=$page&pagesize=$amountPerPull&sortKey=$searchOrder&sortDirection=$searchDirection&apikey=${arrApiKey}" \ + | jq -r '.records[].id' \ + | sort > /config/extended/cache/tocheck.txt + + log "$page :: missing :: Filtering Album IDs by removing previously searched Album IDs (/config/extended/logs/notfound/)" + + ls "${STATE_DIR}/extended/logs/notfound/" | sed "s/--.*//" > "${STATE_DIR}/extended/cache/notfound.txt" + + for lidarrRecordId in $(comm -13 "${STATE_DIR}/extended/cache/notfound.txt" "${STATE_DIR}/extended/cache/tocheck.txt"); do + for f in /config/extended/logs/notfound/"$lidarrRecordId"--*; do + if [ ! -f "$f" ]; then + touch "${STATE_DIR}/extended/cache/lidarr/list/${lidarrRecordId}-missing" + fi + done done - rm /config/extended/cache/notfound.txt /config/extended/cache/tocheck.txt + rm "${STATE_DIR}/extended/cache/notfound.txt" "${STATE_DIR}/extended/cache/tocheck.txt" - lidarrMissingRecords=$(ls /config/extended/cache/lidarr/list 2>/dev/null | wc -l) + lidarrMissingRecords=$(ls "${STATE_DIR}/extended/cache/lidarr/list" 2>/dev/null | wc -l) log "$page :: missing :: ${lidarrMissingRecords} albums found to process!" wantedListAlbumTotal=$lidarrMissingRecords - if [ ${lidarrMissingRecords} -gt 0 ]; then + if [ "${lidarrMissingRecords}" -gt 0 ]; then log "$page :: missing :: Searching for $wantedListAlbumTotal items" SearchProcess - rm /config/extended/cache/lidarr/list/*-missing + rm "${STATE_DIR}/extended/cache/lidarr/list/*-missing" fi done fi # Get cutoff album list - lidarrCutoffTotalRecords=$(wget --timeout=0 -q -O - "$arrUrl/api/v1/wanted/cutoff?page=1&pagesize=1&sortKey=$searchOrder&sortDirection=$searchDirection&apikey=${arrApiKey}" | jq -r .totalRecords) + lidarrCutoffTotalRecords=$(wget --timeout=0 -q -O - \ + "$arrUrl/api/v1/wanted/cutoff?page=1&pagesize=1&sortKey=$searchOrder&sortDirection=$searchDirection&apikey=${arrApiKey}" \ + | jq -r .totalRecords + ) + log "FINDING CUTOFF ALBUMS sorted by $searchSort" log "$lidarrCutoffTotalRecords CutOff Albums Found Found!" log "Getting CutOff Album IDs" + page=0 - if [ $lidarrCutoffTotalRecords -ge 1 ]; then - offsetcount=$(( $lidarrCutoffTotalRecords / $amountPerPull )) - for ((i=0;i<=$offsetcount;i++)); do - page=$(( $i + 1 )) - offset=$(( $i * $amountPerPull )) - dlnumber=$(( $offset + $amountPerPull )) + if [ "$lidarrCutoffTotalRecords" -ge 1 ]; then + offsetcount=$(( lidarrCutoffTotalRecords / amountPerPull )) + for ((i=0;i<=offsetcount;i++)); do + page=$(( i + 1 )) + offset=$(( i * amountPerPull )) + dlnumber=$(( offset + amountPerPull )) if [ "$dlnumber" -gt "$lidarrCutoffTotalRecords" ]; then dlnumber="$lidarrCutoffTotalRecords" fi log "$page :: cutoff :: Downloading page $page... ($offset - $dlnumber of $lidarrCutoffTotalRecords Results)" # lidarrRecords=$(wget --timeout=0 -q -O - "$arrUrl/api/v1/wanted/cutoff?page=$page&pagesize=$amountPerPull&sortKey=$searchOrder&sortDirection=$searchDirection&apikey=${arrApiKey}" | jq -r '.records[].id') - wget --timeout=0 -q -O - "$arrUrl/api/v1/wanted/cutoff?page=$page&pagesize=$amountPerPull&sortKey=$searchOrder&sortDirection=$searchDirection&apikey=${arrApiKey}" | jq -r '.records[].id' | sort > /config/extended/cache/tocheck.txt + wget --timeout=0 -q -O - \ + "$arrUrl/api/v1/wanted/cutoff?page=$page&pagesize=$amountPerPull&sortKey=$searchOrder&sortDirection=$searchDirection&apikey=${arrApiKey}" \ + | jq -r '.records[].id' \ + | sort > "${STATE_DIR}/extended/cache/tocheck.txt" log "$page :: cutoff :: Filtering Album IDs by removing previously searched Album IDs (/config/extended/logs/notfound/)" ls /config/extended/logs/notfound/ | sed "s/--.*//" > /config/extended/cache/notfound.txt - for lidarrRecordId in $(comm -13 /config/extended/cache/notfound.txt /config/extended/cache/tocheck.txt); do - if [ ! -f /config/extended/logs/notfound/$lidarrRecordId--* ]; then - touch /config/extended/cache/lidarr/list/${lidarrRecordId}-cutoff - fi + for lidarrRecordId in $(comm -13 "${STATE_DIR}/extended/cache/notfound.txt" "${STATE_DIR}/extended/cache/tocheck.txt"); do + for f in /config/extended/logs/notfound/"$lidarrRecordId"--*; do + if [ ! -f "$f" ]; then + touch "${STATE_DIR}/extended/cache/lidarr/list/${lidarrRecordId}-missing" + fi + done done - rm /config/extended/cache/notfound.txt /config/extended/cache/tocheck.txt + rm "${STATE_DIR}/extended/cache/notfound.txt" "${STATE_DIR}/extended/cache/tocheck.txt" - lidarrCutoffRecords=$(ls /config/extended/cache/lidarr/list/*-cutoff 2>/dev/null | wc -l) + local cutoffFiles + cutoffFiles=("${STATE_DIR}/extended/cache/lidarr/list/*-cutoff") + lidarrCutoffRecords=${#cutoffFiles[@]} log "$page :: cutoff :: ${lidarrCutoffRecords} albums found to process!" wantedListAlbumTotal=$lidarrCutoffRecords - if [ ${lidarrCutoffRecords} -gt 0 ]; then + if [ "${lidarrCutoffRecords}" -gt 0 ]; then log "$page :: cutoff :: Searching for $wantedListAlbumTotal items" SearchProcess - rm /config/extended/cache/lidarr/list/*-cutoff + rm "${STATE_DIR}/extended/cache/lidarr/list/*-cutoff" fi done @@ -1115,9 +1030,9 @@ SearchProcess () { fi processNumber=0 - for lidarrMissingId in $(ls -tr /config/extended/cache/lidarr/list); do - processNumber=$(( $processNumber + 1 )) - wantedAlbumId=$(echo $lidarrMissingId | sed -e "s%[^[:digit:]]%%g") + for lidarrMissingId in $(ls -tr "${STATE_DIR}/extended/cache/lidarr/list"); do + processNumber=$(( processNumber + 1 )) + wantedAlbumId=$(echo "$lidarrMissingId" | sed -e "s%[^[:digit:]]%%g") checkLidarrAlbumId=$wantedAlbumId wantedAlbumListSource=$(echo $lidarrMissingId | sed -e "s%[^[:alpha:]]%%g") lidarrAlbumData="$(curl -s "$arrUrl/api/v1/album/$wantedAlbumId?apikey=${arrApiKey}")" @@ -1130,31 +1045,26 @@ SearchProcess () { LidarrTaskStatusCheck - if [ -f "/config/extended/logs/notfound/$wantedAlbumId--$lidarrArtistForeignArtistId--$lidarrAlbumForeignAlbumId" ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $wantedAlbumListSource :: $lidarrAlbumType :: $wantedAlbumListSource :: $lidarrArtistName :: $lidarrAlbumTitle :: Previously Not Found, skipping..." + [ -f "${STATE_DIR}/extended/logs/notfound/$wantedAlbumId--$lidarrArtistForeignArtistId--$lidarrAlbumForeignAlbumId" ] \ + && logDl "$wantedAlbumListSource :: $lidarrArtistName :: $lidarrAlbumTitle :: Previously Not Found, skipping..." \ + && continue + + # Skip Video Check for Various Artists album searches because videos are not supported... + if [ "$enableVideo" == "true" ] \ + && [ "$lidarrArtistForeignArtistId" != "89ad4ac3-39f7-470e-963a-56509c546377" ] \ + && [ -d "${STATE_DIR}/extended/logs/video/complete" ] \ + && [ ! -f "${STATE_DIR}/extended/logs/video/complete/$lidarrArtistForeignArtistId" ]; then + logDl "$wantedAlbumListSource :: $lidarrArtistName :: $lidarrAlbumTitle :: Skipping until all videos are processed for the artist..." + continue + else + logDl "$wantedAlbumListSource :: $lidarrArtistName :: $lidarrAlbumTitle :: Skipping until all videos are processed for the artist..." continue fi - - if [ "$enableVideoScript" == "true" ]; then - # Skip Video Check for Various Artists album searches because videos are not supported... - if [ "$lidarrArtistForeignArtistId" != "89ad4ac3-39f7-470e-963a-56509c546377" ]; then - if [ -d /config/extended/logs/video/complete ]; then - if [ ! -f "/config/extended/logs/video/complete/$lidarrArtistForeignArtistId" ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrAlbumType :: $wantedAlbumListSource :: $lidarrArtistName :: $lidarrAlbumTitle :: Skipping until all videos are processed for the artist..." - continue - fi - else - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrAlbumType :: $wantedAlbumListSource :: $lidarrArtistName :: $lidarrAlbumTitle :: Skipping until all videos are processed for the artist..." - continue - fi - fi - fi - if [ -f "/config/extended/logs/downloaded/notfound/$lidarrAlbumForeignAlbumId" ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrAlbumTitle :: $lidarrAlbumType :: Previously Not Found, skipping..." - rm "/config/extended/logs/downloaded/notfound/$lidarrAlbumForeignAlbumId" - touch "/config/extended/logs/notfound/$wantedAlbumId--$lidarrArtistForeignArtistId--$lidarrAlbumForeignAlbumId" - chmod 777 "/config/extended/logs/notfound/$wantedAlbumId--$lidarrArtistForeignArtistId--$lidarrAlbumForeignAlbumId" + if [ -f "${STATE_DIR}/extended/logs/downloaded/notfound/$lidarrAlbumForeignAlbumId" ]; then + logDL "Previously Not Found, skipping..." + rm "${STATE_DIR}/extended/logs/downloaded/notfound/$lidarrAlbumForeignAlbumId" + touch "${STATE_DIR}/extended/logs/notfound/$wantedAlbumId--$lidarrArtistForeignArtistId--$lidarrAlbumForeignAlbumId" continue fi @@ -1182,71 +1092,65 @@ SearchProcess () { lidarrAlbumReleasesMaxTrackCount=$(echo "$lidarrAlbumData" | jq -r ".releases[].trackCount" | sort -n -r | head -n1) lidarrAlbumReleaseDate=$(echo "$lidarrAlbumData" | jq -r .releaseDate) lidarrAlbumReleaseDate=${lidarrAlbumReleaseDate:0:10} - lidarrAlbumReleaseDateClean="$(echo $lidarrAlbumReleaseDate | sed -e "s%[^[:digit:]]%%g")" + lidarrAlbumReleaseDateClean="$(echo "$lidarrAlbumReleaseDate" | sed -e "s%[^[:digit:]]%%g")" lidarrAlbumReleaseYear="${lidarrAlbumReleaseDate:0:4}" - currentDate="$(date "+%F")" - currentDateClean="$(echo "$currentDate" | sed -e "s%[^[:digit:]]%%g")" + currentDate="$(date "+%Y%m%d")" - + if [[ ${currentDate} -ge ${lidarrAlbumReleaseDateClean} ]]; then + skipNotFoundLogCreation="false" - if [[ ${currentDateClean} -ge ${lidarrAlbumReleaseDateClean} ]]; then - skipNotFoundLogCreation="false" - releaseDateComparisonInDays=$(( ${currentDateClean} - ${lidarrAlbumReleaseDateClean} )) - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Starting Search..." + releaseDateComparisonInDays=$(( $(( \ + $(date --date="$currentDate" "+%s") - $(date --date="$lidarrAlbumReleaseDateClean" "+%s") \ + )) / 60 / 60 / 24 \ + )) + logDl "Starting Search..." if [ $releaseDateComparisonInDays -lt 8 ]; then skipNotFoundLogCreation="true" fi else - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Album ($lidarrAlbumReleaseDate) has not been released, skipping..." + logDl "Album ($lidarrAlbumReleaseDate) has not been released, skipping..." continue fi - if [ "$dlClientSource" == "deezer" ]; then - skipTidal=true - skipDeezer=false - fi - if [ "$dlClientSource" == "tidal" ]; then - skipDeezer=true - skipTidal=false - fi - - if [ "$dlClientSource" == "both" ]; then - skipDeezer=false - skipTidal=false - fi + skipTidal=$([ "$dlClientSource" != "tidal" ] && [ "$dlClientSource" != "both" ]) + skipDeezer=$([ "$dlClientSource" != "deezer" ] && [ "$dlClientSource" != "both" ]) if [ "$skipDeezer" == "false" ]; then - + mapfile -t deezerArtistIds < <(echo "$deezerArtistUrl" | grep -o '[[:digit:]]*' | sort -u) if [ -z "$deezerArtistUrl" ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: DEEZER :: ERROR :: musicbrainz id: $lidarrArtistForeignArtistId is missing Deezer link, see: \"/config/logs/deezer-artist-id-not-found.txt\" for more detail..." - touch "/config/logs/deezer-artist-id-not-found.txt" - if cat "/config/logs/deezer-artist-id-not-found.txt" | grep "https://musicbrainz.org/artist/$lidarrArtistForeignArtistId/edit" | read; then + log "DEEZER :: ERROR :: musicbrainz id: $lidarrArtistForeignArtistId is missing Deezer link, see: \ + \"${STATE_DIR}/logs/deezer-artist-id-not-found.txt\" for more detail..." + touch "${STATE_DIR}/logs/deezer-artist-id-not-found.txt" + skipDeezer=true + if grep "https://musicbrainz.org/artist/$lidarrArtistForeignArtistId/edit" "${STATE_DIR}/logs/deezer-artist-id-not-found.txt" | read -r; then sleep 0.01 else - echo "Update Musicbrainz Relationship Page: https://musicbrainz.org/artist/$lidarrArtistForeignArtistId/edit for \"${lidarrArtistName}\" with Deezer Artist Link" >> "/config/logs/deezer-artist-id-not-found.txt" - chmod 777 "/config/logs/deezer-artist-id-not-found.txt" - NotifyWebhook "ArtistError" "Update Musicbrainz Relationship Page: for ${lidarrArtistName} with Deezer Artist Link" + echo "Update Musicbrainz Relationship Page: \ + https://musicbrainz.org/artist/$lidarrArtistForeignArtistId/edit for \"${lidarrArtistName}\" with Deezer Artist Link" \ + >> "${STATE_DIR}/logs/deezer-artist-id-not-found.txt" + NotifyWebhook "ArtistError" \ + "Update Musicbrainz Relationship Page: \ + for ${lidarrArtistName} with Deezer Artist Link" fi - skipDeezer=true fi - deezerArtistIds=($(echo "$deezerArtistUrl" | grep -o '[[:digit:]]*' | sort -u)) fi - if [ "$skipTidal" == "false" ]; then - - if [ -z "$tidalArtistUrl" ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: TIDAL :: ERROR :: musicbrainz id: $lidarrArtistForeignArtistId is missing Tidal link, see: \"/config/logs/tidal-artist-id-not-found.txt\" for more detail..." - touch "/config/logs/tidal-artist-id-not-found.txt" - if cat "/config/logs/tidal-artist-id-not-found.txt" | grep "https://musicbrainz.org/artist/$lidarrArtistForeignArtistId/edit" | read; then - sleep 0.01 - else - echo "Update Musicbrainz Relationship Page: https://musicbrainz.org/artist/$lidarrArtistForeignArtistId/edit for \"${lidarrArtistName}\" with Tidal Artist Link" >> "/config/logs/tidal-artist-id-not-found.txt" - chmod 777 "/config/logs/tidal-artist-id-not-found.txt" - NotifyWebhook "ArtistError" "Update Musicbrainz Relationship Page: for ${lidarrArtistName} with Tidal Artist Link" - fi - skipTidal=true + if [ "$skipTidal" == "false" ] && [ -z "$tidalArtistUrl" ]; then + log "TIDAL :: ERROR :: musicbrainz id: $lidarrArtistForeignArtistId is missing Tidal link, see: \ + \"${STATE_DIR}/logs/tidal-artist-id-not-found.txt\" for more detail..." + touch "${STATE_DIR}/logs/tidal-artist-id-not-found.txt" + skipTidal=true + if grep "https://musicbrainz.org/artist/$lidarrArtistForeignArtistId/edit" "${STATE_DIR}/logs/tidal-artist-id-not-found.txt" | read -r; then + sleep 0.01 + else + echo "Update Musicbrainz Relationship Page: \ + https://musicbrainz.org/artist/$lidarrArtistForeignArtistId/edit for \"${lidarrArtistName}\" with Tidal Artist Link" \ + >> "${STATE_DIR}/logs/tidal-artist-id-not-found.txt" + NotifyWebhook "ArtistError" \ + "Update Musicbrainz Relationship Page: \ + for ${lidarrArtistName} with Tidal Artist Link" fi fi @@ -1259,10 +1163,10 @@ SearchProcess () { # Get Release Titles & Disambiguation - if [ -f /temp-release-list ]; then - rm /temp-release-list - fi - for releaseId in $(echo "$lidarrAlbumReleaseIds"); do + [ -f "/tmp/temp-release-list" ] \ + && rm /tmp/temp-release-list + + for releaseId in $lidarrAlbumReleaseIds; do releaseTitle=$(echo "$lidarrAlbumData" | jq -r ".releases[] | select(.id==$releaseId) | .title") releaseDisambiguation=$(echo "$lidarrAlbumData" | jq -r ".releases[] | select(.id==$releaseId) | .disambiguation") if [ -z "$releaseDisambiguation" ]; then @@ -1270,26 +1174,25 @@ SearchProcess () { else releaseDisambiguation=" ($releaseDisambiguation)" fi - echo "${releaseTitle}${releaseDisambiguation}" >> /temp-release-list + echo "${releaseTitle}${releaseDisambiguation}" >> /tmp/temp-release-list done - echo "$lidarrAlbumTitle" >> /temp-release-list + + echo "$lidarrAlbumTitle" >> /tmp/temp-release-list # Get Release Titles OLDIFS="$IFS" IFS=$'\n' if [ "$preferSpecialEditions" == "true" ]; then - lidarrReleaseTitles=$(cat /temp-release-list | awk '{ print length, $0 }' | sort -u -n -s -r | cut -d" " -f2-) + lidarrReleaseTitles=$(< /tmp/temp-release-list awk '{ print length, $0 }' | sort -u -n -s -r | cut -d" " -f2-) else - lidarrReleaseTitles=$(cat /temp-release-list | awk '{ print length, $0 }' | sort -u -n -s | cut -d" " -f2-) + lidarrReleaseTitles=$(< /tmp/temp-release-list awk '{ print length, $0 }' | sort -u -n -s | cut -d" " -f2-) fi - lidarrReleaseTitles=($(echo "$lidarrReleaseTitles")) + mapfile -t lidarrReleaseTitles < <(echo "$lidarrReleaseTitles") IFS="$OLDIFS" loopCount=0 - until false - do - - loopCount=$(( $loopCount + 1 )) + until false; do + loopCount=$(( loopCount + 1 )) if [ "$loopCount" == "1" ]; then # First loop is either explicit or clean depending on script settings if [ "$audioLyricType" == "both" ] || [ "$audioLyricType" == "explicit" ]; then @@ -1304,11 +1207,11 @@ SearchProcess () { lidarrDownloadImportNotfication="false" releaseProcessCount=0 - for title in ${!lidarrReleaseTitles[@]}; do - releaseProcessCount=$(( $releaseProcessCount + 1)) + for title in "${!lidarrReleaseTitles[@]}"; do + releaseProcessCount=$(( releaseProcessCount + 1)) lidarrReleaseTitle="${lidarrReleaseTitles[$title]}" lidarrAlbumReleaseTitleClean=$(echo "$lidarrReleaseTitle" | sed -e "s%[^[:alpha:][:digit:]]%%g" -e "s/ */ /g" | sed 's/^[.]*//' | sed 's/[.]*$//g' | sed 's/^ *//g' | sed 's/ *$//g') - lidarrAlbumReleaseTitleClean="${lidarrAlbumReleaseTitleClean:0:130}" + lidarrAlbumReleaseTitleClean="${lidarrAlbumReleaseTitleClean:0:130}" lidarrAlbumReleaseTitleSearchClean="$(echo "$lidarrReleaseTitle" | sed -e "s%[^[:alpha:][:digit:]]% %g" -e "s/ */ /g" | sed 's/^[.]*//' | sed 's/[.]*$//g' | sed 's/^ *//g' | sed 's/ *$//g')" lidarrAlbumReleaseTitleFirstWord="$(echo "$lidarrReleaseTitle" | awk '{ print $1 }')" lidarrAlbumReleaseTitleFirstWord="${lidarrAlbumReleaseTitleFirstWord:0:3}" @@ -1316,44 +1219,30 @@ SearchProcess () { #echo "Debugging :: $loopCount :: $releaseProcessCount :: $lidarrArtistForeignArtistId :: $lidarrReleaseTitle :: $lidarrAlbumReleasesMinTrackCount-$lidarrAlbumReleasesMaxTrackCount :: $lidarrAlbumReleaseTitleFirstWord :: $albumArtistNameSearch :: $albumTitleSearch" - if echo "$lidarrAlbumTitle" | grep -i "instrumental" | read; then + if echo "$lidarrAlbumTitle" | grep -i "instrumental" | read -r; then sleep 0.01 - else - # ignore instrumental releases - if [ "$ignoreInstrumentalRelease" == "true" ]; then - if echo "$lidarrReleaseTitle" | grep -i "instrumental" | read; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Instrumental Release Found, Skipping..." - continue - fi - fi + elif [ "$ignoreInstrumentalRelease" == "true" ] && echo "$lidarrReleaseTitle" | grep -i "instrumental" | read -r ; then + logDl "Instrumental Release Found, Skipping..." + continue fi # Skip Various Artists album search that is not supported... - if [ "$lidarrArtistForeignArtistId" != "89ad4ac3-39f7-470e-963a-56509c546377" ]; then - - #log "1 : $lidarrDownloadImportNotfication" - + if [ "$lidarrArtistForeignArtistId" != "89ad4ac3-39f7-470e-963a-56509c546377" ] \ + && [ "$lidarrDownloadImportNotfication" == "false" ]; then # Tidal Artist search - if [ "$lidarrDownloadImportNotfication" == "false" ]; then - if [ "$dlClientSource" == "both" ] || [ "$dlClientSource" == "tidal" ]; then - for tidalArtistId in $(echo $tidalArtistIds); do - ArtistTidalSearch "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal" "$tidalArtistId" "$lyricFilter" - sleep 0.01 - done - fi + if [ "$dlClientSource" == "both" ] || [ "$dlClientSource" == "tidal" ]; then + for tidalArtistId in $tidalArtistIds; do + ArtistTidalSearch "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal" "$tidalArtistId" "$lyricFilter" + sleep 0.01 + done fi - - #log "2 : $lidarrDownloadImportNotfication" - # Deezer artist search - if [ "$lidarrDownloadImportNotfication" == "false" ]; then - if [ "$dlClientSource" == "both" ] || [ "$dlClientSource" == "deezer" ]; then - for dId in ${!deezerArtistIds[@]}; do - deezerArtistId="${deezerArtistIds[$dId]}" - ArtistDeezerSearch "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal" "$deezerArtistId" "$lyricFilter" - sleep 0.01 - done - fi + if [ "$dlClientSource" == "both" ] || [ "$dlClientSource" == "deezer" ]; then + for dId in "${!deezerArtistIds[@]}"; do + deezerArtistId="${deezerArtistIds[$dId]}" + ArtistDeezerSearch "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal" "$deezerArtistId" "$lyricFilter" + sleep 0.01 + done fi fi @@ -1388,42 +1277,38 @@ SearchProcess () { # Break after all operations are complete if [ "$loopCount" == "$endLoop" ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Album Not found" + logDl "Album Not found" if [ "$skipNotFoundLogCreation" == "false" ]; then - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Marking Album as notfound" - if [ ! -f "/config/extended/logs/notfound/$wantedAlbumId--$lidarrArtistForeignArtistId--$lidarrAlbumForeignAlbumId" ]; then - touch "/config/extended/logs/notfound/$wantedAlbumId--$lidarrArtistForeignArtistId--$lidarrAlbumForeignAlbumId" - chmod 777 "/config/extended/logs/notfound/$wantedAlbumId--$lidarrArtistForeignArtistId--$lidarrAlbumForeignAlbumId" + logDl "Marking Album as notfound" + if [ ! -f "${STATE_DIR}/extended/logs/notfound/$wantedAlbumId--$lidarrArtistForeignArtistId--$lidarrAlbumForeignAlbumId" ]; then + touch "${STATE_DIR}/extended/logs/notfound/$wantedAlbumId--$lidarrArtistForeignArtistId--$lidarrAlbumForeignAlbumId" fi else - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Skip marking album as not found because it's a new release for 7 days..." + logDl "Skip marking album as not found because it's a new release for 7 days..." fi break fi done - - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Search Complete..." + logDl "Search Complete..." done } GetDeezerAlbumInfo () { - until false - do - log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: Getting Album info..." - if [ ! -f "/config/extended/cache/deezer/$1.json" ]; then - curl -s "https://api.deezer.com/album/$1" -o "/config/extended/cache/deezer/$1.json" + until false; do + logDl "Getting Album info..." + if [ ! -f "${STATE_DIR}/extended/cache/deezer/$1.json" ]; then + curl -s "https://api.deezer.com/album/$1" -o "${STATE_DIR}/extended/cache/deezer/$1.json" sleep $sleepTimer fi - if [ -f "/config/extended/cache/deezer/$1.json" ]; then - if jq -e . >/dev/null 2>&1 <<<"$(cat /config/extended/cache/deezer/$1.json)"; then + if [ -f "${STATE_DIR}/extended/cache/deezer/$1.json" ]; then + if jq -e . >/dev/null 2>&1 <<<"$(cat "${STATE_DIR}/extended/cache/deezer/$1.json")"; then log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: Album info downloaded and verified..." - chmod 777 /config/extended/cache/deezer/$1.json albumInfoVerified=true break else log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: Error getting album information" - if [ -f "/config/extended/cache/deezer/$1.json" ]; then - rm "/config/extended/cache/deezer/$1.json" + if [ -f "${STATE_DIR}/extended/cache/deezer/$1.json" ]; then + rm "${STATE_DIR}/extended/cache/deezer/$1.json" fi log "$page :: $wantedAlbumListSource :: $processNumber of $wantedListAlbumTotal :: $lidarrArtistName :: $lidarrAlbumTitle :: Retrying..." fi @@ -1441,18 +1326,16 @@ ArtistDeezerSearch () { # $3 Lyric Type (true or false) - false == Clean, true == Explicit # Get deezer artist album list - if [ ! -d /config/extended/cache/deezer ]; then - mkdir -p /config/extended/cache/deezer + if [ ! -d "${STATE_DIR}/extended/cache/deezer" ]; then + mkdir -p "${STATE_DIR}/extended/cache/deezer" fi - if [ ! -f "/config/extended/cache/deezer/$2-albums.json" ]; then - getDeezerArtistAlbums=$(curl -s "https://api.deezer.com/artist/$2/albums?limit=1000" > "/config/extended/cache/deezer/$2-albums.json") + if [ ! -f "${STATE_DIR}/extended/cache/deezer/$2-albums.json" ]; then + getDeezerArtistAlbums=$(curl -s "https://api.deezer.com/artist/$2/albums?limit=1000" > "${STATE_DIR}/extended/cache/deezer/$2-albums.json") sleep $sleepTimer - getDeezerArtistAlbumsCount="$(cat "/config/extended/cache/deezer/$2-albums.json" | jq -r .total)" + getDeezerArtistAlbumsCount="$(jq -r .total "${STATE_DIR}/extended/cache/deezer/$2-albums.json")" fi - if [ "$getDeezerArtistAlbumsCount" == "0" ]; then - return - fi + [ "$getDeezerArtistAlbumsCount" == "0" ] && return if [ "$3" == "true" ]; then type="Explicit" @@ -1460,18 +1343,26 @@ ArtistDeezerSearch () { type="Clean" fi - log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Artist Search :: Deezer :: $type :: $lidarrReleaseTitle :: Searching $2... (Track Count: $lidarrAlbumReleasesMinTrackCount-$lidarrAlbumReleasesMaxTrackCount)..." - log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Artist Search :: Deezer :: $type :: $lidarrReleaseTitle :: Filtering results by lyric type..." - deezerArtistAlbumsData=$(cat "/config/extended/cache/deezer/$2-albums.json" | jq -r .data[]) - deezerArtistAlbumsIds=$(echo "${deezerArtistAlbumsData}" | jq -r "select(.explicit_lyrics=="$3") | .id") + log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: \ + Artist Search :: Deezer :: $type :: $lidarrReleaseTitle :: \ + Searching $2... (Track Count: $lidarrAlbumReleasesMinTrackCount-$lidarrAlbumReleasesMaxTrackCount)..." + + log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: \ + Artist Search :: Deezer :: $type :: $lidarrReleaseTitle :: Filtering results by lyric type..." + + deezerArtistAlbumsData=$(jq -r .data[] "${STATE_DIR}/extended/cache/deezer/$2-albums.json") + deezerArtistAlbumsIds=$(echo "${deezerArtistAlbumsData}" | jq -r "select(.explicit_lyrics==\"$3\") | .id") resultsCount=$(echo "$deezerArtistAlbumsIds" | wc -l) - log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Artist Search :: Deezer :: $type :: $lidarrReleaseTitle :: $resultsCount search results found" - for deezerAlbumID in $(echo "$deezerArtistAlbumsIds"); do + + log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: \ + Artist Search :: Deezer :: $type :: $lidarrReleaseTitle :: $resultsCount search results found" + + for deezerAlbumID in $deezerArtistAlbumsIds; do deezerAlbumData="$(echo "$deezerArtistAlbumsData" | jq -r "select(.id==$deezerAlbumID)")" deezerAlbumTitle="$(echo "$deezerAlbumData" | jq -r ".title")" - deezerAlbumTitleClean="$(echo ${deezerAlbumTitle} | sed -e "s%[^[:alpha:][:digit:]]%%g" -e "s/ */ /g" | sed 's/^[.]*//' | sed 's/[.]*$//g' | sed 's/^ *//g' | sed 's/ *$//g')" - deezerAlbumTitleClean="${deezerAlbumTitleClean:0:130}" + deezerAlbumTitleClean="$(echo "${deezerAlbumTitle}" | sed -e "s%[^[:alpha:][:digit:]]%%g" -e "s/ */ /g" | sed 's/^[.]*//' | sed 's/[.]*$//g' | sed 's/^ *//g' | sed 's/ *$//g')" + deezerAlbumTitleClean="${deezerAlbumTitleClean:0:130}" GetDeezerAlbumInfo "$deezerAlbumID" deezerAlbumData="$(cat "/config/extended/cache/deezer/$deezerAlbumID.json")" deezerAlbumTrackCount="$(echo "$deezerAlbumData" | jq -r .nb_tracks)" @@ -1480,27 +1371,40 @@ ArtistDeezerSearch () { downloadedReleaseYear="${downloadedReleaseDate:0:4}" # Reject release if greater than the max track count - if [ "$deezerAlbumTrackCount" -gt "$lidarrAlbumReleasesMaxTrackCount" ]; then - continue - fi + [ "$deezerAlbumTrackCount" -gt "$lidarrAlbumReleasesMaxTrackCount" ] && continue # Reject release if less than the min track count - if [ "$deezerAlbumTrackCount" -lt "$lidarrAlbumReleasesMinTrackCount" ]; then - continue - fi + [ "$deezerAlbumTrackCount" -lt "$lidarrAlbumReleasesMinTrackCount" ] && continue - log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Artist Search :: Deezer :: $type :: $lidarrReleaseTitle :: $lidarrAlbumReleaseTitleClean vs $deezerAlbumTitleClean :: Checking for Match..." - log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Artist Search :: Deezer :: $type :: $lidarrReleaseTitle :: $lidarrAlbumReleaseTitleClean vs $deezerAlbumTitleClean :: Calculating Damerau-Levenshtein distance..." - diff=$(python -c "from pyxdameraulevenshtein import damerau_levenshtein_distance; print(damerau_levenshtein_distance(\"${lidarrAlbumReleaseTitleClean,,}\", \"${deezerAlbumTitleClean,,}\"))" 2>/dev/null) - if [ "$diff" -le "$matchDistance" ]; then - log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Artist Search :: Deezer :: $type :: $lidarrReleaseTitle :: $lidarrAlbumReleaseTitleClean vs $deezerAlbumTitleClean :: Deezer MATCH Found :: Calculated Difference = $diff" + log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: \ + Artist Search :: Deezer :: $type :: $lidarrReleaseTitle :: \ + $lidarrAlbumReleaseTitleClean vs $deezerAlbumTitleClean :: Checking for Match..." + + log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: \ + Artist Search :: Deezer :: $type :: $lidarrReleaseTitle :: \ + $lidarrAlbumReleaseTitleClean vs $deezerAlbumTitleClean :: Calculating Damerau-Levenshtein distance..." + + diff=$(python -c "from editdistpy import damerau_osa; \ + print(damerau_osa.distance(\"${lidarrAlbumReleaseTitleClean,,}\", \"${deezerAlbumTitleClean,,}\", $matchDistance))" \ + 2>/dev/null + ) + + if [ "$diff" != "-1" ]; then + log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: \ + Artist Search :: Deezer :: $type :: $lidarrReleaseTitle :: \ + $lidarrAlbumReleaseTitleClean vs $deezerAlbumTitleClean :: Deezer MATCH Found :: Calculated Difference = $diff" # Execute Download - log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Artist Search :: Deezer :: $type :: $lidarrReleaseTitle :: Downloading $deezerAlbumTrackCount Tracks :: $deezerAlbumTitle ($downloadedReleaseYear)" + log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: \ + Artist Search :: Deezer :: $type :: $lidarrReleaseTitle :: \ + Downloading $deezerAlbumTrackCount Tracks :: $deezerAlbumTitle ($downloadedReleaseYear)" DownloadProcess "$deezerAlbumID" "DEEZER" "$downloadedReleaseYear" "$deezerAlbumTitle" "$deezerAlbumTrackCount" else - log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Artist Search :: Deezer :: $type :: $lidarrReleaseTitle :: $lidarrAlbumReleaseTitleClean vs $deezerAlbumTitleClean :: Deezer Match Not Found :: Calculated Difference ($diff) greater than $matchDistance" + log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: \ + Artist Search :: Deezer :: $type :: $lidarrReleaseTitle :: \ + $lidarrAlbumReleaseTitleClean vs $deezerAlbumTitleClean :: \ + Deezer Match Not Found :: Calculated Difference ($diff) greater than $matchDistance" fi # End search if lidarr was successfully notified for import @@ -1521,11 +1425,12 @@ FuzzyDeezerSearch () { type="Clean" fi - if [ ! -d /config/extended/cache/deezer ]; then - mkdir -p /config/extended/cache/deezer - fi + [ ! -d "${STATE_DIR}/extended/cache/deezer" ] \ + && mkdir -p "${STATE_DIR}/extended/cache/deezer" - log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Fuzzy Search :: Deezer :: $type :: $lidarrReleaseTitle :: Searching... (Track Count: $lidarrAlbumReleasesMinTrackCount-$lidarrAlbumReleasesMaxTrackCount)" + log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: \ + Fuzzy Search :: Deezer :: $type :: $lidarrReleaseTitle :: \ + Searching... (Track Count: $lidarrAlbumReleasesMinTrackCount-$lidarrAlbumReleasesMaxTrackCount)" deezerSearch="" if [ "$lidarrArtistForeignArtistId" == "89ad4ac3-39f7-470e-963a-56509c546377" ]; then @@ -1535,9 +1440,13 @@ FuzzyDeezerSearch () { # Search with Artist for non VA albums deezerSearch=$(curl -s "https://api.deezer.com/search?q=artist:%22${albumArtistNameSearch}%22%20album:%22${albumTitleSearch}%22&strict=on&limit=20" | jq -r ".data[]") fi + resultsCount=$(echo "$deezerSearch" | jq -r .album.id | sort -u | wc -l) - log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Fuzzy Search :: Deezer :: $type :: $lidarrReleaseTitle :: $resultsCount search results found" - if [ ! -z "$deezerSearch" ]; then + + log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: \ + Fuzzy Search :: Deezer :: $type :: $lidarrReleaseTitle :: $resultsCount search results found" + + if [ -n "$deezerSearch" ]; then for deezerAlbumID in $(echo "$deezerSearch" | jq -r .album.id | sort -u); do deezerAlbumData="$(echo "$deezerSearch" | jq -r ".album | select(.id==$deezerAlbumID)")" deezerAlbumTitle="$(echo "$deezerAlbumData" | jq -r ".title")" @@ -1552,39 +1461,52 @@ FuzzyDeezerSearch () { downloadedReleaseDate="$(echo "$deezerAlbumData" | jq -r .release_date)" downloadedReleaseYear="${downloadedReleaseDate:0:4}" - if [ "$deezerAlbumExplicitLyrics" != "$2" ]; then - continue - fi - + [ "$deezerAlbumExplicitLyrics" != "$2" ] && continue # Reject release if greater than the max track count - if [ "$deezerAlbumTrackCount" -gt "$lidarrAlbumReleasesMaxTrackCount" ]; then - continue - fi - + [ "$deezerAlbumTrackCount" -gt "$lidarrAlbumReleasesMaxTrackCount" ] && continue # Reject release if less than the min track count - if [ "$deezerAlbumTrackCount" -lt "$lidarrAlbumReleasesMinTrackCount" ]; then - continue - fi + [ "$deezerAlbumTrackCount" -lt "$lidarrAlbumReleasesMinTrackCount" ] && continue - log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Fuzzy Search :: Deezer :: $type :: $lidarrReleaseTitle :: $lidarrAlbumReleaseTitleClean vs $deezerAlbumTitleClean :: Checking for Match..." - log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Fuzzy Search :: Deezer :: $type :: $lidarrReleaseTitle :: $lidarrAlbumReleaseTitleClean vs $deezerAlbumTitleClean :: Calculating Damerau-Levenshtein distance..." - diff=$(python -c "from pyxdameraulevenshtein import damerau_levenshtein_distance; print(damerau_levenshtein_distance(\"${lidarrAlbumReleaseTitleClean,,}\", \"${deezerAlbumTitleClean,,}\"))" 2>/dev/null) - if [ "$diff" -le "$matchDistance" ]; then - log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Fuzzy Search :: Deezer :: $type :: $lidarrReleaseTitle :: $lidarrAlbumReleaseTitleClean vs $deezerAlbumTitleClean :: Deezer MATCH Found :: Calculated Difference = $diff" - log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Fuzzy Search :: Deezer :: $type :: $lidarrReleaseTitle :: Downloading $deezerAlbumTrackCount Tracks :: $deezerAlbumTitle ($downloadedReleaseYear)" + log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: \ + Fuzzy Search :: Deezer :: $type :: $lidarrReleaseTitle :: \ + $lidarrAlbumReleaseTitleClean vs $deezerAlbumTitleClean :: Checking for Match..." + + log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: \ + Fuzzy Search :: Deezer :: $type :: $lidarrReleaseTitle :: \ + $lidarrAlbumReleaseTitleClean vs $deezerAlbumTitleClean :: Calculating Damerau-Levenshtein distance..." + + diff=$(python -c "from editdistpy import damerau_osa; \ + print(damerau_osa.distance(\"${lidarrAlbumReleaseTitleClean,,}\", \"${deezerAlbumTitleClean,,}\", $matchDistance))" \ + 2>/dev/null + ) + if [ "$diff" != "-1" ]; then + log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: \ + Fuzzy Search :: Deezer :: $type :: $lidarrReleaseTitle :: \ + $lidarrAlbumReleaseTitleClean vs $deezerAlbumTitleClean :: Deezer MATCH Found :: Calculated Difference = $diff" + + log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: \ + Fuzzy Search :: Deezer :: $type :: $lidarrReleaseTitle :: \ + Downloading $deezerAlbumTrackCount Tracks :: $deezerAlbumTitle ($downloadedReleaseYear)" DownloadProcess "$deezerAlbumID" "DEEZER" "$downloadedReleaseYear" "$deezerAlbumTitle" "$deezerAlbumTrackCount" else - log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Fuzzy Search :: Deezer :: $type :: $lidarrReleaseTitle :: $lidarrAlbumReleaseTitleClean vs $deezerAlbumTitleClean :: Deezer Match Not Found :: Calculated Difference ($diff) greater than $matchDistance" + log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: \ + Fuzzy Search :: Deezer :: $type :: $lidarrReleaseTitle :: \ + $lidarrAlbumReleaseTitleClean vs $deezerAlbumTitleClean :: \ + Deezer Match Not Found :: Calculated Difference ($diff) greater than $matchDistance" fi # End search if lidarr was successfully notified for import if [ "$lidarrDownloadImportNotfication" == "true" ]; then break fi done - log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Fuzzy Search :: Deezer :: $type :: $lidarrReleaseTitle :: ERROR :: Results found, but none matching search criteria..." + log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: \ + Fuzzy Search :: Deezer :: $type :: $lidarrReleaseTitle :: \ + ERROR :: Results found, but none matching search criteria..." else - log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: Fuzzy Search :: Deezer :: $type :: $lidarrReleaseTitle :: ERROR :: No results found via Fuzzy Search..." + log "$1 :: $lidarrArtistName :: $lidarrAlbumTitle :: $lidarrAlbumType :: \ + Fuzzy Search :: Deezer :: $type :: $lidarrReleaseTitle :: \ + ERROR :: No results found via Fuzzy Search..." fi } @@ -1783,9 +1705,6 @@ AudioProcess () { Configuration - # Perform NotFound Folder Cleanup process - NotFoundFolderCleaner - LidarrRootFolderCheck DownloadFormat @@ -1821,14 +1740,13 @@ AudioProcess () { log "Starting Script...." for (( ; ; )); do - let i++ - logfileSetup - verifyConfig + (( i++ )) || true + verifyConfig getArrAppInfo verifyApiAccess AudioProcess log "Script sleeping for $audioScriptInterval..." - sleep $audioScriptInterval + sleep "$audioScriptInterval" done exit