config / .fgfs / fgaddon /
Sébastien MARQUE many improvement
8c5b3fa 4 years ago
1 contributor
206 lines | 8.233kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207#!/bin/bash

fgaddon_url=https://sourceforge.net/p/flightgear/fgaddon/HEAD/tree/trunk/Aircraft
fgaddon_svn=https://svn.code.sf.net/p/flightgear/fgaddon/trunk/Aircraft
fgaddon_path=$HOME/.fgfs/flightgear-fgaddon/Aircraft

aircrafts=$(mktemp --dry-run /dev/shm/Aircraft-XXXXXXXXX)
aircraft=$(mktemp --dry-run /dev/shm/aircraft-XXXXXXX)
setxml=$(mktemp --dry-run /dev/shm/setxml-XXXXXXXX)
in_ram_database=$(mktemp --dry-run /dev/shm/XXXXXXX)
database=${DB:-$0.db}

attributes=(description long-description author flight-model type)

xmlgetnext () {
   local IFS='>'
   read -d '<' TAG VALUE
   TAG=$(tr '\n' ' ' <<< $TAG | sed 's/  */ /g; s/ *$//')
}

function sqlite_request () {
    sqlite3 "$in_ram_database" <<< "$1"
}

function trap_exit () {
    echo "updating installation status"
    for ac in $(sqlite_request 'select printf("%i:%s/%s", aircrafts.id, aircrafts.name, setxml.file) from aircrafts inner join setxml where aircrafts.id = setxml.variantof and setxml.installed != 0;'); do
        ac_path=${ac#*:}
        if test ! -e $fgaddon_path/$ac_path-set.xml; then
            sqlite_request "update setxml set installed = 0 where file = '${ac_path#*/}' and variantof = ${ac%:*}"
        fi
    done
    for ac in $fgaddon_path/*/*-set.xml; do
        ac=${ac/$fgaddon_path}
        sx=${ac##*/}
        ac=${ac%/*}
        if test -d $fgaddon_path/$ac/.svn; then
            install_type=1
        elif test -d $fgaddon_path/$ac/.git; then
            install_type=2
        else
            install_type=3
        fi
        sqlite_request "update setxml set installed = $install_type
                        where exists (
                            select 1 from aircrafts where name = '${ac/\/}' and setxml.variantof = id
                        )"
    done
    if test -r "$database" && md5sum $in_ram_database | sed "s,$in_ram_database,$database," | md5sum --status -c -; then
        rm -f $in_ram_database
        echo "no changes in $database"
    elif test -w "$database"; then
        sqlite_request "vacuum"
        mv -f $in_ram_database "$database"
        echo "database $database updated"
    elif ! test -e "$database"; then
        mv $in_ram_database "$database"
        echo "database $database created"
    else
        rm -f $in_ram_database
        echo "nothing can be done with $database !"
    fi
    rm -f $aircrafts $aircraft $setxml
}

update_database () {
    let progress++
    echo "[ ${progress}${total:+/$total} ] $ac"

    dbupdate=$(sqlite_request "select revision from aircrafts where name is '$ac'")
    if test -z "$dbupdate"; then
        sqlite_request "insert into aircrafts (name, revision, date, author)
                        values ('$ac', ${revision[$ac]}, ${revdate[$ac]}, '${revauthor[$ac]}')"
    elif test $dbupdate -lt ${revision[$ac]}; then
        sqlite_request "update aircrafts set
                            revision = ${revision[$ac]},
                            author   = '${revauthor[$ac]}',
                            date = ${revdate[$ac]}
                        where name is '$ac'"
    fi
    id=$(sqlite_request "select id from aircrafts where name is '$ac'")

    for sx in ${setxmlmodified[$ac]}; do
        test -n "${_sx[$ac/$sx]}" && continue
        _sx[$ac/$sx]="already done"
        unset description long_description author flight_model in_sim
        echo " -> $sx"
        svn export --quiet --force --revision ${revision[$ac]} $fgaddon_svn/$ac/$sx-set.xml $setxml
        while xmlgetnext; do
            if [[ "$TAG" = @($attributes_case) ]]; then
                test -n "$in_sim" && eval "${TAG//-/_}=\"$VALUE\""
                test -n "$description" \
                  -a -n "$long_description" \
                  -a -n "$author" \
                  -a -n "$flight_model" \
                  -a -n "$type" && break
            elif test "$TAG" = 'sim'; then
                in_sim=1
            elif test "$TAG" = '/sim'; then
                break
            fi
        done < $setxml

        test -z "$description" \
          -a -z "$long_description" \
          -a -z "$author" \
          -a -z "$flight_model" \
          -a -z "$type" && echo "WARNING: no info found, skipping" && continue

        if test -n "$description" -a -z "$flight_model"; then
            grep -qi 'jsbsim' <<< "$description" && flight_model='jsb'
            grep -qi 'yasim' <<< "$description" && flight_model='yasim'
        fi

        if test -n "$long_description"; then
            long_description=$(sed 's/^\s*//g' <<< $long_description | tr '\n' ' ')
        fi

        known=$(sqlite_request "select variantof from setxml where file is '$sx'")
        if test -n "$known"; then
            for attribute in ${attributes[@]}; do
                dbvalue=$(sqlite_request "select $attribute from setxml where file is '$sx'")
                eval "wgvalue=\$$attribute"
                if test "$dbvalue" != "$wgvalue" -a -n "$wgvalue"; then
                    sqlite_request "update setxml set $attribute = '$wgvalue' where file is '$sx'"
                fi
            done
        else
            sqlite_request "insert into setxml values ('$sx', $id, '$description', '$long_description', '$author', '$type', '$flight_model', 0)"
        fi
    done
}

trap trap_exit EXIT

test -e $database && cp $database $in_ram_database

sqlite_request "create table if not exists aircrafts (id integer primary key, name text, revision integer, date integer, author text)"
sqlite_request "create table if not exists setxml (file text, variantof integer, description text, long_description text, author text, type text, flight_model text, installed integer)"

attributes_case=$(printf "%s|" "${attributes[@]}")
attributes_case=${attributes_case:0:-1}
latest_revision=$(sqlite_request "select max(revision) from aircrafts")

echo "downloading FGADDON history from revision ${latest_revision:-0}"
svn log --revision ${latest_revision:-0}:HEAD --xml --verbose $fgaddon_svn > $aircrafts

while xmlgetnext; do
    case "$TAG" in
        'logentry revision='*)
            eval $(echo ${TAG#* })
            unset revdate revauthor ac path_list setxmlmodified
        ;;
        'author')
            revauthor=$VALUE
        ;;
        'date')
            revdate=$(date +%s -d "$VALUE")
        ;;
        'path '*)
            path_list[${#path_list[@]}]="$VALUE"
        ;;
        '/logentry')
            revlog[${#revlog[@]}]=$(
                printf '%s\n' "${path_list[@]}" | awk -F/ -v revision=$revision -v revauthor=$revauthor -v revdate=$revdate -v dq='"' '
                {
                    a[$4]++
                    if ($5 ~ "-set.xml$") b[$4]=b[$4] " " gensub("-set.xml$", "", "1", $5)
                }
                END {
                    for (i in a)
                        printf("<revision[%s]=%i;revauthor[%s]=%s;revdate[%s]=%i;%s>",
                                i, revision,
                                i, revauthor,
                                i, revdate,
                                b[i] != "" ? "setxmlmodified[" i "]=" dq gensub("^ ", "", "g", b[i]) " ${setxmlmodified[" i "]}" dq ";" : "")
                }')
        ;;
        '/log')
            unset revision revauthor revdate setxmlmodified
            declare -A revision revauthor revdate setxmlmodified
            analyse () {
                while xmlgetnext; do
                    test -z "$TAG" -a ${#revision[@]} -eq 0 && continue
                    case $TAG in
                        'BEGIN') continue;;
                        'END'  ) break 2;;
                    esac
                    echo $TAG
                done <<< "<BEGIN>${revlog[@]}<END>"
            }
            eval $(analyse)
            total=${#revision[@]}
            declare -A _sx
            for ac in "${!revision[@]}"; do
                update_database
                if test -d $fgaddon_path/$ac/.svn \
                && test "$(svn info --show-item=url $fgaddon_path/$ac)" != "$fgaddon_svn/$ac" \
                || test -d $fgaddon_path/$ac -a ! -d $fgaddon_path/$ac/.svn; then
                    echo "INFO: local $ac installed out from repo" >&2
                fi
            done
            break
        ;;
    esac
done < $aircrafts