1 contributor
#!/bin/bash
DB=/var/lib/navidrome/navidrome.db
medias=/music
no_cover_flag=.no_cover
cover_img=cover
mbz_agent='getCover/0.1 (https://seb.lautre.net/git/seb/scripts)'
test -e $0.conf && source $0.conf
coverartarchive_api="https://coverartarchive.org/release"
coverart=$(mktemp --dry-run /dev/shm/XXXXXXXX)
sizes=(small 250 500 large 1200)
OK () { echo -e "\e[3;32m ${1:-OK} \e[0;m"; return 0; }
WARNING () { echo -e "\e[3;33m ${1:-alerte} \e[0;m"; return 1; }
ERROR () { echo -e "\e[3;31m ${1:-erreur} \e[0;m"; return 1; }
sql_request () {
sqlite3 $DB <<< "$1"
}
covered () {
case "${forcing_level:-none}" in
retry)
if test -w "${album#*:}/$no_cover_flag"; then
rm -f "${album#*:}/$no_cover_flag" 2>/dev/null
return 1
else
return 0
fi
;;
force)
rm -f "${album#*:}/$no_cover_flag" 2>/dev/null
return 1
;;
none)
if compgen -G "${album#*:}/$cover_img.*" > /dev/null; then
return 0
elif test -e "${album#*:}/$no_cover_flag"; then
return 0
else
return 1
fi
;;
esac
}
get_image () {
if curl -Ls $1 > /dev/shm/$2; then
mime_type=$(file -bn --mime-type /dev/shm/$2)
if [[ ${mime_type:-erreur} =~ ^image/ ]]; then
mv -f /dev/shm/$2 ${album#*:}/$cover_img.${2##*.} \
|| ERROR "échec en écriture"
else
WARNING "${album%%:*} type $mime_type"
fi
else
ERROR "${album%%:*} échec du téléchargement"
fi
}
get_spotify_access_token () {
if test -n "$spotifyID" -a -n "$spotifySecret"; then
spotify_access_token=$(curl --silent \
--request POST \
--url https://accounts.spotify.com/api/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header "Authorization: Basic $(base64 -w0 <<< $spotifyID:$spotifySecret | sed 's/K$/=/')" \
-d 'grant_type=client_credentials' | jq -r '.access_token // empty')
if test -z "$spotify_access_token"; then
ERROR "problème d'identifant Spotify"
spotify_access_token_error=1
echo ID: $spotifyID
fi
fi
}
get_from_mbz () {
curl -Ls $coverartarchive_api/${album%%:*} > $coverart
if test $(file -bn --mime-type $coverart) = application/json; then
unset img
for size in ${sizes[@]}; do
img=$(jq -r '.images | .[] | select(.front == true) | .thumbnails | ."'$size'"?' $coverart 2>/dev/null)
test -n "$img" && break
done
if test -n "$img"; then
get_image "$img" "${album%%:*}.${img##*.}"
fi
else
return 1
fi
}
get_from_spotify () {
if test -n "$album_name" -a -n "$artist"; then
curl --request GET --silent \
--header "Authorization: Bearer $spotify_access_token" \
--header 'Content-Type: application/json' \
--data 'type=album' \
--data "query==album:${_album_name}%20artist:${_artist}" \
--url "https://api.spotify.com/v1/search" > $coverart
found_albums=$(jq -r '.albums .total // empty' $coverart)
if test ${found_albums:-0} -gt 0; then
img=$(jq --raw-output --arg artist "${artist^^}" --arg album "${album_name^^}" "
.albums .items
| .[]
| select(.name | ascii_upcase == \$album)
| select(.artists | .[].name | ascii_upcase == \$artist)
| .images
| .[]
| select(.height == 300)
| .url // empty" $coverart)
if test -n "$img"; then
get_image "$img" "${img##*/}.jpg"
else
WARNING "pas d'image trouvée sur spotify (artist: $artist; album: $album_name)"
fi
else
WARNING "aucun album trouvé sur spotify"
fi
else
ERROR "album: $album_name; artist: $artist"
fi
}
if ! test -d $medias; then
ERROR "$medias n'est pas un répertoire"
exit 1
fi
if declare -f pre_get_cover > /dev/null; then
pre_get_cover
fi
IFS=$'\n'
for arg in $@; do
if [[ $arg =~ ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}:/ ]]; then
from_CLI=1
albums[${#albums[@]}]="${arg%/}"
elif [[ $arg =~ ^/ ]]; then
from_CLI=1
albums[${#albums[@]}]=":${arg%/}"
elif [[ $arg =~ ^(force|retry)$ ]]; then
forcing_level=$arg
else
WARNING "incohérence sur $arg"
fi
done
if test -n "$from_CLI"; then
forcing_level=force
fi
if test ${#albums[@]} -eq 0; then
albums=($(sql_request 'select printf("%s:'${medias%/}'/%s/%s", mbz_album_id, artist, name)
from album where cover_art_path = ""
and name != "[Unknown Album]"'))
fi
for album in ${albums[@]}; do
mbz_related=0
if ! test -d "${album#*:}"; then
if test -n "$from_CLI"; then
WARNING "${album#*:}: chemin inconnu"
fi
continue
fi
if covered; then
continue
fi
echo -n "${album#*:} "
if test -n "${album%%:*}"; then
mbz_related=1
if get_from_mbz; then
OK
continue
fi
fi
eval "$(sql_request 'select printf("artist=""%s"";album_name=""%s""", artist, name)
from album
where artist || "/" || name = "'${album#*:$medias/}'"')"
eval $(php -r 'echo "_artist=".rawurlencode($argv[1]).";_album_name=".rawurlencode($argv[2]);' -- "$artist" "$album_name")
curl \
--request GET \
--user-agent "$mbz_agent" \
--silent --location \
--url "http://musicbrainz.org/ws/2/release/?fmt=json&query=release:$_album_name%20AND%20artist:$_artist" > $coverart
mbids=($(jq --raw-output --arg artist "${artist^^}" --arg album "${album_name^^}" '
.releases
| .[]
| select(.title | ascii_upcase == $album)
| select(."artist-credit" | .[].name | ascii_upcase == $artist)
| .id // empty' $coverart))
for mbid in ${mbids[@]}; do
album="$mbid:${album#*:}"
if get_from_mbz; then
OK
continue 2
fi
done
if test -z "$spotify_access_token" -a -z "$spotify_access_token_error"; then
get_spotify_access_token
fi
if test -n "$spotify_access_token"; then
if get_from_spotify; then
OK
else
WARNING "pas trouvé (spotify)"
touch "${album#*:}/$no_cover_flag"
fi
else
WARNING "pas trouvé ($(( ${mbz_related:-0} + ${#mbids[@]} )) relations sur musicbrainz)"
touch "${album#*:}/$no_cover_flag"
fi
done
rm -f $coverart
if declare -f post_get_cover > /dev/null; then
post_get_cover
fi