#!/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-fgaddon/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 and setxml.installed != 0;'); do ac_path=${ac#*:} if test ! -e $fgaddon_path/$ac_path-set.xml; then sqlite_request "update setxml set installed = 0 where file = '${ac_path#*/}' and variantof = ${ac%:*}" fi done for ac in $fgaddon_path/*/*-set.xml; do ac=${ac/$fgaddon_path} sx=${ac##*/} ac=${ac%/*} if test -d $fgaddon_path/$ac/.svn; then install_type=1 elif test -d $fgaddon_path/$ac/.git; then install_type=2 else install_type=3 fi sqlite_request "update setxml set installed = $install_type where exists ( select 1 from aircrafts where name = '${ac/\/}' and setxml.variantof = id )" 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 if [[ "$TAG" = @($attributes_case) ]]; then 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 elif test "$TAG" = 'sim'; then in_sim=1 elif test "$TAG" = '/sim'; then break fi done < $setxml test -z "$description" \ -a -z "$long_description" \ -a -z "$author" \ -a -z "$flight_model" \ -a -z "$type" && echo "WARNING: no info found, skipping" && continue 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" -a -n "$wgvalue"; then sqlite_request "update setxml set $attribute = '$wgvalue' where file is '$sx'" fi done else sqlite_request "insert into setxml values ('$sx', $id, '$description', '$long_description', '$author', '$type', '$flight_model', 0)" 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[@]}") attributes_case=${attributes_case:0:-1} 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 if test -d $fgaddon_path/$ac/.svn \ && test "$(svn info --show-item=url $fgaddon_path/$ac)" != "$fgaddon_svn/$ac" \ || test -d $fgaddon_path/$ac -a ! -d $fgaddon_path/$ac/.svn; then echo "INFO: local $ac installed out from repo" >&2 fi done break ;; esac done < $aircrafts