scripts / analyse-votes-AN /
Newer Older
623 lines | 29.036kb
ajout script d'analyse des v...
Sébastien MARQUE authored on 2019-02-17
1
#!/bin/bash
2

            
fix info parfois manquante s...
Sébastien MARQUE authored on 2021-11-21
3
set -e
4

            
complète re-écriture
Sébastien Marque authored on 2019-04-27
5
for tool in sqlite3 getopt md5sum mktemp; do
6
    which $tool > /dev/null 2>&1 || {
7
        echo missing tool $tool
8
        exit 1
9
    }
plus de souplesse dans les p...
Sébastien MARQUE authored on 2019-02-20
10
done
11

            
ajout possibilité de compare...
Sébastien Marque authored on 2019-05-03
12
IFS_=$IFS
13

            
amélioration code
Sébastien Marque authored on 2019-05-30
14
function sqlite_request () {
15
    sqlite3 "$in_ram_database" <<< "$1"
16
}
17

            
complète re-écriture
Sébastien Marque authored on 2019-04-27
18
function create_database () {
fix syntax error
Sébastien Marque authored on 2019-06-10
19
    if test ${#groupes[@]} -eq 0; then
complète re-écriture
Sébastien Marque authored on 2019-04-27
20
        echo "unable to find groupes in $config_file" >&2
21
        exit 1
fixe pb quand groupe cible e...
Sébastien Marque authored on 2019-02-18
22
    fi
complète re-écriture
Sébastien Marque authored on 2019-04-27
23

            
amélioration code
Sébastien Marque authored on 2019-05-30
24
    sqlite_request "create table if not exists votes (id integer primary key, nom text)"
25
    sqlite_request "create table if not exists url (id integer primary key autoincrement, url text)"
26
    sqlite_request "create table if not exists députés (id integer primary key autoincrement, nom text, groupe integer)"
27
    sqlite_request "create table if not exists groupes (id integer primary key autoincrement, nom text, nom_court text)"
28
    sqlite_request "create table if not exists scrutins (num integer primary key, date text not null, intitulé text non null, adoption boolean, url integer)"
29
    sqlite_request "create table if not exists dépouillement (député integer not null, scrutin integer not null, groupe integer not null, vote integer not null)"
fix missing table
Sébastien MARQUE authored on 2021-02-13
30
    sqlite_request "create table if not exists dossiers (id text primary key, titre text, url text)"
complète re-écriture
Sébastien Marque authored on 2019-04-27
31

            
32
    v_id=0
33
    for v in Pour Contre Abstention Non-votant; do
amélioration code
Sébastien Marque authored on 2019-05-30
34
        if test -z $(sqlite_request "select nom from votes where id is $v_id"); then
35
            sqlite_request "insert into votes values ($v_id, '$v')"
complète re-écriture
Sébastien Marque authored on 2019-04-27
36
        else
amélioration code
Sébastien Marque authored on 2019-05-30
37
            test -z $(sqlite_request "select nom from votes where id is $v_id and nom is '$v'") \
38
                && sqlite_request "update votes set nom = '$v' where id is $v_id)"
complète re-écriture
Sébastien Marque authored on 2019-04-27
39
        fi
40
        let v_id++
41
    done
42
    unset v_id v
43

            
ajout script d'analyse des v...
Sébastien MARQUE authored on 2019-02-17
44
    for g in ${!groupes[@]}; do
amélioration code
Sébastien Marque authored on 2019-05-30
45
        test -z $(sqlite_request "select id from groupes where nom is '${groupes[$g]}' and nom_court is '$g'") \
46
            && sqlite_request "insert into groupes (nom, nom_court) values ('${groupes[$g]}', '$g')"
ajout script d'analyse des v...
Sébastien MARQUE authored on 2019-02-17
47
    done
complète re-écriture
Sébastien Marque authored on 2019-04-27
48
    unset g groupes
ajout script d'analyse des v...
Sébastien MARQUE authored on 2019-02-17
49

            
amélioration code
Sébastien Marque authored on 2019-05-30
50
    test -z $(sqlite_request "select id from url where id = 0") \
51
        && sqlite_request "insert into url values (0, '')"
complète re-écriture
Sébastien Marque authored on 2019-04-27
52
}
ajout script d'analyse des v...
Sébastien MARQUE authored on 2019-02-17
53

            
complète re-écriture
Sébastien Marque authored on 2019-04-27
54
function update_database () {
55
    test "$no_db_update" = $true_flag && return
56
    tempfile="/dev/shm/scrutin.$$"
57
    progress=0
fix bug sur premier scrutin
Sébastien Marque authored on 2019-04-27
58
    first_=$first
amélioration code
Sébastien Marque authored on 2019-05-30
59
    first=$(sqlite_request "select count(num) from scrutins")
complète re-écriture
Sébastien Marque authored on 2019-04-27
60
    if test ${first:-0} -lt $last; then
61
        echo "récupération des scrutins n°$((${first:-0}+1)) à n°$last dans "$database" (à conserver autant que possible)" >&2
ajout script d'analyse des v...
Sébastien MARQUE authored on 2019-02-17
62

            
fix missing table
Sébastien MARQUE authored on 2021-02-13
63
        local url_database=/dev/shm/url_database
complète re-écriture
Sébastien Marque authored on 2019-04-27
64
        : > "$url_database"
65
        test $((last % 100)) -ne 0 && last_offset=0
fix dossiers manquants
Sébastien MARQUE authored on 2019-12-09
66
        IFS=$' \t\n'
complète re-écriture
Sébastien Marque authored on 2019-04-27
67
        for offset in $(seq $((last - 100)) -100 ${first:-0} ) $last_offset; do
sélection possible de la man...
Sébastien MARQUE authored on 2021-02-13
68
            wget -qO- "http://www2.assemblee-nationale.fr/scrutins/liste/(offset)/$offset/(legislature)/$mandature/(type)/TOUS/(idDossier)/TOUS" \
complète re-écriture
Sébastien Marque authored on 2019-04-27
69
                | awk '
70
                    /<td class="denom">/ {
71
                        scrutin = gensub(/^.+denom.>([[:digit:]]+).*<.td./,"\\1","1",$0)
72
                    }
73
                    /<td class="desc">.+dossier<.a/ {
74
                        a[scrutin] = gensub(/^.+.<a href="(.+)">dossier<.a>.*$/,"\\1","1",$0)
75
                    }
76
                    END {
77
                        for (i in a)
78
                            print gensub("*","","1",i) "|" a[i]
79
                    }' >> "$url_database"
80
        done
81
        sort -u "$url_database" > "${url_database}.sorted"
82
        mv -f "${url_database}.sorted" "$url_database"
83

            
84
        IFS=$'\n'
85
        begin=$(date +%s)
86
        for scrutin in $(seq $((${first:-0}+1)) $last); do
sélection possible de la man...
Sébastien MARQUE authored on 2021-02-13
87
            wget -qO- "http://www2.assemblee-nationale.fr/scrutins/detail/(legislature)/$mandature/(num)/$scrutin" \
complète re-écriture
Sébastien Marque authored on 2019-04-27
88
                |  sed -r '0,/< *div class="titre-bandeau-bleu +to-print" *>/d; /< *script +type="text\/javascript" *>/,$d' > $tempfile
89

            
90
            unset title date adoption url id_url
91

            
92
            title=$(sed -rn '/<h1 class="">Analyse du scrutin n° '$scrutin'/n; s,^.*<h3 class="president-title">(.+).</h3>,\1,p' $tempfile \
93
                    | sed "s/;//g; s/[ \t][ \t]+/ /g; s/^Scrutin public sur *//; s/^l[ae']s* *//")
fix info parfois manquante s...
Sébastien MARQUE authored on 2021-11-21
94
            eval $(sed -rn '
95
                    s,^.*<h1 class="">Analyse du scrutin n° '$scrutin'<br/>(.+) </h1>,date="\1",p
96
                    s,^.*<p class="annonce"><span class="annoncevote">(.+).</span></p>.*$,adoption="\1",p
97
                    s,^.*<p .*class="repartitionvotes.*Pour l.adoption :.+>([0-9]+)<.*$,pour=\1,p
98
                    s,^.*<p .*class="repartitionvotes.*Contre :.+>([0-9]+)<.*$,contre=\1,p' $tempfile)
99
            test -n "$title" -a -n "$date" || {
complète re-écriture
Sébastien Marque authored on 2019-04-27
100
                echo "erreur dans la récupération du scrutin $scrutin"
101
                exit 1
102
            }
fix info parfois manquante s...
Sébastien MARQUE authored on 2021-11-21
103
            if test -n "$adoption"; then
104
                grep -q 'e a a' <<< "$adoption" && adoption=1 || adoption=0
105
            else
106
                if test $pour -gt $contre; then
107
                    adoption=1
108
                elif test $contre -gt $pour; then
109
                    adoption=0
110
                fi
111
            fi
petite simplification du cod...
Sébastien MARQUE authored on 2019-03-31
112

            
complète re-écriture
Sébastien Marque authored on 2019-04-27
113
            url=$(awk -F'|' "/^$scrutin\|/{print \$2}" "$url_database")
amélioration code
Sébastien Marque authored on 2019-05-30
114
            id_url=$(sqlite_request "select id from url where url is '$url'")
complète re-écriture
Sébastien Marque authored on 2019-04-27
115
            if test -z "$id_url"; then
amélioration code
Sébastien Marque authored on 2019-05-30
116
                sqlite_request "insert into url (url) values ('$url')"
117
                id_url=$(sqlite_request "select id from url where url is '$url'")
complète re-écriture
Sébastien Marque authored on 2019-04-27
118
            fi
écriture directe en feuille ...
Sébastien MARQUE authored on 2019-03-31
119

            
amélioration code
Sébastien Marque authored on 2019-05-30
120
            sqlite_request "insert into scrutins values ($scrutin, '$date', \"${title//\"}\", $adoption, ${id_url:-0})"
fix info parfois manquante s...
Sébastien MARQUE authored on 2021-11-21
121
            unset adoption pour contre
complète re-écriture
Sébastien Marque authored on 2019-04-27
122

            
amélioration code
Sébastien Marque authored on 2019-05-30
123
            for v in $(sqlite_request "select * from votes"); do
124
                for g in $(sqlite_request "select id,nom from groupes"); do
complète re-écriture
Sébastien Marque authored on 2019-04-27
125
                    for d in $(sed -rn '/<p class="nomgroupe">'${g#*|}' <span class="block topmargin">/,/<div class="TTgroupe topmargin-lg">/p' $tempfile \
126
                        | sed -rn '/<p class="typevote">'${v#*|}':/,/<.div>/p' \
127
                        | sed 's,</li>,\n,g' \
128
                        | sed -rn '/<p class="typevote">/d; s,^\s*<li>\s*,,; s,&nbsp;, ,g; s/^\s*//; s/M(me|\.) //; s/ \(.*$//; s,<b>,,; s,</b>,,p'); do
amélioration code
Sébastien Marque authored on 2019-05-30
129
                        d_id=$(sqlite_request "select id from députés where nom is \"$d\" and groupe is ${g%|*}")
complète re-écriture
Sébastien Marque authored on 2019-04-27
130
                        if test -z "$d_id"; then
amélioration code
Sébastien Marque authored on 2019-05-30
131
                            sqlite_request "insert into députés (nom, groupe) values (\"$d\", ${g%|*})"
132
                            d_id=$(sqlite_request "select id from députés where nom is \"$d\" and groupe is ${g%|*}")
complète re-écriture
Sébastien Marque authored on 2019-04-27
133
                        fi
amélioration code
Sébastien Marque authored on 2019-05-30
134
                        sqlite_request "insert into dépouillement values ($d_id, $scrutin, ${g%|*}, ${v%|*})"
complète re-écriture
Sébastien Marque authored on 2019-04-27
135
                    done
136
                done
137
            done
138

            
amélioration du calcul ETA p...
Sébastien MARQUE authored on 2019-05-30
139
            if test $(( ($scrutin - $first) * 100 / ( $last - $first ) )) -ne $progress; then
140
                progress=$(( ($scrutin - $first) * 100 / ( $last - $first ) ))
complète re-écriture
Sébastien Marque authored on 2019-04-27
141
                if test $(($progress % ${update_progress:-1})) -eq 0; then
142
                    now=$(date +%s)
143
                    delta=$(( $now - $begin ))
amélioration du calcul ETA p...
Sébastien MARQUE authored on 2019-05-30
144
#                   scrutin = first+1 à la première itération
145
                    echo $progress%, ETA: $(date +%H:%M:%S -d "$(($delta * ($last - $scrutin) / ($scrutin - $first) )) seconds")
complète re-écriture
Sébastien Marque authored on 2019-04-27
146
                fi
147
            fi
148
        done
149
        rm -f "$url_database" "$tempfile"
150
    fi
fix bug sur premier scrutin
Sébastien Marque authored on 2019-04-27
151
    first=$first_
complète re-écriture
Sébastien Marque authored on 2019-04-27
152
}
153

            
154
function write_comparaison () {
ajoute colonnes loyauté, pan...
Sébastien MARQUE authored on 2019-11-13
155

            
ajout possibilité de compare...
Sébastien Marque authored on 2019-05-03
156
    result="comparaisons ${groupe[0]} avec ${groupe_ref:-GDR}${dossier:+ - ${dossier}}"
complète re-écriture
Sébastien Marque authored on 2019-04-27
157
    content="/dev/shm/$result/content.xml"
ajoute colonnes loyauté, pan...
Sébastien MARQUE authored on 2019-11-13
158
    id_cols="Scrutin Date Titre Adoption Panurgisme${nom:+ Participation Loyauté}"
amélioration code
Sébastien Marque authored on 2019-05-30
159
    typevotes=$(sqlite_request "select nom from votes")
ajout possibilité de compare...
Sébastien Marque authored on 2019-05-03
160
    nb_cols=$(( $(wc -w <<< $id_cols) + $(wc -w <<< $typevotes) * ${#groupe[@]} ))
161
    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')
simplification écriture des ...
Sébastien MARQUE authored on 2019-11-13
162
    function write_cell () {
163
        case $1 in
164
            url)
165
                cell='<table:table-cell office:value-type="string" calcext:value-type="string">'
166
                cell+="<text:p><text:a xlink:href=\"$2\" xlink:type=\"simple\">$3</text:a></text:p>";;
167
            texte)
168
                cell='<table:table-cell office:value-type="string" calcext:value-type="string">'
169
                cell+="<text:p>$2</text:p>"
170
                ;;
171
            nombre)
172
                cell="<table:table-cell office:value-type=\"float\" office:value=\"$2\" calcext:value-type=\"float\">"
173
                cell+="<text:p>$2</text:p>"
174
                ;;
175
            *)
176
                return 1;;
177
        esac
178
        cell+='</table:table-cell>'
179
        echo $cell >> "$content"
180
    }
complète re-écriture
Sébastien Marque authored on 2019-04-27
181

            
182
    echo "génération du fichier $result"
183

            
184
    mkdir -p "/dev/shm/$result/META-INF"
185

            
186
    cat > "/dev/shm/$result/META-INF/manifest.xml" << EOmetainf
écriture directe en feuille ...
Sébastien MARQUE authored on 2019-03-31
187
<?xml version="1.0" encoding="UTF-8"?>
188
<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" manifest:version="1.2">
189
 <manifest:file-entry manifest:full-path="/" manifest:version="1.2" manifest:media-type="application/vnd.oasis.opendocument.spreadsheet"/>
190
 <manifest:file-entry manifest:full-path="content.xml" manifest:media-type="text/xml"/>
191
</manifest:manifest>
192
EOmetainf
193

            
complète re-écriture
Sébastien Marque authored on 2019-04-27
194
    printf 'application/vnd.oasis.opendocument.spreadsheet' > "/dev/shm/$result/mimetype"
écriture directe en feuille ...
Sébastien MARQUE authored on 2019-03-31
195

            
complète re-écriture
Sébastien Marque authored on 2019-04-27
196
    echo '<?xml version="1.0" encoding="UTF-8"?>' > "$content"
écriture directe en feuille ...
Sébastien MARQUE authored on 2019-03-31
197

            
complète re-écriture
Sébastien Marque authored on 2019-04-27
198
    cat >> "$content" << EOcontent
199
    <office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.2">
200
    <office:scripts/>
201
    <office:font-face-decls>
202
    <style:font-face style:name="Liberation Sans" svg:font-family="&apos;Liberation Sans&apos;" style:font-family-generic="swiss" style:font-pitch="variable"/>
203
    <style:font-face style:name="DejaVu Sans" svg:font-family="&apos;DejaVu Sans&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
204
    <style:font-face style:name="FreeSans" svg:font-family="FreeSans" style:font-family-generic="system" style:font-pitch="variable"/>
205
    </office:font-face-decls>
206
    <office:automatic-styles>
207
EOcontent
208

            
ajout possibilité de compare...
Sébastien Marque authored on 2019-05-03
209
    IFS=$'\n'
complète re-écriture
Sébastien Marque authored on 2019-04-27
210
    for i in $(seq $nb_cols); do
211
        cat >> "$content" << EOcontent
212
            <style:style style:name="co$i" style:family="table-column">
213
            <style:table-column-properties fo:break-before="auto" style:column-width="30.00mm"/>
214
            </style:style>
écriture directe en feuille ...
Sébastien MARQUE authored on 2019-03-31
215
EOcontent
complète re-écriture
Sébastien Marque authored on 2019-04-27
216
    done
écriture directe en feuille ...
Sébastien MARQUE authored on 2019-03-31
217

            
218
    cat >> "$content" << EOcontent
complète re-écriture
Sébastien Marque authored on 2019-04-27
219
    <style:style style:name="ro1" style:family="table-row">
220
    <style:table-row-properties style:row-height="4.52mm" fo:break-before="auto" style:use-optimal-row-height="true"/>
221
    </style:style>
222
    <style:style style:name="ta1" style:family="table" style:master-page-name="Default">
223
    <style:table-properties table:display="true" style:writing-mode="lr-tb"/>
224
    </style:style>
225
    <style:style style:name="ce1" style:family="table-cell" style:parent-style-name="Default">
226
    <style:table-cell-properties fo:background-color="#cccccc"/>
227
    </style:style>
228
    </office:automatic-styles>
229
    <office:body>
230
    <office:spreadsheet>
231
    <table:calculation-settings table:automatic-find-labels="false"/>
232
    <table:table table:name="$result" table:style-name="ta1">
233
    <office:forms form:automatic-focus="false" form:apply-design-mode="false"/>
234
    <table:table-column table:style-name="co1" table:number-columns-repeated="$(wc -w <<< $id_cols)" table:default-cell-style-name="Default"/>
écriture directe en feuille ...
Sébastien MARQUE authored on 2019-03-31
235
EOcontent
236

            
complète re-écriture
Sébastien Marque authored on 2019-04-27
237
    for i in $(seq $(wc -w <<< $typevotes)); do
238
        cat >> "$content" << EOcontent
239
        <table:table-column table:style-name="co1" table:default-cell-style-name="ce1"/>
écriture directe en feuille ...
Sébastien MARQUE authored on 2019-03-31
240
EOcontent
ajout possibilité de compare...
Sébastien Marque authored on 2019-05-03
241
        for (( g = 1; g < ${#groupe[@]}; g++ )); do
242
            cat >> "$content" << EOcontent
243
            <table:table-column table:style-name="co1" table:default-cell-style-name="Default"/>
244
EOcontent
245
        done
complète re-écriture
Sébastien Marque authored on 2019-04-27
246
    done
247
    echo '<table:table-row table:style-name="ro1">' >> "$content"
écriture directe en feuille ...
Sébastien MARQUE authored on 2019-03-31
248

            
ajout possibilité de compare...
Sébastien Marque authored on 2019-05-03
249
    IFS=$IFS_
complète re-écriture
Sébastien Marque authored on 2019-04-27
250
    for colonne in $id_cols; do
simplification écriture des ...
Sébastien MARQUE authored on 2019-11-13
251
        write_cell texte $colonne
complète re-écriture
Sébastien Marque authored on 2019-04-27
252
    done
écriture directe en feuille ...
Sébastien MARQUE authored on 2019-03-31
253

            
complète re-écriture
Sébastien Marque authored on 2019-04-27
254
    for typevote in $typevotes; do
ajout possibilité de compare...
Sébastien Marque authored on 2019-05-03
255
        for g in "${groupe[@]}"; do
simplification écriture des ...
Sébastien MARQUE authored on 2019-11-13
256
            write_cell texte "$typevote - $g"
complète re-écriture
Sébastien Marque authored on 2019-04-27
257
        done
258
    done
259

            
260
    echo '</table:table-row>' >> "$content"
261

            
262
    progress=0
263
    begin=$(date +%s)
264
    line=1
améliore progression
Sébastien Marque authored on 2019-05-03
265
    test -z "$seq" && qty=$(( $last - $first ))
ajout possibilité de compare...
Sébastien Marque authored on 2019-05-03
266
    IFS=$'\n'
complète re-écriture
Sébastien Marque authored on 2019-04-27
267
    for scrutin in $(eval ${seq:-seq $first $last}); do
268

            
amélioration code
Sébastien Marque authored on 2019-05-30
269
        data=$(sqlite_request "select date,intitulé,adoption,url.url from scrutins inner join url on scrutins.url = url.id where num is $scrutin")
complète re-écriture
Sébastien Marque authored on 2019-04-27
270
        date=$(cut -d'|' -sf 1 <<< $data)
271
        title=$(cut -d'|' -sf 2 <<< $data)
272
        adoption=$(cut -d'|' -sf 3 <<< $data)
273
        url=$(cut -d'|' -sf 4 <<< $data)
274
        test $adoption -eq 1 && adoption='oui' || adoption='non'
groupe de référence: GDR
Sébastien MARQUE authored on 2019-02-17
275

            
simplification écriture des ...
Sébastien MARQUE authored on 2019-11-13
276
        echo '<table:table-row table:style-name="ro1">' >> "$content"
277

            
complète re-écriture
Sébastien Marque authored on 2019-04-27
278
        if test -n "$url"; then
simplification écriture des ...
Sébastien MARQUE authored on 2019-11-13
279
            write_cell url "$url" $scrutin
complète re-écriture
Sébastien Marque authored on 2019-04-27
280
        else
simplification écriture des ...
Sébastien MARQUE authored on 2019-11-13
281
            write_cell nombre $scrutin
complète re-écriture
Sébastien Marque authored on 2019-04-27
282
        fi
simplification écriture des ...
Sébastien MARQUE authored on 2019-11-13
283
        write_cell texte "$date"
284
        write_cell texte "${title//\'/&apos;}"
285
        write_cell texte "$adoption"
ajoute colonnes loyauté, pan...
Sébastien MARQUE authored on 2019-11-13
286

            
amélioration code
Sébastien MARQUE authored on 2019-11-13
287
        for typevote in $(seq 0 $(( $(wc -w <<< $typevotes) - 1 ))); do
ajoute colonnes loyauté, pan...
Sébastien MARQUE authored on 2019-11-13
288
            vote_cible[$typevote]=$(sqlite_request "select
complète re-écriture
Sébastien Marque authored on 2019-04-27
289
                                        count(député)
290
                                     from
291
                                        dépouillement
292
                                     where
293
                                        scrutin is $scrutin
294
                                     and
295
                                        vote is $typevote
296
                                     and
ajout possibilité de compare...
Sébastien Marque authored on 2019-05-03
297
                                        groupe is ${groupe_id[0]} ${nom:+ and député is ${nom%|*}}")
ajoute colonnes loyauté, pan...
Sébastien MARQUE authored on 2019-11-13
298
        done
299
        if test \( ${vote_cible[0]} -gt ${vote_cible[1]} -a $adoption = oui \) \
300
            -o  \( ${vote_cible[1]} -gt ${vote_cible[0]} -a $adoption = non \); then
301
            panurge=1
302
        else
303
            panurge=0
304
        fi
simplification écriture des ...
Sébastien MARQUE authored on 2019-11-13
305
        write_cell nombre $panurge
ajoute colonnes loyauté, pan...
Sébastien MARQUE authored on 2019-11-13
306

            
307
        if test -n "$nom"; then
308
            for typevote in 0 1; do
309
                votes_g0[$typevote]=$(sqlite_request "select
310
                                            count(député)
311
                                         from
312
                                            dépouillement
313
                                         where
314
                                            scrutin is $scrutin
315
                                         and
316
                                            vote is $typevote
317
                                         and
318
                                            groupe is ${groupe_id[0]}")
319
            done
320
            participation=$(( vote_cible[0] + vote_cible[1] + vote_cible[2] + vote_cible[3] ))
321
            if test $(( (${votes_g0[0]} - ${votes_g0[1]}) * (${vote_cible[0]} - ${vote_cible[1]}) )) -gt 0; then
322
                loyaute=1
323
            else
324
                loyaute=0
325
            fi
simplification écriture des ...
Sébastien MARQUE authored on 2019-11-13
326
            write_cell nombre $participation
327
            write_cell nombre $loyaute
ajoute colonnes loyauté, pan...
Sébastien MARQUE authored on 2019-11-13
328
        fi
329

            
amélioration code
Sébastien MARQUE authored on 2019-11-13
330
        for typevote in $(seq 0 $(( $(wc -w <<< $typevotes) - 1 ))); do
simplification écriture des ...
Sébastien MARQUE authored on 2019-11-13
331
            write_cell nombre ${vote_cible[$typevote]}
ajout possibilité de compare...
Sébastien Marque authored on 2019-05-03
332
            for (( g = 1; g < ${#groupe_id[@]}; g++ )); do
amélioration code
Sébastien Marque authored on 2019-05-30
333
                votes=$(sqlite_request "select
ajout possibilité de compare...
Sébastien Marque authored on 2019-05-03
334
                                            count(député)
335
                                         from
336
                                            dépouillement
337
                                         where
338
                                            scrutin is $scrutin
339
                                         and
340
                                            vote is $typevote
341
                                         and
342
                                            groupe is ${groupe_id[$g]}")
simplification écriture des ...
Sébastien MARQUE authored on 2019-11-13
343
                write_cell nombre $votes
complète re-écriture
Sébastien Marque authored on 2019-04-27
344
            done
ajout possibilité de compare...
Sébastien Marque authored on 2019-05-03
345
        done
complète re-écriture
Sébastien Marque authored on 2019-04-27
346
        echo '</table:table-row>' >> "$content"
347

            
meilleur calcul progression
Sébastien Marque authored on 2019-04-27
348
        if test $(( ($line * 100) / ${qty:-$last} )) -ne $progress; then
349
            progress=$(( ($line * 100) / ${qty:-$last} ))
350
            if test $(( $progress % ${generation_progress:-5} )) -eq 0; then
complète re-écriture
Sébastien Marque authored on 2019-04-27
351
                now=$(date +%s)
352
                delta=$(( $now - $begin ))
meilleur calcul progression
Sébastien Marque authored on 2019-04-27
353
                echo $progress%, ETA: $(date +%H:%M:%S -d "$(( $delta * (${qty:-$last} - $line) / $line )) seconds")
complète re-écriture
Sébastien Marque authored on 2019-04-27
354
            fi
355
        fi
meilleur calcul progression
Sébastien Marque authored on 2019-04-27
356

            
357
        let line++
358

            
ajout script d'analyse des v...
Sébastien MARQUE authored on 2019-02-17
359
    done
complète re-écriture
Sébastien Marque authored on 2019-04-27
360
    echo
361

            
362
    cat >> "$content" << EOcontent
363
    </table:table>
364
    <table:named-expressions/>
365
    <table:database-ranges>
ajout possibilité de compare...
Sébastien Marque authored on 2019-05-03
366
    <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"/>
complète re-écriture
Sébastien Marque authored on 2019-04-27
367
    </table:database-ranges>
368
    </office:spreadsheet>
369
    </office:body>
370
    </office:document-content>
371
EOcontent
372

            
373
    ( cd "/dev/shm/$result" && zip -r ../"$result" * > /dev/null 2>&1 && cd .. && rm -fr "$result" )
374

            
375
    mv -f "/dev/shm/$result.zip" "$result.ods"
376

            
377
    echo "$result.ods"
378
}
379

            
380
function save_database () {
améliore abandon
Sébastien MARQUE authored on 2020-02-23
381
    test -n "$result" -a -d "/dev/shm/$result" && rm -fr "/dev/shm/$result"
améliore le trap
Sébastien Marque authored on 2019-04-27
382
    test -n "$database" -a -n "$in_ram_database" || return
améliore la sortie
Sébastien Marque authored on 2019-06-10
383
    test -r "$in_ram_database" || return
complète re-écriture
Sébastien Marque authored on 2019-04-27
384
    if test -r "$database" && md5sum $in_ram_database | sed "s,$in_ram_database,$database," | md5sum --status -c -; then
385
        rm -f $in_ram_database
386
    elif test -w "$database"; then
387
        mv -f $in_ram_database "$database"
388
    elif ! test -e "$database"; then
389
        mv $in_ram_database "$database"
390
    else
391
        rm -f $in_ram_database
392
    fi
393
}
394

            
factorisation
Sébastien MARQUE authored on 2020-02-08
395
function dernier_scrutin_public () {
sélection possible de la man...
Sébastien MARQUE authored on 2021-02-13
396
    wget -qO- "http://www2.assemblee-nationale.fr/scrutins/liste/(legislature)/$mandature/(type)/TOUS/(idDossier)/TOUS" \
factorisation
Sébastien MARQUE authored on 2020-02-08
397
            | sed -rn 's,^.*<td class="denom">(.+)</td>.*$,\1,p' \
398
            | head -1
399
}
400

            
complète re-écriture
Sébastien Marque authored on 2019-04-27
401
trap save_database EXIT
402

            
403
true_flag=$(mktemp --dry-run XXXXX)
404

            
405
OPTS=$( getopt -l no-db-update,\
406
                  db-update-only,\
407
                  cible:,\
408
                  ref:,\
409
                  député:,\
410
                  premier-scrutin:,\
411
                  dernier-scrutin:,\
412
                  période:,\
413
                  liste-dossiers,\
414
                  liste-députés,\
415
                  dossiers,\
416
                  dossier:,\
417
                  conf:,\
418
                  database:,\
419
                  progrès-génération:\
ajout d'un message d'aide
Sébastien Marque authored on 2019-04-27
420
                  progrès-update:,\
421
                  help \
complète re-écriture
Sébastien Marque authored on 2019-04-27
422
                  -- "$@" )
423

            
424
eval set --$OPTS
425

            
426
while [[ $# -gt 0 ]]; do
427
    case "$1" in
428
        "--no-db-update")
ajout d'un message d'aide
Sébastien Marque authored on 2019-04-27
429
#|ne met pas à jour la base de données
complète re-écriture
Sébastien Marque authored on 2019-04-27
430
            no_db_update=$true_flag;;
431
        "--db-update-only")
ajout d'un message d'aide
Sébastien Marque authored on 2019-04-27
432
#|ne génère pas de fichier de résultat
complète re-écriture
Sébastien Marque authored on 2019-04-27
433
            db_update_only=$true_flag;;
434
        "--cible")
ajout possibilité de compare...
Sébastien Marque authored on 2019-05-03
435
#<nom court du groupe>|génère un comparatif pour ce groupe. Par défaut LREM
436
            groupe[0]="${2^^}"
complète re-écriture
Sébastien Marque authored on 2019-04-27
437
            shift;;
438
        "--ref")
ajout possibilité de compare...
Sébastien Marque authored on 2019-05-03
439
#<nom court du groupe ou des groupes>|compare avec ce ou ces groupes. Si plusieurs groupes, ils sont séparés par une virgule, sans espace. Par défaut GDR
fix typo
Sébastien Marque authored on 2019-04-27
440
            groupe_ref="${2^^}"
complète re-écriture
Sébastien Marque authored on 2019-04-27
441
            shift;;
442
        "--député")
ajout d'un message d'aide
Sébastien Marque authored on 2019-04-27
443
#<nom>|filtre la cible sur un-e député-e sur le groupe cible (par défaut LREM). <nom> est insensible à la casse. Tout ou partie du nom ou du prénom peut être donné, espace compris. Caractère % utilisé comme caractère joker. Si aucune correspondance n'est trouvée avec un-e député-é, sortie en erreur. Si plusieurs député-e-s correspondent la liste est affichée et sortie en erreur.
complète re-écriture
Sébastien Marque authored on 2019-04-27
444
            depute=$true_flag
445
            nom="$2"
446
            shift;;
sélection possible de la man...
Sébastien MARQUE authored on 2021-02-13
447
        "--mandature")
448
           mandature="$2"
449
           ;;
complète re-écriture
Sébastien Marque authored on 2019-04-27
450
        "--premier-scrutin")
ajout d'un message d'aide
Sébastien Marque authored on 2019-04-27
451
#<numéro>|commence la génération du résultat à partir du scrutin <numéro>
complète re-écriture
Sébastien Marque authored on 2019-04-27
452
            no_db_update=$true_flag
453
            first="$2"
454
            shift;;
455
        "--dernier-scrutin")
ajout d'un message d'aide
Sébastien Marque authored on 2019-04-27
456
#<numéro>|termine la génération du résultat au scrutin <numéro>
complète re-écriture
Sébastien Marque authored on 2019-04-27
457
            no_db_update=$true_flag
458
            last="$2"
459
            shift;;
460
        "--période")
ajout d'un message d'aide
Sébastien Marque authored on 2019-04-27
461
#<jj/mm/aaaa:JJ/MM/AAAA>|génère un résultat pour les scrutins allant de jj/mm/aaaa à JJ/MM/AAAA
complète re-écriture
Sébastien Marque authored on 2019-04-27
462
            periode=$true_flag
463
            no_db_update=$true_flag
464
            periode_value="$2"
465
            shift;;
466
        "--liste-députés-du-groupe")
ajout d'un message d'aide
Sébastien Marque authored on 2019-04-27
467
#<nom court du groupe>|liste les député-e-s du groupe <nom court du groupe> sur la mandature
complète re-écriture
Sébastien Marque authored on 2019-04-27
468
            liste_deputes=$true_flag
469
            liste_deputes_value="${2^^}"
470
            shift;;
471
        "--liste-députés")
ajout d'un message d'aide
Sébastien Marque authored on 2019-04-27
472
#|liste tou-te-s les député-e-s de la mandature
complète re-écriture
Sébastien Marque authored on 2019-04-27
473
            liste_deputes=$true_flag;;
474
        "--liste-dossiers")
ajout d'un message d'aide
Sébastien Marque authored on 2019-04-27
475
#|affiche une liste numérotée des dossiers et sort
complète re-écriture
Sébastien Marque authored on 2019-04-27
476
            liste_dossiers=$true_flag;;
477
        "--dossier")
ajout d'un message d'aide
Sébastien Marque authored on 2019-04-27
478
#<numéro>|génère un résultat pour le dossier numéroté <numéro>
complète re-écriture
Sébastien Marque authored on 2019-04-27
479
            dossier=$true_flag
480
            dossier_value="$2"
481
            shift;;
482
        "--dossiers")
ajout d'un message d'aide
Sébastien Marque authored on 2019-04-27
483
#|sélection interactive du dossier
complète re-écriture
Sébastien Marque authored on 2019-04-27
484
            dossier=$true_flag;;
485
        "--conf")
ajout d'un message d'aide
Sébastien Marque authored on 2019-04-27
486
#<fichier>|indique le chemin vers le fichier de configuration. Par défaut "{_}.conf"
complète re-écriture
Sébastien Marque authored on 2019-04-27
487
            test -r "$2" || {
488
                echo "config introuvable $2" >&2
489
                options_error=$true_flag
490
            }
491
            config_file="$2"
492
            shift;;
493
        "--database")
ajout d'un message d'aide
Sébastien Marque authored on 2019-04-27
494
#<fichier>|indique le chemin vers la base de données SQLite3 contenant les informations. Par défaut "{_}.db"
complète re-écriture
Sébastien Marque authored on 2019-04-27
495
            test -r "$2" && file -b "$2" | grep -q '^SQLite 3.x database' || {
496
                echo "erreur sur option database: fichier '$2' introuvable ou pas une base SQLite 3" >&2
497
                options_error=$true_flag
498
            }
499
            database="$2"
500
            shift;;
501
        "--progrès-génération")
ajout d'un message d'aide
Sébastien Marque authored on 2019-04-27
502
#<chiffre>|affiche de la progression de la génération du fichier tous les <chiffre>%. Par défaut 5
complète re-écriture
Sébastien Marque authored on 2019-04-27
503
            generation_progress="$2"
504
            shift;;
505
        "--progrès-update")
ajout d'un message d'aide
Sébastien Marque authored on 2019-04-27
506
#<chiffre>|affiche de la progression de la mise à jour de la base de données tous les <chiffre>%. Par défaut 1
complète re-écriture
Sébastien Marque authored on 2019-04-27
507
            update_progress="$2"
508
            shift;;
ajout d'un message d'aide
Sébastien Marque authored on 2019-04-27
509
        "--help")
510
#|affiche cette aide et quitte
511
            echo "$0 [options]"
512
            echo "génère un classeur ODS pour comparer les scrutins publics de la 15ème mandature à l'Assemblée Nationale"
513
            echo
514
            sed -rn '/^ *"--.+"\)/N; s/^ *"(--.+)"\)\n#(.+)$/\1|\2/p' "$0" \
515
                | awk -F'|' -v marge='  ' -v prog="$0" '{
516
                    printf("%s %s\n" marge "%s\n\n", $1, $2, gensub("\\. ", "\\\n" marge, "g", gensub("\\{_\\}", prog, "g", $3)))
517
                }'
518
            exit;;
complète re-écriture
Sébastien Marque authored on 2019-04-27
519
    esac
520
    shift
ajout script d'analyse des v...
Sébastien MARQUE authored on 2019-02-17
521
done
écriture directe en feuille ...
Sébastien MARQUE authored on 2019-03-31
522

            
complète re-écriture
Sébastien Marque authored on 2019-04-27
523
test "$options_error" = $true_flag && exit 1
ajout script d'analyse des v...
Sébastien MARQUE authored on 2019-02-17
524

            
complète re-écriture
Sébastien Marque authored on 2019-04-27
525
test -z "$database" && database="${0}.db"
utilsation d'une archive com...
Sébastien MARQUE authored on 2019-02-20
526

            
fix syntax error
Sébastien Marque authored on 2019-06-10
527
declare -A groupes
complète re-écriture
Sébastien Marque authored on 2019-04-27
528
if test -n "$config_file"; then
529
    source "$config_file"
530
else
531
    config_file="${0}.conf"
532
    if test -r "$config_file"; then
533
        source "$config_file"
534
    fi
utilsation d'une archive com...
Sébastien MARQUE authored on 2019-02-20
535
fi
536

            
ajout possibilité de compare...
Sébastien Marque authored on 2019-05-03
537
IFS=',' groupe=(${groupe[0]:-LREM} ${groupe_ref:-GDR})
ajout script d'analyse des v...
Sébastien MARQUE authored on 2019-02-17
538

            
complète re-écriture
Sébastien Marque authored on 2019-04-27
539
in_ram_database=$(mktemp --dry-run /dev/shm/XXXXXXXXXXXX)
540
if test -r "$database"; then
541
    cp "$database" "$in_ram_database"
542
else
543
    create_database
544
fi
ajout script d'analyse des v...
Sébastien MARQUE authored on 2019-02-17
545

            
ajout possibilité de compare...
Sébastien Marque authored on 2019-05-03
546
for (( g = 0; g < ${#groupe[@]}; g++ )); do
amélioration code
Sébastien Marque authored on 2019-05-30
547
    groupe_id[$g]=$(sqlite_request "select id from groupes where nom_court is '${groupe[$g]}'")
ajout possibilité de compare...
Sébastien Marque authored on 2019-05-03
548
    if test -z "${groupe_id[$g]}"; then
549
        echo "groupe ${groupe[$g]} inconnu" >&2
complète re-écriture
Sébastien Marque authored on 2019-04-27
550
        exit 1
551
    fi
552
done
ajout script d'analyse des v...
Sébastien MARQUE authored on 2019-02-17
553

            
complète re-écriture
Sébastien Marque authored on 2019-04-27
554
if test "$periode" = $true_flag; then
amélioration code
Sébastien Marque authored on 2019-05-30
555
    first=$(sqlite_request "select num from scrutins where date like '% du ${periode_value%:*}' order by num asc" | head -1)
556
    last=$(sqlite_request "select num from scrutins where date like '% du ${periode_value#*:}' order by num asc" | tail -1)
complète re-écriture
Sébastien Marque authored on 2019-04-27
557
    test -z "$first" && echo "date de début inconnue: ${periode_value#*:}" >&2 && rm -f $in_ram_database && exit 1
558
    test -z "$last" && echo "date de fin inconnue: ${periode_value%:*}" >&2 && rm -f $in_ram_database && exit 1
fix bug sur premier scrutin
Sébastien Marque authored on 2019-04-27
559
elif test "$dossier" != $true_flag; then
factorisation
Sébastien MARQUE authored on 2020-02-08
560
    test -z "$last" && last=$(dernier_scrutin_public)
fix bug sur premier scrutin
Sébastien Marque authored on 2019-04-27
561
    test -z "$first" && first=1
complète re-écriture
Sébastien Marque authored on 2019-04-27
562
fi
affiche nom du fichier des r...
Sébastien MARQUE authored on 2019-03-30
563

            
complète re-écriture
Sébastien Marque authored on 2019-04-27
564
if test "$liste_dossiers" = $true_flag; then
amélioration code
Sébastien Marque authored on 2019-05-30
565
    sqlite_request "select printf('%s - %s', id, url) from url" | sed 's,https*://.*/dossiers/,,; s/_/ /g; s/.asp$//'
complète re-écriture
Sébastien Marque authored on 2019-04-27
566
    exit
567
fi
568

            
569
if test "$db_update_only" = $true_flag; then
570
    unset first last
factorisation
Sébastien MARQUE authored on 2020-02-08
571
    last=$(dernier_scrutin_public)
complète re-écriture
Sébastien Marque authored on 2019-04-27
572
    update_database
573
    exit
574
fi
575

            
576
if test "$liste_deputes" = $true_flag; then
577
    if test -n "$liste_deputes_value"; then
amélioration code
Sébastien Marque authored on 2019-05-30
578
        sqlite_request "select printf('%s - %s', députés.nom, groupes.nom_court) from députés inner join groupes on groupes.id = députés.groupe where groupes.nom_court is '$liste_deputes_value'"
complète re-écriture
Sébastien Marque authored on 2019-04-27
579
    else
amélioration code
Sébastien Marque authored on 2019-05-30
580
        sqlite_request "select printf('%s - %s', députés.nom, groupes.nom_court) from députés inner join groupes on groupes.id = députés.groupe order by groupes.nom_court asc"
complète re-écriture
Sébastien Marque authored on 2019-04-27
581
    fi
582
    exit
583
fi
écriture directe en feuille ...
Sébastien MARQUE authored on 2019-03-31
584

            
complète re-écriture
Sébastien Marque authored on 2019-04-27
585
if test "$depute" = $true_flag; then
586
    if test -n "$nom"; then
amélioration code
Sébastien Marque authored on 2019-05-30
587
        match=$(sqlite_request "select count(députés.id) from députés inner join groupes on groupes.id = députés.groupe where députés.nom like '%$nom%' and groupes.nom_court is '$groupe' collate nocase")
complète re-écriture
Sébastien Marque authored on 2019-04-27
588
        if test $match -ne 1; then
589
            if test $match -eq 0; then
590
                echo "pas de député correspondant dans le groupe $groupe"
591
            else 
592
                echo "plusieurs députés correspondent:"
amélioration code
Sébastien Marque authored on 2019-05-30
593
                sqlite_request "select députés.nom from députés inner join groupes on groupes.id = députés.groupe where députés.nom like '%$nom%' and groupes.nom_court is '$groupe' collate nocase"
complète re-écriture
Sébastien Marque authored on 2019-04-27
594
            fi
595
            exit 1
596
        else
amélioration code
Sébastien Marque authored on 2019-05-30
597
            nom=$(sqlite_request "select députés.id,députés.nom from députés inner join groupes on groupes.id = députés.groupe where députés.nom like '%$nom%' and groupes.nom_court is '$groupe' collate nocase")
ajout possibilité de compare...
Sébastien Marque authored on 2019-05-03
598
            groupe[0]="${nom#*|} (${groupe[0]})"
complète re-écriture
Sébastien Marque authored on 2019-04-27
599
        fi
600
    fi
601
fi
602

            
603
if test "$dossier" = $true_flag; then
factorisation
Sébastien MARQUE authored on 2020-02-08
604
    last=$(dernier_scrutin_public)
complète re-écriture
Sébastien Marque authored on 2019-04-27
605
    if test -z "$dossier_value"; then
606
        IFS=$'\n'
amélioration code
Sébastien Marque authored on 2019-05-30
607
        select dossier in $(sqlite_request "select url from url" | sed 's,^.*/dossiers/,,; s/_/ /g; s/.asp$//'); do
complète re-écriture
Sébastien Marque authored on 2019-04-27
608
            if test -n "$dossier"; then
amélioration code
Sébastien Marque authored on 2019-05-30
609
                seq="sqlite_request \"select num from scrutins inner join url on url.id = scrutins.url where url.url like '%/dossiers/${dossier// /_}%' order by num asc\""
610
                qty=$(sqlite_request "select count(num) from scrutins inner join url on url.id = scrutins.url where url.url like '%/dossiers/${dossier// /_}%' order by num asc")
complète re-écriture
Sébastien Marque authored on 2019-04-27
611
                break
612
            fi
613
        done
614
        IFS=$IFS_
615
    else
amélioration code
Sébastien Marque authored on 2019-05-30
616
        seq="sqlite_request \"select num from scrutins inner join url on url.id = scrutins.url where url.id is $dossier_value order by num asc\""
617
        qty=$(sqlite_request "select count(num) from scrutins inner join url on url.id = scrutins.url where url.id is $dossier_value order by num asc")
618
        dossier=$(sqlite_request "select url from url where id is $dossier_value" | sed 's,^.*/dossiers/,,; s/_/ /g; s/.asp$//')
complète re-écriture
Sébastien Marque authored on 2019-04-27
619
    fi
620
fi
écriture directe en feuille ...
Sébastien MARQUE authored on 2019-03-31
621

            
complète re-écriture
Sébastien Marque authored on 2019-04-27
622
update_database
623
write_comparaison