config / .fgfs / fgaddon /
Newer Older
427 lines | 15.49kb
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_svn=https://svn.code.sf.net/p/flightgear/fgaddon/trunk/Aircraft
many improvement
Sébastien MARQUE authored on 2020-09-08
14
fgaddon_path=$HOME/.fgfs/flightgear-fgaddon/Aircraft
ré-écriture complète
Sébastien MARQUE authored on 2020-09-20
15
database=${DB:-$0.db}
16
#locale=fr
17

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

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

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

            
26

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

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

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

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

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

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

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

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

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

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

            
216
            if [[ "$property" = /PropertyList@($data_pattern) ]]; then
217
                eval "data[${property/\/PropertyList}]=\"${VALUE//\"/\\\"}\""
218
                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
219
            fi
ajout de gestion de bdd pour...
Sébastien MARQUE authored on 2020-08-24
220

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            
365
echo parsing history
366

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