... | ... |
@@ -0,0 +1,164 @@ |
1 |
+#!/bin/bash |
|
2 |
+ |
|
3 |
+fgaddon_url=https://sourceforge.net/p/flightgear/fgaddon/HEAD/tree/trunk/Aircraft |
|
4 |
+fgaddon_svn=https://svn.code.sf.net/p/flightgear/fgaddon/trunk/Aircraft |
|
5 |
+fgaddon_path=$HOME/.fgfs/flightgear-addons/Aircraft |
|
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 |
+aircrafts=$(mktemp --dry-run /dev/shm/Aircraft-XXXXXXXXX) |
|
10 |
+aircraft=$(mktemp --dry-run /dev/shm/aircraft-XXXXXXX) |
|
11 |
+setxml=$(mktemp --dry-run /dev/shm/setxml-XXXXXXXX) |
|
12 |
+in_ram_database=$(mktemp --dry-run /dev/shm/XXXXXXX) |
|
13 |
+database=${DB:-$0.db} |
|
14 |
+ |
|
15 |
+attributes=(description long_description author flight_model) |
|
16 |
+ |
|
17 |
+function get_attribute () { |
|
18 |
+ eval "unset $1" |
|
19 |
+ result=$(sed -rn "${attribute_regex//__attribute__/${1//_/-}}" $setxml) |
|
20 |
+ eval "$1=\$\"$result\"" |
|
21 |
+} |
|
22 |
+ |
|
23 |
+function sqlite_request () { |
|
24 |
+ sqlite3 "$in_ram_database" <<< "$1" |
|
25 |
+} |
|
26 |
+ |
|
27 |
+function trap_exit () { |
|
28 |
+ if test -r "$database" && md5sum $in_ram_database | sed "s,$in_ram_database,$database," | md5sum --status -c -; then |
|
29 |
+ rm -f $in_ram_database |
|
30 |
+ elif test -w "$database"; then |
|
31 |
+ mv -f $in_ram_database "$database" |
|
32 |
+ elif ! test -e "$database"; then |
|
33 |
+ mv $in_ram_database "$database" |
|
34 |
+ else |
|
35 |
+ rm -f $in_ram_database |
|
36 |
+ fi |
|
37 |
+ rm -f $aircrafts $aircraft $setxml |
|
38 |
+} |
|
39 |
+ |
|
40 |
+update_database () { |
|
41 |
+ let progress++ |
|
42 |
+ echo "[ ${progress}${total:+/$total} ] $ac" |
|
43 |
+ |
|
44 |
+ dbupdate=$(sqlite_request "select date from aircrafts where name is '$ac'") |
|
45 |
+ if test -z "$dbupdate"; then |
|
46 |
+ sqlite_request "insert into aircrafts (name, date) values ('$ac', $update)" |
|
47 |
+ elif test $dbupdate -ne $update; then |
|
48 |
+ sqlite_request "update aircrafts set date = $update where name is '$ac'" |
|
49 |
+ fi |
|
50 |
+ id=$(sqlite_request "select id from aircrafts where name is '$ac'") |
|
51 |
+ |
|
52 |
+ wget -qO- $fgaddon_url/$ac > $aircraft |
|
53 |
+ for sx in $(sed -rn 's/<a class="icon" href="(.+-set.xml)" title=".+"><i class="fa fa-file-o">.+$/\1/p' $aircraft); do |
|
54 |
+ echo " -> ${sx/-set.xml}" |
|
55 |
+ wget -qO- $fgaddon_url/$ac/$sx > $setxml |
|
56 |
+ for attribute in ${attributes[@]}; do |
|
57 |
+ get_attribute $attribute |
|
58 |
+ done |
|
59 |
+ |
|
60 |
+ test -e $fgaddon_path/$ac/$sx |
|
61 |
+ installed=$? |
|
62 |
+ |
|
63 |
+ if test -n "$description" -a -z "$flight_model"; then |
|
64 |
+ grep -qi 'jsbsim' <<< "$description" && flight_model='jsb' |
|
65 |
+ grep -qi 'yasim' <<< "$description" && flight_model='yasim' |
|
66 |
+ fi |
|
67 |
+ |
|
68 |
+ known=$(sqlite_request "select variantof from setxml where file is '$sx'") |
|
69 |
+ if test -n "$known"; then |
|
70 |
+ for attribute in ${attributes[@]}; do |
|
71 |
+ dbvalue=$(sqlite_request "select $attribute from setxml where file is '$sx'") |
|
72 |
+ eval "wgvalue=\$$attribute" |
|
73 |
+ if test "$dbvalue" != "$wgvalue"; then |
|
74 |
+ sqlite_request "update setxml set $attribute = '$wgvalue' where file is '$sx'" |
|
75 |
+ fi |
|
76 |
+ done |
|
77 |
+ else |
|
78 |
+ sqlite_request "insert into setxml values ('$sx', $id, '$description', '$long_description', '$author', '$type', '$flight_model', $installed)" |
|
79 |
+ fi |
|
80 |
+ done |
|
81 |
+} |
|
82 |
+ |
|
83 |
+trap trap_exit EXIT |
|
84 |
+ |
|
85 |
+test -e $database && cp $database $in_ram_database |
|
86 |
+ |
|
87 |
+sqlite_request "create table if not exists aircrafts (id integer primary key, name text, date integer)" |
|
88 |
+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)" |
|
89 |
+ |
|
90 |
+test -z "$1" && echo "mode RSS" |
|
91 |
+ |
|
92 |
+case ${1:-rss} in |
|
93 |
+ 'full') |
|
94 |
+ echo "downloading the FGADDON list" |
|
95 |
+ wget -qO- $fgaddon_url > $aircrafts |
|
96 |
+ |
|
97 |
+ total=$(grep -c '<a class="icon" href=".*class="fa fa-folder".*i> ' $aircrafts) |
|
98 |
+ |
|
99 |
+ for ac in $(sed -rn 's/^\s*<a class="icon" href="(.+)" title=.* class="fa fa-folder".+$/\1/p' $aircrafts); do |
|
100 |
+ update=$(grep -A3 '<a class="icon" href=".*class="fa fa-folder".*i> '$ac'<' $aircrafts | sed -rn '$s/^\s*<span title="(.+)">.*$/\1/p') |
|
101 |
+ update=$(date +%s -d"$update") |
|
102 |
+ update_database |
|
103 |
+ done |
|
104 |
+ ;; |
|
105 |
+ 'rss') |
|
106 |
+ xmlgetnext () { |
|
107 |
+ local IFS='>' |
|
108 |
+ read -d '<' TAG VALUE |
|
109 |
+ } |
|
110 |
+ |
|
111 |
+ get_updates_from_rss () { |
|
112 |
+ wget -qO- https://sourceforge.net/p/flightgear/fgaddon/feed | while xmlgetnext; do |
|
113 |
+ case "$TAG" in |
|
114 |
+ 'lastBuildDate') |
|
115 |
+ if test ${latest_update:-0} -ge $(date +%s -d "$VALUE"); then |
|
116 |
+ echo "no new updates" |
|
117 |
+ exit |
|
118 |
+ fi |
|
119 |
+ ;; |
|
120 |
+ 'item') |
|
121 |
+ unset link pubDate revision title file;; |
|
122 |
+ 'link') |
|
123 |
+ link="$VALUE";; |
|
124 |
+ 'title') |
|
125 |
+ title="$VALUE";; |
|
126 |
+ 'guid isPermaLink="false"') |
|
127 |
+ revision=$(sed -r 's,^.+/([0-9]+)/$,\1,' <<< $VALUE);; |
|
128 |
+ 'pubDate') |
|
129 |
+ pubDate=$(date +%s -d "$VALUE");; |
|
130 |
+ '/item') |
|
131 |
+ echo "checking $revision ($(date +"%d %B" -d@$pubDate)): $title" >&2 |
|
132 |
+ wget -qO- "$link" > $aircrafts |
|
133 |
+ for file in $(egrep '/trunk/Aircraft/.*/.*-set.xml$' $aircrafts); do |
|
134 |
+ file=${file/\/trunk\/Aircraft\/} |
|
135 |
+ echo ${file%/*} |
|
136 |
+ echo $pubDate |
|
137 |
+ done |
|
138 |
+ ;; |
|
139 |
+ '/channel') |
|
140 |
+ if test ${latest_update:-0} -lt $pubDate; then |
|
141 |
+ echo "WARNING: $(( ($pubDate - ${latest_update:-0}) / 86400 )) days between the oldest RSS entry and last DB entry" >&2 |
|
142 |
+ echo "a $0 full may be useful" >&2 |
|
143 |
+ fi |
|
144 |
+ ;; |
|
145 |
+ esac |
|
146 |
+ done |
|
147 |
+ } |
|
148 |
+ latest_update=$(sqlite_request "select max(date) from aircrafts") |
|
149 |
+ ac_list=($(get_updates_from_rss)) |
|
150 |
+ total=$(( ${#ac_list[@]} / 2 )) |
|
151 |
+ for ((i=0; i < ${#ac_list[@]}; i=i+2)); do |
|
152 |
+ ac=${ac_list[i]} |
|
153 |
+ update=${ac_list[ac+1]} |
|
154 |
+ update_database |
|
155 |
+ done |
|
156 |
+ ;; |
|
157 |
+ *) |
|
158 |
+ echo "usage: [DB=path/to/database] $0 [rss|full]" |
|
159 |
+ echo |
|
160 |
+ echo "rss: updates only last repo changes" |
|
161 |
+ echo "full: updates from all repo" |
|
162 |
+ ;; |
|
163 |
+esac |
|
164 |
+ |
... | ... |
@@ -8,8 +8,24 @@ function fgfs () { |
8 | 8 |
local fgfs_install=$FGDIR/install |
9 | 9 |
function update_fg () { |
10 | 10 |
case $1 in |
11 |
+ fgaddon) |
|
12 |
+ DB=$FGADDON/fgaddon.db $HOME/.fgfs/fgaddon |
|
13 |
+ ;; |
|
11 | 14 |
data) |
12 |
- svn up $FGADDON |
|
15 |
+ typeset -A control_system_data=( |
|
16 |
+ git pull |
|
17 |
+ svn up |
|
18 |
+ ) |
|
19 |
+ for control_system update_command in ${(kv)control_system_data}; do |
|
20 |
+ find $FGADDON \ |
|
21 |
+ -maxdepth 3 \ |
|
22 |
+ -mindepth 1 \ |
|
23 |
+ -type d \ |
|
24 |
+ -name .${control_system} \ |
|
25 |
+ -printf "\n[ %h ]\n" \ |
|
26 |
+ -execdir ${control_system} ${update_command} \; |
|
27 |
+ done |
|
28 |
+ unset control_system_data control_system update_command |
|
13 | 29 |
;; |
14 | 30 |
source) |
15 | 31 |
typeset -A control_system_data=( |
... | ... |
@@ -93,6 +109,21 @@ function fgfs () { |
93 | 109 |
fgfs_args+=("--aircraft-dir=$official_aircraft") |
94 | 110 |
unset official_aircraft |
95 | 111 |
|
112 |
+############ APPAREIL DANS FGADDON ? |
|
113 |
+ elif which sqlite3 > /dev/null 2>&1 \ |
|
114 |
+ && test -r $FGADDON/fgaddon.db \ |
|
115 |
+ && test $(sqlite3 $FGADDON/fgaddon.db <<< "select count(file) from setxml where file is '${fgfs_arg}-set.xml'") -eq 1; then |
|
116 |
+ model=$(sqlite3 $FGADDON/fgaddon.db <<< "select name from aircrafts inner join setxml on aircrafts.id = setxml.variantof where setxml.file is '${fgfs_arg}-set.xml'") |
|
117 |
+ read -q "REPLY?download $model ? (y/N) " |
|
118 |
+ read |
|
119 |
+ if test -n "$REPLY" && test ${REPLY:l} = "y"; then |
|
120 |
+ svn co https://svn.code.sf.net/p/flightgear/fgaddon/trunk/Aircraft/$model $FGADDON/Aircraft/$model |
|
121 |
+ fgfs_args+=("--aircraft=$fgfs_arg") |
|
122 |
+ else |
|
123 |
+ echo "aircraft $fgfs_arg isn't installed" |
|
124 |
+ return |
|
125 |
+ fi |
|
126 |
+ |
|
96 | 127 |
############ SERVEUR MULTIPLAY ? |
97 | 128 |
elif set -o BASH_REMATCH && [[ $fgfs_arg =~ "^mp([0-9]+)$" ]]; then |
98 | 129 |
fgfs_args+=("--multiplay=out,10,mpserver${BASH_REMATCH[2]}.flightgear.org,5000") |
... | ... |
@@ -149,7 +180,7 @@ function fgfs () { |
149 | 180 |
######## AUTRE OPTION |
150 | 181 |
else |
151 | 182 |
case $fgfs_arg in |
152 |
- --update(-data|-source|-build|)) |
|
183 |
+ --update(-data|-source|-build|-fgaddon|)) |
|
153 | 184 |
for up in ${${=${fgfs_arg#--update}:-data source build}#-}; do |
154 | 185 |
update_fg $up |
155 | 186 |
done |