1 contributor
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-addons/Aircraft
attribute_regex='s/^.*id="l[0-9]+" class="code_block">.*<span class="nt"><__attribute__><.span>(.+)<span class="nt"><.__attribute__><.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 () {
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;'); do
ac_path=${ac#*:}
test ! -e $fgaddon_path/$ac_path
installed=$?
sqlite_request "update setxml set installed = $installed where file = '${ac_path#*/}' and variantof = ${ac%:*}"
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
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, $revdate, '$revauthor')"
elif test $dbupdate -lt $revision; then
sqlite_request "update aircrafts set revision = $revision, author = '$revauthor' 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
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
test ! -e $fgaddon_path/$ac/$sx
installed=$?
sqlite_request "insert into setxml values ('$sx', $id, '$description', '$long_description', '$author', '$type', '$flight_model', $installed)"
fi
done
}
xmlgetnext () {
local IFS='>'
read -d '<' TAG VALUE
}
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)"
test -z "$1" && echo "mode RSS"
case ${1:-rss} in
'full')
echo "downloading the FGADDON list"
wget -qO- $fgaddon_url | sed -n '/<table>/,/<\/table>/p' > $aircrafts
total=$(grep -c '<a class="icon" href=".*class="fa fa-folder".*i> ' $aircrafts)
while xmlgetnext; do
case "$TAG" in
'tr')
unset ac revision revauthor
;;
'a class="icon" href='*)
eval $(echo "${TAG#* }")
ac=$href
;;
'span title='*)
eval $(echo "${TAG#* }")
revdate=$(date +%s -d "$title")
;;
'a href="/p/flightgear/fgaddon/'*)
eval $(echo "${TAG#* }")
revision=$(tr -cd '[:digit:]' <<< $href)
;;
'span class="icon emboss x16" style="text-align:center;" title="User"'*)
user=1
;;
'/span')
test -n "$user" && revauthor=$(tr -cd '[:alnum:]' <<< $VALUE) && unset user
;;
'/tr')
test -n "$revision" -a -n "$revauthor" -a -n "$ac" -a -n "$revdate" && update_database
;;
esac
done < $aircrafts
;;
'rss')
get_updates_from_rss () {
while xmlgetnext; do
case "$TAG" in
'item')
let entry++
unset link revdate revauthor revision title;;
'link')
link="$VALUE";;
'title')
title="$VALUE";;
'dc:creator'*)
revauthor="$VALUE";;
'guid isPermaLink="false"')
revision=$(sed -r 's,^.+/([0-9]+)/$,\1,' <<< $VALUE)
if test $revision -eq ${latest_revision:-0}; then
test $entry -eq 1 && echo "no new updates" >&2
break
fi
;;
'pubDate')
revdate=$(date +%s -d "$VALUE")
;;
'/item')
echo "$revision ($(date +"%d %B" -d@$revdate), $revauthor): $title" >&2
wget -qO- "$link" | awk -v data="revision=$revision revdate=$revdate revauthor=$revauthor" '
/>\/trunk\/Aircraft\/.+</ {
ac[gensub("^.+>/trunk/Aircraft/([^/]+).+<.*$", "ac=\\1", "1", $0)]++
}
END {
for (i in ac) print data " " i
}'
;;
'/channel')
if test ${latest_revision:-0} -lt $revision; then
echo "WARNING: $(( ($revision - ${latest_revision:-0}) )) revisions between the oldest RSS entry and last DB entry" >&2
echo "a \`$0 full' may be useful" >&2
fi
;;
esac
done < $aircrafts | awk '
{
if (a[$4] == "") a[$4]=$0
}
END {
for (i in a) {
total++
command = command a[i] " update_database;"
}
printf("total=%i;%s", total, command)
}'
}
latest_revision=$(sqlite_request "select max(revision) from aircrafts")
wget -qO- https://sourceforge.net/p/flightgear/fgaddon/feed > $aircrafts
eval "$(get_updates_from_rss)"
;;
*)
echo "usage: [DB=path/to/database] $0 [rss|full]"
echo
echo "rss: updates only last repo changes"
echo "full: updates from all repo"
exit 1
;;
esac