Showing 1 changed files with 94 additions and 139 deletions
+94 -139
.fgfs/fgaddon
... ...
@@ -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">&lt;__attribute__&gt;<.span>(.+)<span class="nt">&lt;.__attribute__&gt;<.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>&nbsp;' $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