config / .fgfs / fgaddon /
Newer Older
428 lines | 15.572kb
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
1
#!/bin/bash
2

            
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
3
set -e
4

            
5
declare -A data=(
6
        [/sim/description]=text
7
        [/sim/long-description]=text
8
        [/sim/author]=text
9
        [/sim/flight-model]=text
10
        [/sim/type]=text
11
        [/sim/model/path]=text
12
)
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
13
fgaddon_url=https://sourceforge.net/p/flightgear/fgaddon/HEAD/tree/trunk/Aircraft
14
fgaddon_svn=https://svn.code.sf.net/p/flightgear/fgaddon/trunk/Aircraft
many improvement
Sébastien MARQUE authored on 2020-09-08
15
fgaddon_path=$HOME/.fgfs/flightgear-fgaddon/Aircraft
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
16
database=${DB:-$0.db}
17
#locale=fr
18

            
19
test -r "$0.conf" && source $0.conf && echo config red
20

            
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
21

            
22
aircrafts=$(mktemp --dry-run /dev/shm/Aircraft-XXXXXXXXX)
23
aircraft=$(mktemp --dry-run /dev/shm/aircraft-XXXXXXX)
24
setxml=$(mktemp --dry-run /dev/shm/setxml-XXXXXXXX)
25
in_ram_database=$(mktemp --dry-run /dev/shm/XXXXXXX)
26

            
27

            
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
28
function xmlgetnext () {
29
    local IFS='>'
30
    read -d '<' TAG VALUE
31
    # by design, the first TAG/VALUE pair is empty
32
    # to avoid infinite loops at end of file parsing we return an error
33
    # the next time we find an empty TAG
34
    if test -z "$TAG"; then
35
        test ${xmlgetnext_firstentry:-1} -eq 1 && xmlgetnext_firstentry=0 || return 1;
36
    fi
37
    # process $TAG only if necessary
38
    local _TAG=$(printf '%q' $TAG)
39
    if test ${_TAG:0:1} = '$'; then
40
        TAG=$(tr '\n' ' ' <<< $TAG | sed 's/  */ /g; s/ *$//')
41
    fi
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
42
}
43

            
44
function sqlite_request () {
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
45
    if ! sqlite3 "$in_ram_database" <<< "$1"; then
46
        register_state
47
    fi
48
}
49

            
50
function xmlremovecomments () {
51
    sed -ri 's/<(!--|script>)/\n&/;s/(<\/script|--)>/&\n/' $setxml
52
    sed -ri '/<(script>|!--).*(<\/script|--)>/d;/<(script>|!--)/,/(<\/script|--)>/d' $setxml
53
}
54

            
55
function trap_break () {
56
    trap '' INT
57
    echo "stop requested"
58
    register_state
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
59
}
60

            
61
function trap_exit () {
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
62
    trapped_rc=$?
63
    trap '' INT
64
    rm -f $aircrafts $aircraft $setxml
65
    if test ! -e $in_ram_database; then
66
        exit
67
    fi
68
    test $trapped_rc -ne 0 && register_state
many improvements
Sébastien MARQUE authored on 2020-09-02
69
    echo "updating installation status"
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
70
    for ac in $(sqlite_request 'select printf("%i:%s/%s", aircrafts.id, aircrafts.name, setxml.file)
71
                                from aircrafts inner join setxml
72
                                where aircrafts.id = setxml.variantof and setxml.installed != 0;'); do
many improvements
Sébastien MARQUE authored on 2020-09-02
73
        ac_path=${ac#*:}
many improvement
Sébastien MARQUE authored on 2020-09-08
74
        if test ! -e $fgaddon_path/$ac_path-set.xml; then
75
            sqlite_request "update setxml set installed = 0 where file = '${ac_path#*/}' and variantof = ${ac%:*}"
76
        fi
77
    done
78
    for ac in $fgaddon_path/*/*-set.xml; do
79
        ac=${ac/$fgaddon_path}
80
        sx=${ac##*/}
81
        ac=${ac%/*}
82
        if test -d $fgaddon_path/$ac/.svn; then
83
            install_type=1
84
        elif test -d $fgaddon_path/$ac/.git; then
85
            install_type=2
86
        else
87
            install_type=3
88
        fi
89
        sqlite_request "update setxml set installed = $install_type
90
                        where exists (
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
91
                            select 1
92
                            from aircrafts
93
                            where name = '${ac/\/}' and setxml.variantof = id
many improvement
Sébastien MARQUE authored on 2020-09-08
94
                        )"
many improvements
Sébastien MARQUE authored on 2020-09-02
95
    done
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
96
    missing_setxml=$(sqlite_request "select name from aircrafts where id not in (select variantof from setxml)")
97
    if test -n "$missing_setxml"; then
98
        echo "missing setxml config: $missing_setxml"
99
    fi
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
100
    if test -r "$database" && md5sum $in_ram_database | sed "s,$in_ram_database,$database," | md5sum --status -c -; then
101
        rm -f $in_ram_database
many improvements
Sébastien MARQUE authored on 2020-09-02
102
        echo "no changes in $database"
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
103
    elif test -w "$database"; then
complete rewrite (use svn in...
Sébastien MARQUE authored on 2020-09-07
104
        sqlite_request "vacuum"
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
105
        mv -f $in_ram_database "$database"
many improvements
Sébastien MARQUE authored on 2020-09-02
106
        echo "database $database updated"
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
107
    elif ! test -e "$database"; then
108
        mv $in_ram_database "$database"
many improvements
Sébastien MARQUE authored on 2020-09-02
109
        echo "database $database created"
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
110
    else
111
        rm -f $in_ram_database
many improvements
Sébastien MARQUE authored on 2020-09-02
112
        echo "nothing can be done with $database !"
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
113
    fi
114
}
115

            
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
116
function register_state () {
117
set +x
118
    sqlite_request "drop table if exists recover_rev"
119
    sqlite_request "create table recover_rev (
120
                        revkey text,
121
                        revision integer,
122
                        revauthor text,
123
                        revdate integer
124
                    )"
125
    for revkey in ${!revision[@]}; do
126
        sqlite_request "insert into recover_rev values (
127
                            '$revkey',
128
                            ${revision[$revkey]:-0},
129
                            '${revauthor[$revkey]}',
130
                            ${revdate[$revkey]:-0}
131
                        )"
132
    done
133
    sqlite_request "drop table if exists recover_setxmlmodified"
134
    sqlite_request "create table if not exists recover_setxmlmodified (
135
                        sx text
136
                    )"
137
    for sx in ${!setxmlmodified[@]}; do
138
        sqlite_request "insert into recover_setxmlmodified values (
139
                            '$sx'
140
                        )"
141
    done
142
    set +x
143
    exit
144
}
145

            
146
function update_database () {
147
    echo "[ ${#revision[@]} ] ${ac:1}"
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
148

            
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
149
    dbupdate=$(sqlite_request "select revision from aircrafts where name is '${ac:1}'")
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
150
    if test -z "$dbupdate"; then
complete rewrite (use svn in...
Sébastien MARQUE authored on 2020-09-07
151
        sqlite_request "insert into aircrafts (name, revision, date, author)
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
152
                        values ('${ac:1}', ${revision[$ac]}, ${revdate[$ac]}, '${revauthor[$ac]}')"
complete rewrite (use svn in...
Sébastien MARQUE authored on 2020-09-07
153
    elif test $dbupdate -lt ${revision[$ac]}; then
154
        sqlite_request "update aircrafts set
155
                            revision = ${revision[$ac]},
156
                            author   = '${revauthor[$ac]}',
157
                            date = ${revdate[$ac]}
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
158
                        where name is '${ac:1}'"
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
159
    fi
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
160
    id=$(sqlite_request "select id from aircrafts where name is '${ac:1}'")
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
161

            
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
162
    for sx in ${!setxmlmodified[@]}; do
163
        unset include include_rootpath
164
        [[ "$sx" =~ ^"${ac:1}/" ]] || continue
165
        for col in ${!data[@]}; do
166
            data[$col]=
167
        done
168
        sx=${sx#*/}
remove -set.xml from filenam...
Sébastien MARQUE authored on 2020-09-02
169
        echo " -> $sx"
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
170
        if ! svn export --quiet --force $fgaddon_svn/${ac:1}/$sx-set.xml $setxml; then
171
            register_state
172
        fi
173
        xmlremovecomments
174
        unset xmlgetnext_firstentry property
complete rewrite (use svn in...
Sébastien MARQUE authored on 2020-09-07
175
        while xmlgetnext; do
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
176
            case "${TAG:0:1}" in
177
                ''|'?'|'!')
178
                    continue;;
179
                /)
180
                    property=${property%/*};;
181
                *)
182
                    if test "${TAG: -1}" != '/'; then
183
                        property+=/${TAG%% *}
fix syntax mistake
Sébastien MARQUE authored on 2020-09-21
184
                    fi;;
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
185
#                    property+=/${TAG%% *}
186
#                    if test "${TAG: -1}" = '/'; then
187
#                        _TAG=${TAG:0:-1}
188
#                        test "${_TAG#* }" != "${_TAG}" && eval "${_TAG#* }"
189
#                        property=${property%/*}
190
#                    fi;;
191
            esac
192

            
193
            if [[ "$TAG" =~ ^"PropertyList include=" ]]; then
194
                include_rootpath=${include%/*}
195
                test $include = $include_rootpath && unset include_rootpath
196
                eval $(echo ${TAG#* })
197
                [[ "$include" =~ ^Aircraft/Generic/ ]] && unset include include_rootpath && continue
198
                if [[ "$include" =~ ^'../' ]]; then
199
                    if test -n "$include_rootpath"; then
200
                        if [[ "$include_rootpath" =~ '/' ]]; then
201
                            include_rootpath=${include_rootpath%/*}
202
                        else
203
                            unset include_rootpath
204
                        fi
205
                    else
206
                        ac_save=$ac
207
                        unset ac
208
                    fi
209
                    include=${include/\.\.\/}
210
                fi
211
                if ! svn cat $fgaddon_svn/${ac:1}/${include_rootpath:+$include_rootpath/}$include >> $setxml; then
212
                    register_state
213
                fi
214
                xmlremovecomments
215
            fi
216

            
217
            if [[ "$property" = /PropertyList@($data_pattern) ]]; then
218
                eval "data[${property/\/PropertyList}]=\"${VALUE//\"/\\\"}\""
219
                data[${property/\/PropertyList}]=$(tr '\n' ' ' <<< ${data[${property/\/PropertyList}]} | sed -r 's/^\s*//;s/\s+/ /g;s/\s*$//')
many improvement
Sébastien MARQUE authored on 2020-09-08
220
            fi
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
221

            
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
222
            if test -n "$_TAG"; then
223
                # _TAG non-null means xml props ends with /
224
                # need to go back of last property
225
                property=${property/%\/${_TAG%% *}}
226
                unset _TAG
227
            fi
many improvement
Sébastien MARQUE authored on 2020-09-08
228

            
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
229
            # continue parsing (while loop) until everything's found
230
            for col in ${!data[@]}; do
231
                test -z "${data[$col]}" && continue 2
232
            done
233
            break # everything's found
234
        done < $setxml
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
235

            
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
236
        if eval "test -z \"$data_test_null\""; then
237
            echo "WARNING: no info found, skipping"
238
            continue
complete rewrite (use svn in...
Sébastien MARQUE authored on 2020-09-07
239
        fi
240

            
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
241
        known=$(sqlite_request "select variantof from setxml where file is '$sx'")
242
        if test -n "$known"; then
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
243
            for col in ${!data[@]}; do
244
                dbvalue=$(sqlite_request "select '$col'
245
                                          from setxml
246
                                          where file is '$sx' and variantof = $known")
247
                if test "$dbvalue" != "${data[$col]}" -a -n "${data[$col]}"; then
248
                    sqlite_request "update setxml
249
                                    set '$col' = '${data[$col]//\'/\'\'}'
250
                                    where file is '$sx' and variantof = $known"
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
251
                fi
252
            done
253
        else
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
254
            values="'$sx', $id, "
255
            for col in ${!data[@]}; do
256
                values+="'${data[$col]//\'/\'\'}', "
257
            done
258
            values+=0
259
            sqlite_request "insert into setxml values ($values)"
260
        fi
261
        test -n "$ac_save" && ac=$ac_save
262
        unset setxmlmodified[${ac:1}/$sx]
263
    done
264
    unset revision[$ac]
265
}
266

            
267
function apply_revision () {
268
    for ac in "${!revision[@]}"; do
269
        update_database
270
        if test -d $fgaddon_path/${ac:1}/.svn \
271
        && test "$(svn info --show-item=url $fgaddon_path/${ac:1})" != "$fgaddon_svn/${ac:1}" \
272
        || test -d $fgaddon_path/${ac:1} -a ! -d $fgaddon_path/${ac:1}/.svn; then
273
            echo "INFO: local ${ac:1} installed out from repo" >&2
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
274
        fi
275
    done
276
}
277

            
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
278
trap trap_break INT
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
279
trap trap_exit EXIT
280

            
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
281
stty -echoctl
282

            
283
declare -A revision revauthor revdate setxmlmodified files revpath
284
data_pattern=$(printf "%s|" ${!data[@]})
285
data_pattern=${data_pattern:0:-1}
286
data_test_null=$(printf '${data[%s]}' ${!data[@]})
287

            
288
if test -e $database; then
289
    cp $database $in_ram_database
290
    sql_cols=$(sqlite_request "pragma table_info(setxml)" | awk -F'|' '{printf("%s %s ", $2, $3)}')
291
    script_cols="file text variantof integer "
292
    for col in ${!data[@]}; do
293
        script_cols+="$col ${data["$col"]} "
294
    done
295
    script_cols+="installed integer " # last space is important
296
    if test "$sql_cols" != "$script_cols"; then
297
        echo "ALERT: datbase version mismatch !"
298
        exit 1
299
    fi
300
    if sqlite_request '.tables' | grep -q 'recover_' && test -z "$1"; then
301
        echo "recovering from previous saved state"
302
        eval $(sqlite_request "select printf('revision[%s]=%u;revauthor[%s]=%s;revdate[%s]=%u;',
303
                                       revkey, revision,
304
                                       revkey, revauthor,
305
                                       revkey, revdate)
306
                               from recover_rev")
307
        eval $(sqlite_request "select printf('setxmlmodified[%s]=1;', sx)
308
                               from recover_setxmlmodified")
309
        sqlite_request "drop table recover_rev"
310
        sqlite_request "drop table recover_setxmlmodified"
311
        apply_revision
312
        exit
313
    fi
314
fi
315

            
316
sqlite_request "create table if not exists aircrafts (
317
                    id integer primary key,
318
                    name text,
319
                    revision integer,
320
                    date integer,
321
                    author text)"
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
322

            
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
323
sqlite_request "create table if not exists setxml (
324
                    file text,
325
                    variantof integer,
326
                    $(for col in ${!data[@]}; do printf "'%s' %s, " $col ${data[$col]}; done)
327
                    installed integer)"
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
328

            
complete rewrite (use svn in...
Sébastien MARQUE authored on 2020-09-07
329
latest_revision=$(sqlite_request "select max(revision) from aircrafts")
330

            
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
331
# for debugging purpose
332
if test -n "$2"; then
333
    ac=_${1%/*}
334
    revision[$ac]=1
335
    revdate[$ac]=0
336
    revauthor[$ac]=foobar
337
    setxmlmodified[${ac:1}/${1#*/}]=1
338
    set -x
339
    update_database
340
    set +x
341
    exit
342
elif test -n "$1"; then
343
    ac=_${1%/*}
344
    eval $(sqlite_request "select printf('revision[_%s]=%s;revdate[_%s]=%i;revauthor[_%s]=%s;',
345
                                            name, revision,
346
                                            name, date,
347
                                            name, author)
348
                           from aircrafts
349
                           where name = '${ac:1}'")
350
    setxmlmodified[${ac:1}/${1#*/}]=1
351
    if test -z "${revision[$ac]}"; then
352
        echo "aircraft ${ac:1} not found"
353
        rm $in_ram_database
354
        exit
355
    fi
356
    update_database
357
    exit
358
fi
359

            
complete rewrite (use svn in...
Sébastien MARQUE authored on 2020-09-07
360
echo "downloading FGADDON history from revision ${latest_revision:-0}"
361
svn log --revision ${latest_revision:-0}:HEAD --xml --verbose $fgaddon_svn > $aircrafts
362

            
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
363
total=$(grep -c '<logentry' $aircrafts)
364
progress=0
365

            
366
echo parsing history
367

            
complete rewrite (use svn in...
Sébastien MARQUE authored on 2020-09-07
368
while xmlgetnext; do
369
    case "$TAG" in
370
        'logentry revision='*)
371
            eval $(echo ${TAG#* })
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
372
            for action in ${!revpath[@]}; do
373
                unset revpath[$action]
374
            done
complete rewrite (use svn in...
Sébastien MARQUE authored on 2020-09-07
375
        ;;
376
        'author')
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
377
            revauthor=${VALUE//\'/\'\'}
complete rewrite (use svn in...
Sébastien MARQUE authored on 2020-09-07
378
        ;;
379
        'date')
380
            revdate=$(date +%s -d "$VALUE")
381
        ;;
382
        'path '*)
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
383
            TAG=${TAG#* }
384
            TAG=${TAG// /;}
385
            TAG=${TAG//-/_}
386
            eval $(echo ${TAG// /;})
387
            path=(${VALUE//\// })
388
            if test $kind = 'file' -a ${#path[@]} -gt 3; then
389
                revpath[$action]+="$VALUE "
390
            elif test $kind = 'dir' -a ${#path[@]} -eq 3 -a $action = 'D'; then
391
                files[_${path[2]}]=0
392
                unset revision[_${path[2]}] revauthor[_${path[2]}] revdate[_${path[2]}]
393
                for sx in ${!setxmlmodified[@]}; do
394
                    [[ "$sx" =~ "${path[2]}/" ]] && unset setxmlmodified[$sx]
395
                done
396
            fi
complete rewrite (use svn in...
Sébastien MARQUE authored on 2020-09-07
397
        ;;
398
        '/logentry')
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
399
            for item in ${revpath[D]}; do
400
                path=(${item//\// })
401
                [[ "${path[3]}" =~ "-set.xml" ]] && unset setxmlmodified[${path[2]}/${path[3]/-set.xml}]
402
                files[_${path[2]}]=$(( --files[_${path[2]}] ))
403
                if test ${files[_${path[2]}]} -le 0; then
404
                    unset revision[_${path[2]}] revauthor[_${path[2]}] revdate[_${path[2]}]
many improvement
Sébastien MARQUE authored on 2020-09-08
405
                fi
complete rewrite (use svn in...
Sébastien MARQUE authored on 2020-09-07
406
            done
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
407
            for action in A M R; do
408
                for item in ${revpath[$action]}; do
409
                    path=(${item//\// })
410
                    revision[_${path[2]}]=$revision
411
                    revauthor[_${path[2]}]=$revauthor
412
                    revdate[_${path[2]}]=$revdate
413
                    [[ "${path[3]}" =~ "-set.xml" ]] && setxmlmodified[${path[2]}/${path[3]/-set.xml}]=1
414
                    test $action = 'A' && files[_${path[2]}]=$(( ++files[_${path[2]}] ))
415
                done
416
            done
417
            newprogress=$((++logentry * 100 / $total))
418
            if test $(( $newprogress - $progress )) -ge ${progress_granularity:-1}; then
419
                progress=$newprogress
420
                echo "$progress% (${#revision[@]})"
421
            fi
422
        ;;
423
        '/log')
424
            apply_revision
complete rewrite (use svn in...
Sébastien MARQUE authored on 2020-09-07
425
            break
426
        ;;
427
    esac
428
done < $aircrafts