#!/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 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 type) xmlgetnext () { local IFS='>' read -d '<' TAG VALUE TAG=$(tr '\n' ' ' <<< $TAG | sed 's/ */ /g; s/ *$//') } 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-set.xml 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 sqlite_request "vacuum" 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[$ac]}, ${revdate[$ac]}, '${revauthor[$ac]}')" elif test $dbupdate -lt ${revision[$ac]}; then sqlite_request "update aircrafts set revision = ${revision[$ac]}, author = '${revauthor[$ac]}', date = ${revdate[$ac]} where name is '$ac'" fi id=$(sqlite_request "select id from aircrafts where name is '$ac'") for sx in ${setxmlmodified[$ac]}; do test -n "${_sx[$ac/$sx]}" && continue _sx[$ac/$sx]="already done" unset description long_description author flight_model in_sim echo " -> $sx" svn export --quiet --force --revision ${revision[$ac]} $fgaddon_svn/$ac/$sx-set.xml $setxml while xmlgetnext; do case "$TAG" in ${attributes_case:0:${#attributes_case}-1}) test -n "$in_sim" && eval "${TAG//-/_}=\"$VALUE\"" test -n "$description" \ -a -n "$long_description" \ -a -n "$author" \ -a -n "$flight_model" \ -a -n "$type" && break ;; 'sim') in_sim=1;; '/sim') break;; esac done < $setxml if test -n "$description" -a -z "$flight_model"; then grep -qi 'jsbsim' <<< "$description" && flight_model='jsb' grep -qi 'yasim' <<< "$description" && flight_model='yasim' fi if test -n "$long_description"; then long_description=$(sed 's/^\s*//g' <<< $long_description | tr '\n' ' ') 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-set.xml installed=$? sqlite_request "insert into setxml values ('$sx', $id, '$description', '$long_description', '$author', '$type', '$flight_model', $installed)" fi done } 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)" attributes_case=$(printf "'%s'|" "${attributes[@]}") latest_revision=$(sqlite_request "select max(revision) from aircrafts") echo "downloading FGADDON history from revision ${latest_revision:-0}" svn log --revision ${latest_revision:-0}:HEAD --xml --verbose $fgaddon_svn > $aircrafts while xmlgetnext; do case "$TAG" in 'logentry revision='*) eval $(echo ${TAG#* }) unset revdate revauthor ac path_list setxmlmodified ;; 'author') revauthor=$VALUE ;; 'date') revdate=$(date +%s -d "$VALUE") ;; 'path '*) path_list[${#path_list[@]}]="$VALUE" ;; '/logentry') revlog[${#revlog[@]}]=$( printf '%s\n' "${path_list[@]}" | awk -F/ -v revision=$revision -v revauthor=$revauthor -v revdate=$revdate -v dq='"' ' { a[$4]++ if ($5 ~ "-set.xml$") b[$4]=b[$4] " " gensub("-set.xml$", "", "1", $5) } END { for (i in a) printf("", i, revision, i, revauthor, i, revdate, b[i] != "" ? "setxmlmodified[" i "]=" dq gensub("^ ", "", "g", b[i]) " ${setxmlmodified[" i "]}" dq ";" : "") }') ;; '/log') unset revision revauthor revdate setxmlmodified declare -A revision revauthor revdate setxmlmodified analyse () { while xmlgetnext; do test -z "$TAG" -a ${#revision[@]} -eq 0 && continue case $TAG in 'BEGIN') continue;; 'END' ) break 2;; esac echo $TAG done <<< "${revlog[@]}" } eval $(analyse) total=${#revision[@]} declare -A _sx for ac in "${!revision[@]}"; do update_database done break ;; esac done < $aircrafts