config / .fgfs / fgaddon /
Sébastien MARQUE small fixes
9f788c7 4 years ago
1 contributor
163 lines | 6.531kb
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#!/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-addons/Aircraft

attribute_regex='s/^.*id="l[0-9]+" class="code_block">.*<span class="nt">&lt;__attribute__&gt;<.span>(.+)<span class="nt">&lt;.__attribute__&gt;<.span>.*$/\1/p'

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)

function get_attribute () {
    eval "unset $1"
    result=$(sed -rn "${attribute_regex//__attribute__/${1//_/-}}" $setxml)
    eval "$1=\$\"$result\""
}

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

function trap_exit () {
    if test -r "$database" && md5sum $in_ram_database | sed "s,$in_ram_database,$database," | md5sum --status -c -; then
        rm -f $in_ram_database
    elif test -w "$database"; then
        mv -f $in_ram_database "$database"
    elif ! test -e "$database"; then
        mv $in_ram_database "$database"
    else
        rm -f $in_ram_database
    fi
    rm -f $aircrafts $aircraft $setxml
}

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

    dbupdate=$(sqlite_request "select date from aircrafts where name is '$ac'")
    if test -z "$dbupdate"; then
        sqlite_request "insert into aircrafts (name, date) values ('$ac', $update)"
    elif test $dbupdate -ne $update; then
        sqlite_request "update aircrafts set date = $update where name is '$ac'"
    fi
    id=$(sqlite_request "select id from aircrafts where name is '$ac'")

    wget -qO- $fgaddon_url/$ac > $aircraft
    for sx in $(sed -rn 's/<a class="icon" href="(.+-set.xml)" title=".+"><i class="fa fa-file-o">.+$/\1/p' $aircraft); do
        echo " -> ${sx/-set.xml}"
        wget -qO- $fgaddon_url/$ac/$sx > $setxml
        for attribute in ${attributes[@]}; do
            get_attribute $attribute
        done

        test -e $fgaddon_path/$ac/$sx
        installed=$?

        if test -n "$description" -a -z "$flight_model"; then
            grep -qi 'jsbsim' <<< "$description" && flight_model='jsb'
            grep -qi 'yasim' <<< "$description" && flight_model='yasim'
        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"; 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', $installed)"
        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, date integer)"
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)"

test -z "$1" && echo "mode RSS"

case ${1:-rss} in
    'full')
        echo "downloading the FGADDON list"
        wget -qO- $fgaddon_url > $aircrafts

        total=$(grep -c '<a class="icon" href=".*class="fa fa-folder".*i>&nbsp;' $aircrafts)

        for ac in $(sed -rn 's/^\s*<a class="icon" href="(.+)" title=.* class="fa fa-folder".+$/\1/p' $aircrafts); do
            update=$(grep -A3 '<a class="icon" href=".*class="fa fa-folder".*i>&nbsp;'$ac'<' $aircrafts | sed -rn '$s/^\s*<span title="(.+)">.*$/\1/p')
            update=$(date +%s -d"$update")
            update_database
        done
    ;;
    'rss')
        xmlgetnext () {                                                         
           local IFS='>'
           read -d '<' TAG VALUE
        }

        get_updates_from_rss () {
            wget -qO- https://sourceforge.net/p/flightgear/fgaddon/feed | while xmlgetnext; do
                case "$TAG" in
                    'item')
                        let entry++
                        unset link pubDate revision title file;;
                    'link')
                        link="$VALUE";;
                    'title')
                        title="$VALUE";;
                    'guid isPermaLink="false"')
                        revision=$(sed -r 's,^.+/([0-9]+)/$,\1,' <<< $VALUE);;
                    'pubDate')
                        pubDate=$(date +%s -d "$VALUE")
                        if test $entry -eq 1 -a $pubDate -eq ${latest_update:-0}; then
                            echo "no new updates" >&2
                            break
                        fi
                    ;;
                    '/item')
                        echo "checking $revision ($(date +"%d %B" -d@$pubDate)): $title" >&2
                        wget -qO- "$link" > $aircrafts
                        for file in $(egrep '/trunk/Aircraft/.*/.*-set.xml$' $aircrafts); do
                            file=${file/\/trunk\/Aircraft\/}
                            echo ${file%/*}
                            echo $pubDate
                        done
                    ;;
                    '/channel')
                        if test ${latest_update:-0} -lt $pubDate; then
                            echo "WARNING: $(( ($pubDate - ${latest_update:-0}) / 86400 )) days between the oldest RSS entry and last DB entry" >&2
                            echo "a $0 full may be useful" >&2
                        fi
                    ;;
                esac
            done
        }
        latest_update=$(sqlite_request "select max(date) from aircrafts")
        ac_list=($(get_updates_from_rss))
        total=$(( ${#ac_list[@]} / 2 ))
        for ((i=0; i < ${#ac_list[@]}; i=i+2)); do
            ac=${ac_list[i]}
            update=${ac_list[i+1]}
            update_database
        done
    ;;
        *)
            echo "usage: [DB=path/to/database] $0 [rss|full]"
            echo
            echo "rss: updates only last repo changes"
            echo "full: updates from all repo"
    ;;
esac