config / .fgfs / fgaddon /
9b4f01a 4 years ago
1 contributor
180 lines | 7.154kb
#!/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("<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
            done
            break
        ;;
    esac
done < $aircrafts