... | ... |
@@ -4,20 +4,18 @@ fgaddon_url=https://sourceforge.net/p/flightgear/fgaddon/HEAD/tree/trunk/Aircraf |
4 | 4 |
fgaddon_svn=https://svn.code.sf.net/p/flightgear/fgaddon/trunk/Aircraft |
5 | 5 |
fgaddon_path=$HOME/.fgfs/flightgear-addons/Aircraft |
6 | 6 |
|
7 |
-attribute_regex='s/^.*id="l[0-9]+" class="code_block">.*<span class="nt"><__attribute__><.span>(.+)<span class="nt"><.__attribute__><.span>.*$/\1/p' |
|
8 |
- |
|
9 | 7 |
aircrafts=$(mktemp --dry-run /dev/shm/Aircraft-XXXXXXXXX) |
10 | 8 |
aircraft=$(mktemp --dry-run /dev/shm/aircraft-XXXXXXX) |
11 | 9 |
setxml=$(mktemp --dry-run /dev/shm/setxml-XXXXXXXX) |
12 | 10 |
in_ram_database=$(mktemp --dry-run /dev/shm/XXXXXXX) |
13 | 11 |
database=${DB:-$0.db} |
14 | 12 |
|
15 |
-attributes=(description long_description author flight_model) |
|
13 |
+attributes=(description long_description author flight_model type) |
|
16 | 14 |
|
17 |
-function get_attribute () { |
|
18 |
- eval "unset $1" |
|
19 |
- result=$(sed -rn "${attribute_regex//__attribute__/${1//_/-}}" $setxml) |
|
20 |
- eval "$1=\$\"$result\"" |
|
15 |
+xmlgetnext () { |
|
16 |
+ local IFS='>' |
|
17 |
+ read -d '<' TAG VALUE |
|
18 |
+ TAG=$(tr '\n' ' ' <<< $TAG | sed 's/ */ /g; s/ *$//') |
|
21 | 19 |
} |
22 | 20 |
|
23 | 21 |
function sqlite_request () { |
... | ... |
@@ -36,6 +34,7 @@ function trap_exit () { |
36 | 34 |
rm -f $in_ram_database |
37 | 35 |
echo "no changes in $database" |
38 | 36 |
elif test -w "$database"; then |
37 |
+ sqlite_request "vacuum" |
|
39 | 38 |
mv -f $in_ram_database "$database" |
40 | 39 |
echo "database $database updated" |
41 | 40 |
elif ! test -e "$database"; then |
... | ... |
@@ -54,25 +53,47 @@ update_database () { |
54 | 53 |
|
55 | 54 |
dbupdate=$(sqlite_request "select revision from aircrafts where name is '$ac'") |
56 | 55 |
if test -z "$dbupdate"; then |
57 |
- sqlite_request "insert into aircrafts (name, revision, date, author) values ('$ac', $revision, $revdate, '$revauthor')" |
|
58 |
- elif test $dbupdate -lt $revision; then |
|
59 |
- sqlite_request "update aircrafts set revision = $revision, author = '$revauthor' where name is '$ac'" |
|
56 |
+ sqlite_request "insert into aircrafts (name, revision, date, author) |
|
57 |
+ values ('$ac', ${revision[$ac]}, ${revdate[$ac]}, '${revauthor[$ac]}')" |
|
58 |
+ elif test $dbupdate -lt ${revision[$ac]}; then |
|
59 |
+ sqlite_request "update aircrafts set |
|
60 |
+ revision = ${revision[$ac]}, |
|
61 |
+ author = '${revauthor[$ac]}', |
|
62 |
+ date = ${revdate[$ac]} |
|
63 |
+ where name is '$ac'" |
|
60 | 64 |
fi |
61 | 65 |
id=$(sqlite_request "select id from aircrafts where name is '$ac'") |
62 | 66 |
|
63 |
- wget -qO- $fgaddon_url/$ac > $aircraft |
|
64 |
- for sx in $(sed -rn 's/<a class="icon" href="(.+)-set.xml" title=".+"><i class="fa fa-file-o">.+$/\1/p' $aircraft); do |
|
67 |
+ for sx in ${setxmlmodified[$ac]}; do |
|
68 |
+ test -n "${_sx[$ac/$sx]}" && continue |
|
69 |
+ _sx[$ac/$sx]="already done" |
|
70 |
+ unset description long_description author flight_model in_sim |
|
65 | 71 |
echo " -> $sx" |
66 |
- wget -qO- $fgaddon_url/$ac/$sx-set.xml > $setxml |
|
67 |
- for attribute in ${attributes[@]}; do |
|
68 |
- get_attribute $attribute |
|
69 |
- done |
|
72 |
+ svn export --quiet --force --revision ${revision[$ac]} $fgaddon_svn/$ac/$sx-set.xml $setxml |
|
73 |
+ while xmlgetnext; do |
|
74 |
+ case "$TAG" in |
|
75 |
+ ${attributes_case:0:${#attributes_case}-1}) |
|
76 |
+ test -n "$in_sim" && eval "${TAG//-/_}=\"$VALUE\"" |
|
77 |
+ test -n "$description" \ |
|
78 |
+ -a -n "$long_description" \ |
|
79 |
+ -a -n "$author" \ |
|
80 |
+ -a -n "$flight_model" \ |
|
81 |
+ -a -n "$type" && break |
|
82 |
+ ;; |
|
83 |
+ 'sim') in_sim=1;; |
|
84 |
+ '/sim') break;; |
|
85 |
+ esac |
|
86 |
+ done < $setxml |
|
70 | 87 |
|
71 | 88 |
if test -n "$description" -a -z "$flight_model"; then |
72 | 89 |
grep -qi 'jsbsim' <<< "$description" && flight_model='jsb' |
73 | 90 |
grep -qi 'yasim' <<< "$description" && flight_model='yasim' |
74 | 91 |
fi |
75 | 92 |
|
93 |
+ if test -n "$long_description"; then |
|
94 |
+ long_description=$(sed 's/^\s*//g' <<< $long_description | tr '\n' ' ') |
|
95 |
+ fi |
|
96 |
+ |
|
76 | 97 |
known=$(sqlite_request "select variantof from setxml where file is '$sx'") |
77 | 98 |
if test -n "$known"; then |
78 | 99 |
for attribute in ${attributes[@]}; do |
... | ... |
@@ -90,11 +111,6 @@ update_database () { |
90 | 111 |
done |
91 | 112 |
} |
92 | 113 |
|
93 |
-xmlgetnext () { |
|
94 |
- local IFS='>' |
|
95 |
- read -d '<' TAG VALUE |
|
96 |
-} |
|
97 |
- |
|
98 | 114 |
trap trap_exit EXIT |
99 | 115 |
|
100 | 116 |
test -e $database && cp $database $in_ram_database |
... | ... |
@@ -102,124 +118,63 @@ test -e $database && cp $database $in_ram_database |
102 | 118 |
sqlite_request "create table if not exists aircrafts (id integer primary key, name text, revision integer, date integer, author text)" |
103 | 119 |
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)" |
104 | 120 |
|
105 |
-test -z "$1" && echo "mode RSS" |
|
106 |
- |
|
107 |
-case ${1:-rss} in |
|
108 |
- 'full') |
|
109 |
- echo "downloading the FGADDON list" |
|
110 |
- wget -qO- $fgaddon_url | sed -n '/<table>/,/<\/table>/p' > $aircrafts |
|
111 |
- |
|
112 |
- total=$(grep -c '<a class="icon" href=".*class="fa fa-folder".*i> ' $aircrafts) |
|
113 |
- |
|
114 |
- while xmlgetnext; do |
|
115 |
- case "$TAG" in |
|
116 |
- 'tr') |
|
117 |
- unset ac revision revauthor |
|
118 |
- ;; |
|
119 |
- 'a class="icon" href='*) |
|
120 |
- eval $(echo "${TAG#* }") |
|
121 |
- ac=$href |
|
122 |
- ;; |
|
123 |
- 'span title='*) |
|
124 |
- eval $(echo "${TAG#* }") |
|
125 |
- revdate=$(date +%s -d "$title") |
|
126 |
- ;; |
|
127 |
- 'a href="/p/flightgear/fgaddon/'*) |
|
128 |
- eval $(echo "${TAG#* }") |
|
129 |
- revision=$(tr -cd '[:digit:]' <<< $href) |
|
130 |
- ;; |
|
131 |
- 'span class="icon emboss x16" style="text-align:center;" title="User"'*) |
|
132 |
- user=1 |
|
133 |
- ;; |
|
134 |
- '/span') |
|
135 |
- test -n "$user" && revauthor=$(tr -cd '[:alnum:]' <<< $VALUE) && unset user |
|
136 |
- ;; |
|
137 |
- '/tr') |
|
138 |
- test -n "$revision" -a -n "$revauthor" -a -n "$ac" -a -n "$revdate" && update_database |
|
139 |
- ;; |
|
140 |
- esac |
|
141 |
- done < $aircrafts |
|
142 |
- ;; |
|
143 |
- 'rss') |
|
144 |
- get_updates_from_rss () { |
|
145 |
- while xmlgetnext; do |
|
146 |
- case "$TAG" in |
|
147 |
- 'item') |
|
148 |
- let entry++ |
|
149 |
- unset link revdate revauthor revision title;; |
|
150 |
- 'link') |
|
151 |
- link="$VALUE";; |
|
152 |
- 'title') |
|
153 |
- title="$VALUE";; |
|
154 |
- 'dc:creator'*) |
|
155 |
- revauthor="$VALUE";; |
|
156 |
- 'guid isPermaLink="false"') |
|
157 |
- revision=$(sed -r 's,^.+/([0-9]+)/$,\1,' <<< $VALUE) |
|
158 |
- if test $revision -eq ${latest_revision:-0}; then |
|
159 |
- test $entry -eq 1 && echo "no new updates" >&2 |
|
160 |
- break |
|
161 |
- fi |
|
162 |
- ;; |
|
163 |
- 'pubDate') |
|
164 |
- revdate=$(date +%s -d "$VALUE") |
|
165 |
- ;; |
|
166 |
- '/item') |
|
167 |
- echo "$revision ($(date +"%d %B" -d@$revdate), $revauthor): $title" >&2 |
|
168 |
- wget -qO- "$link" | awk -v data="revision=$revision revdate=$revdate revauthor=$revauthor" ' |
|
169 |
- />\/trunk\/Aircraft\/.+</ { |
|
170 |
- ac[gensub("^.+>/trunk/Aircraft/([^/]+).+<.*$", "ac=\\1", "1", $0)]++ |
|
171 |
- } |
|
172 |
- END { |
|
173 |
- for (i in ac) print data " " i |
|
174 |
- }' |
|
175 |
- ;; |
|
176 |
- '/channel') |
|
177 |
- if test ${latest_revision:-0} -lt $revision; then |
|
178 |
- echo "WARNING: $(( ($revision - ${latest_revision:-0}) )) revisions between the oldest RSS entry and last DB entry" >&2 |
|
179 |
- echo "a \`$0 full' may be useful" >&2 |
|
180 |
- fi |
|
181 |
- ;; |
|
182 |
- esac |
|
183 |
- done < $aircrafts | awk ' |
|
121 |
+attributes_case=$(printf "'%s'|" "${attributes[@]}") |
|
122 |
+latest_revision=$(sqlite_request "select max(revision) from aircrafts") |
|
123 |
+ |
|
124 |
+echo "downloading FGADDON history from revision ${latest_revision:-0}" |
|
125 |
+svn log --revision ${latest_revision:-0}:HEAD --xml --verbose $fgaddon_svn > $aircrafts |
|
126 |
+ |
|
127 |
+while xmlgetnext; do |
|
128 |
+ case "$TAG" in |
|
129 |
+ 'logentry revision='*) |
|
130 |
+ eval $(echo ${TAG#* }) |
|
131 |
+ unset revdate revauthor ac path_list setxmlmodified |
|
132 |
+ ;; |
|
133 |
+ 'author') |
|
134 |
+ revauthor=$VALUE |
|
135 |
+ ;; |
|
136 |
+ 'date') |
|
137 |
+ revdate=$(date +%s -d "$VALUE") |
|
138 |
+ ;; |
|
139 |
+ 'path '*) |
|
140 |
+ path_list[${#path_list[@]}]="$VALUE" |
|
141 |
+ ;; |
|
142 |
+ '/logentry') |
|
143 |
+ revlog[${#revlog[@]}]=$( |
|
144 |
+ printf '%s\n' "${path_list[@]}" | awk -F/ -v revision=$revision -v revauthor=$revauthor -v revdate=$revdate -v dq='"' ' |
|
184 | 145 |
{ |
185 |
- if (a[$4] == "") a[$4]=$0 |
|
146 |
+ a[$4]++ |
|
147 |
+ if ($5 ~ "-set.xml$") b[$4]=b[$4] " " gensub("-set.xml$", "", "1", $5) |
|
186 | 148 |
} |
187 | 149 |
END { |
188 |
- for (i in a) { |
|
189 |
- total++ |
|
190 |
- command = command a[i] " update_database;" |
|
191 |
- } |
|
192 |
- printf("total=%i;%s", total, command) |
|
193 |
- }' |
|
194 |
- } |
|
195 |
- latest_revision=$(sqlite_request "select max(revision) from aircrafts") |
|
196 |
- wget -qO- https://sourceforge.net/p/flightgear/fgaddon/feed > $aircrafts |
|
197 |
- eval "$(get_updates_from_rss)" |
|
198 |
- ;; |
|
199 |
- get) |
|
200 |
- test -z "$2" && exit 1 |
|
201 |
- ac=$(sqlite_request "select distinct(name) from aircrafts inner join setxml where aircrafts.id = setxml.variantof and (setxml.file = '$2' or aircrafts.name = '$2');") |
|
202 |
- if test -n "$ac"; then |
|
203 |
- if test -d $fgaddon_path/$ac; then |
|
204 |
- echo "$ac already installed" |
|
205 |
- test -d $fgaddon_path/$ac/.svn && echo "and seems to already be a subversion clone" |
|
206 |
- exit |
|
207 |
- elif test ! -w $fgaddon_path; then |
|
208 |
- echo "can't write in $fgaddon_path" |
|
209 |
- else |
|
210 |
- svn clone $fgaddon_svn/$ac $fgaddon_path/$ac |
|
211 |
- fi |
|
212 |
- else |
|
213 |
- echo "unknown aircraft $2" |
|
214 |
- fi |
|
215 |
- ;; |
|
216 |
- *) |
|
217 |
- echo "usage: [DB=path/to/database] $0 [rss|full]" |
|
218 |
- echo "usage: [DB=path/to/database] $0 get <aircraft>" |
|
219 |
- echo |
|
220 |
- echo "rss: updates only last repo changes" |
|
221 |
- echo "full: updates from all repo" |
|
222 |
- echo "get <aircraft>: svn clone aircraft if not installed" |
|
223 |
- exit 1 |
|
224 |
- ;; |
|
225 |
-esac |
|
150 |
+ for (i in a) |
|
151 |
+ printf("<revision[%s]=%i;revauthor[%s]=%s;revdate[%s]=%i;%s>", |
|
152 |
+ i, revision, |
|
153 |
+ i, revauthor, |
|
154 |
+ i, revdate, |
|
155 |
+ b[i] != "" ? "setxmlmodified[" i "]=" dq gensub("^ ", "", "g", b[i]) " ${setxmlmodified[" i "]}" dq ";" : "") |
|
156 |
+ }') |
|
157 |
+ ;; |
|
158 |
+ '/log') |
|
159 |
+ unset revision revauthor revdate setxmlmodified |
|
160 |
+ declare -A revision revauthor revdate setxmlmodified |
|
161 |
+ analyse () { |
|
162 |
+ while xmlgetnext; do |
|
163 |
+ test -z "$TAG" -a ${#revision[@]} -eq 0 && continue |
|
164 |
+ case $TAG in |
|
165 |
+ 'BEGIN') continue;; |
|
166 |
+ 'END' ) break 2;; |
|
167 |
+ esac |
|
168 |
+ echo $TAG |
|
169 |
+ done <<< "<BEGIN>${revlog[@]}<END>" |
|
170 |
+ } |
|
171 |
+ eval $(analyse) |
|
172 |
+ total=${#revision[@]} |
|
173 |
+ declare -A _sx |
|
174 |
+ for ac in "${!revision[@]}"; do |
|
175 |
+ update_database |
|
176 |
+ done |
|
177 |
+ break |
|
178 |
+ ;; |
|
179 |
+ esac |
|
180 |
+done < $aircrafts |