... | ... |
@@ -1,6 +1,7 @@ |
1 | 1 |
#!/bin/bash |
2 | 2 |
|
3 | 3 |
DB=/var/lib/navidrome/navidrome.db |
4 |
+medias=/music |
|
4 | 5 |
no_cover_flag=.no_cover |
5 | 6 |
cover_img=cover |
6 | 7 |
mbz_agent='getCover/0.1 (https://seb.lautre.net/git/seb/scripts)' |
... | ... |
@@ -11,9 +12,14 @@ coverartarchive_api="https://coverartarchive.org/release" |
11 | 12 |
coverart=$(mktemp --dry-run /dev/shm/XXXXXXXX) |
12 | 13 |
sizes=(small 250 500 large 1200) |
13 | 14 |
|
14 |
-ERROR () { echo -e "\e[3;31m ${1:-erreur} \e[0;m"; } |
|
15 |
-OK () { echo -e "\e[3;32m ${1:-OK} \e[0;m"; } |
|
16 |
-WARNING () { echo -e "\e[3;33m ${1:-alerte} \e[0;m"; } |
|
15 |
+OK () { echo -e "\e[3;32m ${1:-OK} \e[0;m"; return 0; } |
|
16 |
+WARNING () { echo -e "\e[3;33m ${1:-alerte} \e[0;m"; return 1; } |
|
17 |
+ERROR () { echo -e "\e[3;31m ${1:-erreur} \e[0;m"; return 1; } |
|
18 |
+ |
|
19 |
+if ! test -d $medias; then |
|
20 |
+ ERROR "$medias n'est pas un répertoire" |
|
21 |
+ exit 1 |
|
22 |
+fi |
|
17 | 23 |
|
18 | 24 |
sql_request () { |
19 | 25 |
sqlite3 $DB <<< "$1" |
... | ... |
@@ -22,7 +28,7 @@ sql_request () { |
22 | 28 |
covered () { |
23 | 29 |
case "${forcing_level:-none}" in |
24 | 30 |
retry) |
25 |
- if compgen -G "${album#*:}/$no_cover_flag" > /dev/null; then |
|
31 |
+ if test -w "${album#*:}/$no_cover_flag"; then |
|
26 | 32 |
rm -f "${album#*:}/$no_cover_flag" 2>/dev/null |
27 | 33 |
return 1 |
28 | 34 |
else |
... | ... |
@@ -30,11 +36,17 @@ covered () { |
30 | 36 |
fi |
31 | 37 |
;; |
32 | 38 |
force) |
39 |
+ rm -f "${album#*:}/$no_cover_flag" 2>/dev/null |
|
33 | 40 |
return 1 |
34 | 41 |
;; |
35 | 42 |
none) |
36 |
- compgen -G "${album#*:}/$cover_img.*" > /dev/null \ |
|
37 |
- || compgen -G "${album#*:}/$no_cover_flag" > /dev/null |
|
43 |
+ if compgen -G "${album#*:}/$cover_img.*" > /dev/null; then |
|
44 |
+ return 0 |
|
45 |
+ elif test -e "${album#*:}/$no_cover_flag"; then |
|
46 |
+ return 0 |
|
47 |
+ else |
|
48 |
+ return 1 |
|
49 |
+ fi |
|
38 | 50 |
;; |
39 | 51 |
esac |
40 | 52 |
} |
... | ... |
@@ -44,7 +56,6 @@ get_image () { |
44 | 56 |
mime_type=$(file -bn --mime-type /dev/shm/$2) |
45 | 57 |
if [[ ${mime_type:-erreur} =~ ^image/ ]]; then |
46 | 58 |
mv -f /dev/shm/$2 ${album#*:}/$cover_img.${2##*.} \ |
47 |
- && OK \ |
|
48 | 59 |
|| ERROR "échec en écriture" |
49 | 60 |
else |
50 | 61 |
WARNING "${album%%:*} type $mime_type" |
... | ... |
@@ -71,86 +82,109 @@ fi |
71 | 82 |
if declare -f pre_get_cover > /dev/null; then |
72 | 83 |
pre_get_cover |
73 | 84 |
fi |
85 |
+ |
|
74 | 86 |
IFS=$'\n' |
75 | 87 |
for arg in $@; do |
76 | 88 |
if [[ $arg =~ ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}:/ ]]; then |
77 |
- albums[${#albums[@]}]=$arg |
|
89 |
+ from_CLI=1 |
|
90 |
+ albums[${#albums[@]}]="${arg%/}" |
|
91 |
+ elif [[ $arg =~ ^/ ]]; then |
|
92 |
+ from_CLI=1 |
|
93 |
+ albums[${#albums[@]}]=":${arg%/}" |
|
78 | 94 |
elif [[ $arg =~ ^(force|retry)$ ]]; then |
79 | 95 |
forcing_level=$arg |
80 | 96 |
else |
81 | 97 |
WARNING "incohérence sur $arg" |
82 | 98 |
fi |
83 | 99 |
done |
100 |
+if test -n "$from_CLI"; then |
|
101 |
+ forcing_level=force |
|
102 |
+fi |
|
103 |
+ |
|
84 | 104 |
if test ${#albums[@]} -eq 0; then |
85 |
- albums=($(sql_request "select mbz_album_id || ':' || path |
|
86 |
- from media_file |
|
87 |
- where mbz_album_id is not '' |
|
88 |
- and path not like '/media/musique/la mule/%' |
|
89 |
- and has_cover_art = FALSE" | sed -r 's|/[^/]+$||' | sort -u)) |
|
105 |
+ albums=($(sql_request 'select printf("%s:'${medias%/}'/%s/%s", mbz_album_id, artist, name) |
|
106 |
+ from album where cover_art_path = "" |
|
107 |
+ and name != "[Unknown Album]"')) |
|
90 | 108 |
fi |
91 | 109 |
|
110 |
+get_from_mbz () { |
|
111 |
+ curl -Ls $coverartarchive_api/${album%%:*} > $coverart |
|
112 |
+ if test $(file -bn --mime-type $coverart) = application/json; then |
|
113 |
+ unset img |
|
114 |
+ for size in ${sizes[@]}; do |
|
115 |
+ img=$(jq -r '.images | .[] | select(.front == true) | .thumbnails | ."'$size'"?' $coverart 2>/dev/null) |
|
116 |
+ test -n "$img" && break |
|
117 |
+ done |
|
118 |
+ if test -n "$img"; then |
|
119 |
+ get_image "$img" "${album%%:*}.${img##*.}" |
|
120 |
+ fi |
|
121 |
+ else |
|
122 |
+ WARNING "${album%%:*} réponse inattendue de musicbrainz" |
|
123 |
+ fi |
|
124 |
+} |
|
125 |
+ |
|
126 |
+get_from_spotify () { |
|
127 |
+ eval "$(sql_request 'select printf("artist=""%s"";album_name=""%s""", artist, name) |
|
128 |
+ from album |
|
129 |
+ where artist || "/" || name = "'${album#*:$medias/}'"')" |
|
130 |
+ if test -n "$album_name" -a -n "$artist"; then |
|
131 |
+ curl --request GET --silent \ |
|
132 |
+ --header "Authorization: Bearer $spotify_access_token" \ |
|
133 |
+ --header 'Content-Type: application/json' \ |
|
134 |
+ --url "https://api.spotify.com/v1/search?type=album&query=album:${album_name// /%20}${artist:+%20artist:${artist// /%20}}" > $coverart |
|
135 |
+ found_albums=$(jq -r '.albums .total // empty' $coverart) |
|
136 |
+ if test ${found_albums:-0} -gt 0; then |
|
137 |
+ img=$(jq --raw-output --arg artist "${artist^^}" --arg album "${album_name^^}" " |
|
138 |
+ .albums .items |
|
139 |
+ | .[] |
|
140 |
+ | select(.name | ascii_upcase == \$album) |
|
141 |
+ | select(.artists | .[].name | ascii_upcase == \$artist) |
|
142 |
+ | .images |
|
143 |
+ | .[] |
|
144 |
+ | select(.height == 300) |
|
145 |
+ | .url // empty" $coverart) |
|
146 |
+ if test -n "$img"; then |
|
147 |
+ get_image "$img" "${img##*/}.jpg" |
|
148 |
+ else |
|
149 |
+ WARNING "pas d'image trouvée sur spotify (artist: $artist; album: $album_name)" |
|
150 |
+ fi |
|
151 |
+ else |
|
152 |
+ WARNING "aucun album trouvé sur spotify" |
|
153 |
+ fi |
|
154 |
+ else |
|
155 |
+ ERROR "album: $album_name; artist: $artist" |
|
156 |
+ fi |
|
157 |
+} |
|
158 |
+ |
|
92 | 159 |
for album in ${albums[@]}; do |
93 | 160 |
if ! test -d "${album#*:}"; then |
94 |
- WARNING "${album#*:}: chemin inconnu" |
|
161 |
+ if test -n "$from_CLI"; then |
|
162 |
+ WARNING "${album#*:}: chemin inconnu" |
|
163 |
+ fi |
|
95 | 164 |
continue |
96 | 165 |
fi |
97 | 166 |
if ! covered; then |
98 | 167 |
echo -n "${album#*:} " |
99 |
- curl -Ls $coverartarchive_api/${album%%:*} > $coverart |
|
100 |
- if test $(file -bn --mime-type $coverart) = application/json; then |
|
101 |
- unset img |
|
102 |
- for size in ${sizes[@]}; do |
|
103 |
- img=$(jq -r '.images | .[] | select(.front == true) | .thumbnails | ."'$size'"?' $coverart 2>/dev/null) |
|
104 |
- test -n "$img" && break |
|
105 |
- done |
|
106 |
- if test -n "$img"; then |
|
107 |
- get_image "$img" "${album%%:*}.${img##*.}" |
|
108 |
- fi |
|
109 |
- elif test -n "$spotify_access_token"; then |
|
110 |
- curl --user-agent "$mbz_agent" --silent \ |
|
111 |
- "https://musicbrainz.org/ws/2/release/${album%%:*}?fmt=json&inc=artists" > $coverart |
|
112 |
- artist=$(jq -r '."artist-credit"? | .[0].name // empty' $coverart) |
|
113 |
- if [[ ${artist:-__erreur__} = @(Various Artists|__erreur__) ]]; then |
|
114 |
- unset artist |
|
115 |
- WARNING "artiste inconnu ou multiples (compilation ?)" |
|
116 |
- continue |
|
117 |
- fi |
|
118 |
- album_name=$(jq -r '.title' $coverart) |
|
119 |
- if test -n "$album_name"; then |
|
120 |
- curl --request GET --silent --show-error --http1.1 \ |
|
121 |
- --header "Authorization: Bearer $spotify_access_token" \ |
|
122 |
- --header 'Content-Type: application/json' \ |
|
123 |
- --url "https://api.spotify.com/v1/search?type=album&query=album:${album_name// /%20}${artist:+%20artist:${artist// /%20}}" > $coverart |
|
124 |
- found_albums=$(jq -r '.albums .total // empty' $coverart) |
|
125 |
- if test ${found_albums:-0} -gt 0; then |
|
126 |
- img=$(jq --raw-output --arg artist "$artist" --arg album "$album_name" " |
|
127 |
- .albums .items |
|
128 |
- | .[] |
|
129 |
- | select(.name == \$album${artist:+ and (.artists | .[].name == \$artist)}) |
|
130 |
- | .images |
|
131 |
- | .[] |
|
132 |
- | select(.height == 300) |
|
133 |
- | .url // empty" $coverart) |
|
134 |
- if test -n "$img"; then |
|
135 |
- get_image "$img" "${img##*/}.jpg" |
|
136 |
- else |
|
137 |
- touch "${album#*:}/$no_cover_flag" |
|
138 |
- WARNING "${album%%:*} aucune image trouvée" |
|
139 |
- fi |
|
140 |
- elif test ${found_albums:-1} -eq 0; then |
|
141 |
- WARNING "album indisponible sur spotify" |
|
168 |
+ if test -n "${album%%:*}"; then |
|
169 |
+ if get_from_mbz; then |
|
170 |
+ OK |
|
171 |
+ elif test -n "$spotify_access_token"; then |
|
172 |
+ if get_from_spotify; then |
|
173 |
+ OK |
|
142 | 174 |
else |
143 |
- WARNING "${found_albums:-NULL} albums trouvés sur spotify" |
|
144 |
- echo $artist |
|
145 |
- echo $album_name |
|
175 |
+ touch "${album#*:}/$no_cover_flag" |
|
146 | 176 |
fi |
147 | 177 |
fi |
148 |
- else |
|
149 |
- touch "${album#*:}/$no_cover_flag" |
|
150 |
- WARNING "${album%%:*} aucune image trouvée" |
|
178 |
+ elif test -n "$spotify_access_token"; then |
|
179 |
+ if get_from_spotify; then |
|
180 |
+ OK |
|
181 |
+ else |
|
182 |
+ touch "${album#*:}/$no_cover_flag" |
|
183 |
+ fi |
|
151 | 184 |
fi |
152 | 185 |
fi |
153 | 186 |
done |
187 |
+ |
|
154 | 188 |
rm -f $coverart |
155 | 189 |
if declare -f post_get_cover > /dev/null; then |
156 | 190 |
post_get_cover |