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
coverart=$(mktemp --dry-run /dev/shm/XXXXXXXX)
sizes=(500 large small 250 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 () {
install_image () {
mv -f /dev/shm/$1 ${album#*:}/$cover_img.${1##*.} \
&& OK \
|| ERROR "échec en écriture"
}
if curl -Ls $1 > /dev/shm/$2; then
mime_type=$(file -bn --mime-type /dev/shm/$2)
if [[ ${mime_type:-erreur} =~ ^image/ ]]; then
read -t 30 -p "${album%%:*} check ? "
rc=$?
if [[ "$rc$REPLY" =~ 0[OoYy] ]]; then
display /dev/shm/$2
read -p "on garde ? "
if [[ "$REPLY" =~ [OoYy] ]]; then
install_image $2
else
rm /dev/shm/$2
WARNING "vignette rejetée"
fi
else
install_image $2
fi
else
WARNING "${album%%:*} type $mime_type"
fi
else
ERROR "${album%%:*} échec du téléchargement"
fi
}
get_from_mbz () {
curl -Ls https://coverartarchive.org/release${1:+-group}/${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 "${img:-null}" != null && break
done
if test "${img:-null}" != null; then
get_image "$img" "${album%%:*}.${img##*.}"
fi
else
return 1
fi
}
mbz_api () {
curl \
--request ${3:-GET} \
--user-agent "$mbz_agent" \
--silent \
--location \
--url "http://musicbrainz.org/ws/2/$1/?fmt=json&query=$2"
sleep 2
}
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 =~ / ]]; then
from_CLI=1
albums[${#albums[@]}]=$(sql_request 'select mbz_album_id||":"||path
from media_file
where artist||"/"||album = "'$arg'"' \
| sed -r 's|/[^/]+*$||' \
| uniq \
| tail -1)
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 image_files = ""
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 "${album#*:}"
if test -z "${album%%:*}"; then
mbz_album_id=$(sql_request "select distinct mbz_album_id
from media_file
where path like '${album#*:}/%'")
album=${mbz_album_id}${album}
fi
if test -n "${album%%:*}"; then
mbz_related=1
if get_from_mbz; then
continue
else
mbz_api release reid:${album%%:*} > $coverart
rgid=$(jq --raw-output '.releases | .[] | ."release-group" .id // empty' $coverart)
album="${rgid:-null}:${album#*:}"
if get_from_mbz release-group; then
continue
fi
if test -n "$rgid"; then
mbz_api release-group rgid:$rgid > $coverart
mbz_album_ids=($(jq --raw-output '."release-groups" | .[].releases | .[].id // empty' $coverart))
for reid in ${mbz_album_ids[@]}; do
album=$reid:${album#*:}
if get_from_mbz; then
continue 2
fi
done
fi
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")
mbz_api release "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
continue 2
fi
done
WARNING "pas trouvé ($(( ${mbz_related:-0} + ${#mbids[@]} )) relations sur musicbrainz)"
touch "${album#*:}/$no_cover_flag"
done
rm -f $coverart
if declare -f post_get_cover > /dev/null; then
post_get_cover
fi