Showing 2 changed files with 331 additions and 58 deletions
+105 -58
analyse-votes-AN
... ...
@@ -181,9 +181,9 @@ function write_comparaison () {
181 181
     fi
182 182
     content="/dev/shm/$result/content.xml"
183 183
     id_cols=(Scrutin Date Séance Titre Adoption Dossier)
184
+    declare -A style=(["Pour"]=Good ["Contre"]=Bad ["Abstention"]=Neutral ["oui"]=Good ["non"]=Bad)
184 185
     eval $(sqlite_request 'select printf("typevotes[%i]=%s;", id, nom) from votes')
185
-    nb_cols=$(( ${#id_cols[@]} + ${#typevotes[@]} * ${#groupe[@]} ))
186
-    last_col=$(awk -v n=$nb_cols 'BEGIN{printf("%c%c", n < 27 ? "" : int(n/26) + 64, (n % 26) + (n % 26 == 0 ? 26 : 0) + 64)}' | tr -d '\0')
186
+    nb_cols=$(( ${#id_cols[@]} + ${#groupe[@]} ))
187 187
     colors=($(awk -v n=${#groupe[@]} -v from=${from_color:-2A0636} -v to=${to_color:-D09B8A} '
188 188
         function rgbL (p) {
189 189
             r = rgb_from[1] + p * (rgb_to[1] - rgb_from[1])
... ...
@@ -206,20 +206,30 @@ function write_comparaison () {
206 206
             if (n > 1) rgbL(1)
207 207
         }
208 208
     '))
209
+    function get_colname () {
210
+        awk -v n=$1 '
211
+            BEGIN{
212
+                printf("%c%c", n < 27 ? "" : int(n/26) + 64, (n % 26) + (n % 26 == 0 ? 26 : 0) + 64)
213
+            }' | tr -d '\0'
214
+    }
209 215
     function write_cell () {
216
+        cell='<table:table-cell office:value-type='
210 217
         case $1 in
211 218
             url)
212
-                cell='<table:table-cell office:value-type="string" calcext:value-type="string">'
219
+                cell+='"string" calcext:value-type="string">'
213 220
                 cell+="<text:p><text:a xlink:href=$2 xlink:type=\"simple\">$3</text:a></text:p>"
214 221
                 ;;
215 222
             texte)
216
-                cell='<table:table-cell office:value-type="string" calcext:value-type="string">'
217
-                cell+="<text:p>$2</text:p>"
223
+                cell+='"string" calcext:value-type="string"'${style[${2:- }]:+ table:style-name=\"${style[$2]}\"}'>'
224
+                cell+="<text:p>${2:- }</text:p>"
218 225
                 ;;
219 226
             nombre)
220
-                cell="<table:table-cell office:value-type=\"float\" office:value=\"$2\" calcext:value-type=\"float\">"
227
+                cell+='"float" office:value="'$2'" calcext:value-type="float">'
221 228
                 cell+="<text:p>$2</text:p>"
222 229
                 ;;
230
+            formule)
231
+                cell+='"string" table:formula="of:='"$2"'" calcext:value-type="string"'${3:+ table:style-name=\"${3}\"}'>'
232
+                ;;
223 233
             *)
224 234
                 return 1;;
225 235
         esac
... ...
@@ -238,9 +248,38 @@ function write_comparaison () {
238 248
 <manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" manifest:version="1.2">
239 249
  <manifest:file-entry manifest:full-path="/" manifest:version="1.2" manifest:media-type="application/vnd.oasis.opendocument.spreadsheet"/>
240 250
  <manifest:file-entry manifest:full-path="content.xml" manifest:media-type="text/xml"/>
251
+ <manifest:file-entry manifest:full-path="settings.xml" manifest:media-type="text/xml"/>
241 252
 </manifest:manifest>
242 253
 EOmetainf
243 254
 
255
+    cat > "/dev/shm/$result/settings.xml" << EOsettings
256
+<?xml version="1.0" encoding="UTF-8"?>
257
+<office:document-settings xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ooo="http://openoffice.org/2004/office" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" office:version="1.3">
258
+  <office:settings>
259
+    <config:config-item-set config:name="ooo:view-settings">
260
+      <config:config-item-map-indexed config:name="Views">
261
+        <config:config-item-map-entry>
262
+          <config:config-item config:name="ViewId" config:type="string">view1</config:config-item>
263
+          <config:config-item-map-named config:name="Tables">
264
+            <config:config-item-map-entry config:name="$result">
265
+              <config:config-item config:name="HorizontalSplitMode" config:type="short">2</config:config-item>
266
+              <config:config-item config:name="VerticalSplitMode" config:type="short">2</config:config-item>
267
+              <config:config-item config:name="HorizontalSplitPosition" config:type="int">${#id_cols[@]}</config:config-item>
268
+              <config:config-item config:name="VerticalSplitPosition" config:type="int">1</config:config-item>
269
+              <config:config-item config:name="ActiveSplitRange" config:type="short">1</config:config-item>
270
+              <config:config-item config:name="PositionLeft" config:type="int">0</config:config-item>
271
+              <config:config-item config:name="PositionRight" config:type="int">${#id_cols[@]}</config:config-item>
272
+              <config:config-item config:name="PositionTop" config:type="int">0</config:config-item>
273
+              <config:config-item config:name="PositionBottom" config:type="int">1</config:config-item>
274
+            </config:config-item-map-entry>
275
+          </config:config-item-map-named>
276
+        </config:config-item-map-entry>
277
+      </config:config-item-map-indexed>
278
+    </config:config-item-set>
279
+  </office:settings>
280
+</office:document-settings>
281
+EOsettings
282
+
244 283
     printf 'application/vnd.oasis.opendocument.spreadsheet' > "/dev/shm/$result/mimetype"
245 284
 
246 285
     echo '<?xml version="1.0" encoding="UTF-8"?>' > "$content"
... ...
@@ -272,11 +311,20 @@ EOcontent
272 311
     <style:style style:name="ta1" style:family="table" style:master-page-name="Default">
273 312
     <style:table-properties table:display="true" style:writing-mode="lr-tb"/>
274 313
     </style:style>
314
+    <style:style style:name="T1" style:family="text">
315
+    <style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold" fo:color="#5eb91e"/>
316
+    </style:style>
317
+    <style:style style:name="T2" style:family="text">
318
+    <style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold" fo:color="#c9211e"/>
319
+    </style:style>
320
+    <style:style style:name="T3" style:family="text">
321
+    <style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold" fo:color="#e8a202"/>
322
+    </style:style>
275 323
 EOcontent
276 324
 
277 325
     for i in $(seq ${#groupe[@]}); do
278 326
         cat >> "$content" << EOcontent
279
-        <style:style style:name="ce$i" style:family="table-cell" style:parent-style-name="Default">
327
+        <style:style style:name="groupe$i" style:family="table-cell" style:parent-style-name="Default">
280 328
         <style:table-cell-properties fo:wrap-option="wrap" style:vertical-align="middle" fo:background-color="#${colors[$i]%:*}"/>
281 329
         <style:text-properties fo:hyphenate="false" fo:color="#${colors[$i]}"/>
282 330
         </style:style>
... ...
@@ -293,12 +341,10 @@ EOcontent
293 341
     <table:table-column table:style-name="co1" table:number-columns-repeated="${#id_cols[@]}" table:default-cell-style-name="Default"/>
294 342
 EOcontent
295 343
 
296
-    for i in $(seq ${#typevotes[@]}); do
297
-        for g in $(seq ${#groupe[@]}); do
298
-            cat >> "$content" << EOcontent
299
-            <table:table-column table:style-name="co1" table:default-cell-style-name="ce$g"/>
344
+    for g in $(seq ${#groupe[@]}); do
345
+        cat >> "$content" << EOcontent
346
+        <table:table-column table:style-name="co1" table:default-cell-style-name="ce$g"/>
300 347
 EOcontent
301
-        done
302 348
     done
303 349
     echo '<table:table-row table:style-name="ro1">' >> "$content"
304 350
 
... ...
@@ -307,10 +353,9 @@ EOcontent
307 353
         write_cell texte $colonne
308 354
     done
309 355
 
310
-    for typevote in ${typevotes[@]}; do
311
-        for g in "${groupe[@]}"; do
312
-            write_cell texte "$typevote - $g"
313
-        done
356
+    for (( g=0; g<${#groupe[@]}; g++ )); do
357
+        colname=$(get_colname $(( ${#id_cols[@]} + $g + 1)) )
358
+        write_cell formule "COM.MICROSOFT.CONCAT(&quot;${groupe[$g]} (&quot;; $(($last-$first+1))-COUNTIF([.${colname}2:.${colname}$(($last-$first+2))];&quot; &quot;); &quot;)&quot;)" groupe$(($g+1))
314 359
     done
315 360
 
316 361
     echo '</table:table-row>' >> "$content"
... ...
@@ -342,37 +387,38 @@ EOcontent
342 387
         write_cell url   "${dossier_url/#null/\"\"}" "${dossier_texte/#null}"
343 388
 
344 389
         unset votes
345
-        for typevote in $(seq ${#typevotes[@]}); do
346
-            for (( g = 0; g < ${#groupe[@]}; g++ )); do
347
-                votes[${#votes[@]}]=$(sqlite_request "select
348
-                                            count(député)
349
-                                         from
350
-                                            dépouillements
351
-                                         inner join
352
-                                            députés, groupes
353
-                                         on
354
-                                            députés.groupe = groupes.id and dépouillements.député = députés.id
355
-                                         where
356
-                                            scrutin is $scrutin
357
-                                         and
358
-                                            vote is $typevote
359
-                                         and
360
-                                            ${id_groupe[$g]%:*}.nom = '${groupe[$g]//\'/\'\'}'")
361
-            done
362
-        done
363
-        for ((j = 0; j < ${#groupe[@]}; j++)); do
364
-            presence=1 # `let presence+=0` sort en erreur si variable est unset ou égale à 0
365
-            for ((i = $j; i < ${#votes[@]}; i += ${#groupe[@]})); do
366
-                let presence+=${votes[$i]}
367
-            done
368
-            if test $presence -eq 1; then
369
-                for ((i = $j; i < ${#votes[@]}; i += ${#groupe[@]})); do
370
-                    votes[$i]=-1
371
-                done
372
-            fi
390
+        for (( g = 0; g < ${#groupe[@]}; g++ )); do
391
+            case ${id_groupe[$g]%:*} in
392
+                groupes)
393
+                    unset _vote
394
+                    eval $(sqlite_request "select '_vote[' || vote || ']=' || count(vote) from dépouillements
395
+                                           where scrutin = $scrutin and député in (
396
+                                               select id from députés
397
+                                               where groupe in (${id_groupe[$g]#*:})
398
+                                           )
399
+                                           group by vote")
400
+                    if test ${#_vote[@]} -gt 0; then
401
+                        unset _votes
402
+                        for i in {1..3}; do
403
+                            _votes+="<text:span text:style-name=\"T$i\">${_vote[$i]:-0}</text:span> / "
404
+                        done
405
+                        _votes+="${_vote[4]:-0}"
406
+                        votes[${#votes[@]}]=$_votes
407
+                    else
408
+                        votes[${#votes[@]}]=" "
409
+                    fi
410
+                ;;
411
+                députés)
412
+                    votes[${#votes[@]}]=$(sqlite_request "select nom from votes
413
+                                                          where id in (
414
+                                                              select vote from dépouillements
415
+                                                              where scrutin = $scrutin and député in (${id_groupe[$g]#*:})
416
+                                                          )")
417
+                ;;
418
+            esac
373 419
         done
374 420
         for ((i = 0; i < ${#votes[@]}; i ++)); do
375
-            write_cell nombre ${votes[$i]}
421
+            write_cell texte ${votes[$i]}
376 422
         done
377 423
         echo '</table:table-row>' >> "$content"
378 424
 
... ...
@@ -393,7 +439,7 @@ EOcontent
393 439
     </table:table>
394 440
     <table:named-expressions/>
395 441
     <table:database-ranges>
396
-    <table:database-range table:name="__Anonymous_Sheet_DB__0" table:target-range-address="&apos;$result&apos;.D1:&apos;$result&apos;.$last_col$line" table:display-filter-buttons="true"/>
442
+    <table:database-range table:name="__Anonymous_Sheet_DB__0" table:target-range-address="&apos;$result&apos;.D1:&apos;$result&apos;.$(get_colname $nb_cols)$line" table:display-filter-buttons="true"/>
397 443
     </table:database-ranges>
398 444
     </office:spreadsheet>
399 445
     </office:body>
... ...
@@ -468,18 +514,9 @@ trap save_database EXIT
468 514
 
469 515
 test -z "$database" && database="${0}.db"
470 516
 
517
+echo "$0 $@" > $token_file
471 518
 declare -A acronymes
472
-if test -n "$config_file"; then
473
-    source "$config_file"
474
-else
475
-    config_file="${0}.conf"
476
-    if test -r "$config_file"; then
477
-        source "$config_file"
478
-    fi
479
-fi
480
-
481 519
 true_flag=$(mktemp --dry-run XXXXX)
482
-echo "$0 $@" > $token_file
483 520
 
484 521
 while [[ $# -gt 0 ]]; do
485 522
     case "$1" in
... ...
@@ -610,6 +647,7 @@ while [[ $# -gt 0 ]]; do
610 647
             update_progress="$2"
611 648
             shift;;
612 649
         "--mail")
650
+#<adresse mail>|envoie le fichier généré à l'adresse mail indiquée
613 651
             envoi_par_mail=$true_flag
614 652
             destinataire="$2"
615 653
             no_db_update=$true_flag
... ...
@@ -633,6 +671,15 @@ done
633 671
 
634 672
 test "$options_error" = $true_flag && exit 1
635 673
 
674
+if test -n "$config_file"; then
675
+    source "$config_file"
676
+else
677
+    config_file="${0}.conf"
678
+    if test -r "$config_file"; then
679
+        source "$config_file"
680
+    fi
681
+fi
682
+
636 683
 while true; do
637 684
     if ls -1rt /dev/shm/*."${0##*/}" | head -1 | grep -q "^$token_file$"; then
638 685
         # c'est notre tour
... ...
@@ -682,8 +729,8 @@ if test "$periode" = $true_flag; then
682 729
     if test "$envoi_par_mail" = $true_flag; then
683 730
         texte_periode="du $(get_date ${periode_value%:*} first) (scrutin n°$first) au $(get_date ${periode_value#*:} last) (scrutin n°$last)"
684 731
     fi
685
-elif test "$dossier" != $true_flag; then
686
-    test -z "$last" && last=$(dernier_scrutin_public)
732
+elif test "$dossier" != $true_flag -a "$no_db_update" = $true_flag; then
733
+    test -z "$last" && last=$(sqlite_request "select max(num) from scrutins")
687 734
     test -z "$first" && first=1
688 735
 fi
689 736
 
+226
get_cover
... ...
@@ -0,0 +1,226 @@
1
+#!/bin/bash
2
+
3
+DB=/var/lib/navidrome/navidrome.db
4
+medias=/music
5
+no_cover_flag=.no_cover
6
+cover_img=cover
7
+mbz_agent='getCover/0.1 (https://seb.lautre.net/git/seb/scripts)'
8
+
9
+test -e $0.conf && source $0.conf
10
+
11
+coverartarchive_api="https://coverartarchive.org/release"
12
+coverart=$(mktemp --dry-run /dev/shm/XXXXXXXX)
13
+sizes=(small 250 500 large 1200)
14
+
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
+sql_request () {
20
+    sqlite3 $DB <<< "$1"
21
+}
22
+
23
+covered () {
24
+    case "${forcing_level:-none}" in
25
+        retry)
26
+            if test -w "${album#*:}/$no_cover_flag"; then
27
+                rm -f "${album#*:}/$no_cover_flag" 2>/dev/null
28
+                return 1
29
+            else
30
+                return 0
31
+            fi
32
+            ;;
33
+        force)
34
+            rm -f "${album#*:}/$no_cover_flag" 2>/dev/null
35
+            return 1
36
+            ;;
37
+        none)
38
+            if compgen -G "${album#*:}/$cover_img.*" > /dev/null; then
39
+                return 0
40
+            elif test -e "${album#*:}/$no_cover_flag"; then
41
+                return 0
42
+            else
43
+                return 1
44
+            fi
45
+            ;;
46
+    esac
47
+}
48
+
49
+get_image () {
50
+    if curl -Ls $1 > /dev/shm/$2; then
51
+        mime_type=$(file -bn --mime-type /dev/shm/$2)
52
+        if [[ ${mime_type:-erreur} =~ ^image/ ]]; then
53
+            mv -f /dev/shm/$2 ${album#*:}/$cover_img.${2##*.} \
54
+            || ERROR "échec en écriture"
55
+        else
56
+            WARNING "${album%%:*} type $mime_type"
57
+        fi
58
+    else
59
+        ERROR "${album%%:*} échec du téléchargement"
60
+    fi
61
+}
62
+
63
+get_spotify_access_token () {
64
+    if test -n "$spotifyID" -a -n "$spotifySecret"; then
65
+        spotify_access_token=$(curl --silent \
66
+            --request POST \
67
+            --url https://accounts.spotify.com/api/token \
68
+            --header 'Content-Type: application/x-www-form-urlencoded' \
69
+            --header "Authorization: Basic $(base64 -w0 <<< $spotifyID:$spotifySecret | sed 's/K$/=/')" \
70
+            -d 'grant_type=client_credentials' | jq -r '.access_token // empty')
71
+        if test -z "$spotify_access_token"; then
72
+            ERROR "problème d'identifant Spotify"
73
+            spotify_access_token_error=1
74
+            echo ID: $spotifyID
75
+        fi
76
+    fi
77
+}
78
+
79
+get_from_mbz () {
80
+    curl -Ls $coverartarchive_api/${album%%:*} > $coverart
81
+    if test $(file -bn --mime-type $coverart) = application/json; then
82
+        unset img
83
+        for size in ${sizes[@]}; do
84
+            img=$(jq -r '.images | .[] | select(.front == true) | .thumbnails | ."'$size'"?' $coverart 2>/dev/null)
85
+            test -n "$img" && break
86
+        done
87
+        if test -n "$img"; then
88
+            get_image "$img" "${album%%:*}.${img##*.}"
89
+        fi
90
+    else
91
+        return 1
92
+    fi
93
+}
94
+
95
+get_from_spotify () {
96
+    if test -n "$album_name" -a -n "$artist"; then
97
+        curl --request GET --silent \
98
+            --header "Authorization: Bearer $spotify_access_token" \
99
+            --header 'Content-Type: application/json' \
100
+            --data 'type=album' \
101
+            --data "query==album:${_album_name}%20artist:${_artist}" \
102
+            --url "https://api.spotify.com/v1/search" > $coverart
103
+        found_albums=$(jq -r '.albums .total // empty' $coverart)
104
+        if test ${found_albums:-0} -gt 0; then
105
+            img=$(jq --raw-output --arg artist "${artist^^}" --arg album "${album_name^^}" "
106
+                    .albums .items
107
+                    | .[]
108
+                    | select(.name | ascii_upcase == \$album)
109
+                    | select(.artists | .[].name | ascii_upcase == \$artist)
110
+                    | .images
111
+                    | .[]
112
+                    | select(.height == 300)
113
+                    | .url // empty" $coverart)
114
+            if test -n "$img"; then
115
+                get_image "$img" "${img##*/}.jpg"
116
+            else
117
+                WARNING "pas d'image trouvée sur spotify (artist: $artist; album: $album_name)"
118
+            fi
119
+        else
120
+            WARNING "aucun album trouvé sur spotify"
121
+        fi
122
+    else
123
+        ERROR "album: $album_name; artist: $artist"
124
+    fi
125
+}
126
+
127
+if ! test -d $medias; then
128
+    ERROR "$medias n'est pas un répertoire"
129
+    exit 1
130
+fi
131
+
132
+if declare -f pre_get_cover > /dev/null; then
133
+    pre_get_cover
134
+fi
135
+
136
+IFS=$'\n'
137
+for arg in $@; do
138
+    if [[ $arg =~ ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}:/ ]]; then
139
+        from_CLI=1
140
+        albums[${#albums[@]}]="${arg%/}"
141
+    elif [[ $arg =~ ^/ ]]; then
142
+        from_CLI=1
143
+        albums[${#albums[@]}]=":${arg%/}"
144
+    elif [[ $arg =~ ^(force|retry)$ ]]; then
145
+        forcing_level=$arg
146
+    else
147
+        WARNING "incohérence sur $arg"
148
+    fi
149
+done
150
+if test -n "$from_CLI"; then
151
+    forcing_level=force
152
+fi
153
+
154
+if test ${#albums[@]} -eq 0; then
155
+    albums=($(sql_request 'select printf("%s:'${medias%/}'/%s/%s", mbz_album_id, artist, name)
156
+             from album where cover_art_path = ""
157
+             and name != "[Unknown Album]"'))
158
+fi
159
+
160
+for album in ${albums[@]}; do
161
+    mbz_related=0
162
+    if ! test -d "${album#*:}"; then
163
+        if test -n "$from_CLI"; then
164
+            WARNING "${album#*:}: chemin inconnu"
165
+        fi
166
+        continue
167
+    fi
168
+    if covered; then
169
+        continue
170
+    fi
171
+    echo -n "${album#*:} "
172
+    if test -n "${album%%:*}"; then
173
+        mbz_related=1
174
+        if get_from_mbz; then
175
+            OK
176
+            continue
177
+        fi
178
+    fi
179
+
180
+    eval "$(sql_request 'select printf("artist=""%s"";album_name=""%s""", artist, name)
181
+                        from album
182
+                        where artist || "/" || name = "'${album#*:$medias/}'"')"
183
+    eval $(php -r 'echo "_artist=".rawurlencode($argv[1]).";_album_name=".rawurlencode($argv[2]);' -- "$artist" "$album_name")
184
+
185
+    curl \
186
+        --request GET \
187
+        --user-agent "$mbz_agent" \
188
+        --silent --location \
189
+        --url "http://musicbrainz.org/ws/2/release/?fmt=json&query=release:$_album_name%20AND%20artist:$_artist" > $coverart
190
+
191
+    mbids=($(jq --raw-output --arg artist "${artist^^}" --arg album "${album_name^^}" '
192
+            .releases
193
+            | .[]
194
+            | select(.title | ascii_upcase == $album)
195
+            | select(."artist-credit" | .[].name | ascii_upcase == $artist)
196
+            | .id // empty' $coverart))
197
+
198
+    for mbid in ${mbids[@]}; do
199
+        album="$mbid:${album#*:}"
200
+        if get_from_mbz; then
201
+            OK
202
+            continue 2
203
+        fi
204
+    done
205
+
206
+    if test -z "$spotify_access_token" -a -z "$spotify_access_token_error"; then
207
+        get_spotify_access_token
208
+    fi
209
+
210
+    if test -n "$spotify_access_token"; then
211
+        if get_from_spotify; then
212
+            OK
213
+        else
214
+            WARNING "pas trouvé (spotify)"
215
+            touch "${album#*:}/$no_cover_flag"
216
+        fi
217
+    else
218
+        WARNING "pas trouvé ($(( ${mbz_related:-0} + ${#mbids[@]} )) relations sur musicbrainz)"
219
+        touch "${album#*:}/$no_cover_flag"
220
+    fi
221
+done
222
+
223
+rm -f $coverart 
224
+if declare -f post_get_cover > /dev/null; then
225
+    post_get_cover
226
+fi