1 contributor
#!/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("<revision[%s]=%i;revauthor[%s]=%s;revdate[%s]=%i;%s>",
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 <<< "<BEGIN>${revlog[@]}<END>"
}
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