#!/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">.*<__attribute__><.span>(.+)<.__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/.+$/\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>/p' > $aircrafts total=$(grep -c ' ' $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\/.+/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