#! /bin/bash
# $Id$
#
# This script is installed as a cron job to automatically update the
# Docutils web site whenever the SVN files change.  Any .html document
# with a corresponding .txt file is regenerated whenever the .txt
# changes.
#
# Options:
#   -f    Do not give feedback.
#   -t    Run the script in trace mode ("set -o xtrace").
#   -u    Regenerate .html unconditionally.
#   -v    Run verbosely.
#
# Prerequisites:
#
# - Checked out trunk at $snapshotdir.
# - Checked out main tree at $lib.

# exit on error
set -e

# make all newly created files group writeable
umask 002

basedir=/home/groups/docutils/htdocs
project=docutils
# $auxdir is non-public.
auxdir=$basedir/aux
# $htdocsdest is the destination for htdocs and will be moved to
# another server later; so we keep it non-public (under $auxdir).
htdocsdest=$auxdir/htdocs
# Where to create the snapshots (non-public).
snapshotdir=$auxdir/snapshots
# Where to publish the snapshots (public).
snapshotdest=/home/groups/ftp/pub/docutils
sshdir=$auxdir/.ssh
bindir=$auxdir/bin
htdocs_patchfile=$auxdir/htdocs.patch
htdocs_tarball=$auxdir/htdocs.tar
htdocs_new_tarball=$auxdir/htdocs.new.tar
# htdocs directory on SF.net
remotehtdocs=/home/groups/d/do/docutils/htdocs
pylib=$auxdir/lib/python
lib=$pylib/$project

export PYTHONPATH=$pylib:$lib:$lib/extras

trace=0
unconditional=0
verbose=0
feedback=1

while getopts ftuv opt
do
    case $opt in
        f)  feedback=;;
        t)  trace=1;;
        u)  unconditional=1;;
        v)  verbose=1;;
        \?) exit 2;;
    esac
done
shift `expr $OPTIND - 1`

test $feedback && echo 'Starting docutils-update run...'

if [ $trace -eq 1 -o $verbose -eq 1 ] ; then
    set -o xtrace
fi

# update library area
cd $lib
svn up --quiet

# -------------------- Snapshots: --------------------

# gather the materials
cd $snapshotdir
svn up --quiet

# Ensure proper directory permissions are set so that the files can be
# modified by several users.  Changing permissions of files is
# probably not necessary because files can be deleted and re-created.
# Do not change permissions of aux directory to keep it non-public
# (but change permissions for all subdirectories).
#find $basedir -type f -print0 | xargs -0 chmod ug+rw 2> /dev/null || true
find $basedir -name aux -o -type d -print0 | xargs -0 chmod ug+rwxs 2> /dev/null || true

# create the snapshots
exclude='--exclude=.svn'
tar -cz $exclude -f $project-snapshot.tgz $project
tar -cz $exclude -f $project-sandbox-snapshot.tgz sandbox
tar -cz $exclude -f $project-web-snapshot.tgz web
( cd sandbox/gschwant ;
  tar -cz $exclude -f ../../docfactory-snapshot.tgz docfactory )

# plant the snapshots
mv -f *snapshot.tgz $snapshotdest

# -------------------- htdocs: --------------------

cd $snapshotdir

function copy_to_htdocsdest() {
    find "$@" -type d -name .svn -prune -o -type f -print0 | \
        xargs -0 cp --update --parents --target-directory=$htdocsdest
}

# update htdocs
copy_to_htdocsdest sandbox
(cd $project; copy_to_htdocsdest *)
(cd web; copy_to_htdocsdest * .[^.]*)

# update HTML docs
cd $htdocsdest/tools

if [ $trace -eq 0 ] ; then
    set +o xtrace
fi

for htmlfile in `find .. -name '*.html'` ; do
    dir=`dirname $htmlfile`
    base=`basename $htmlfile .html`
    txtfile=$dir/$base.txt
    if [ -e $txtfile ] ; then
        if [ $unconditional -eq 1 -o $txtfile -nt $htmlfile ] ; then
            if [ "${base:0:4}" == "pep-" ] ; then
                test $feedback && echo "$txtfile (PEP)"
                python $lib/tools/pep.py --config=$dir/docutils.conf $txtfile $htmlfile
            else
                test $feedback && echo $txtfile
                python $lib/tools/rst2html.py --config=$dir/docutils.conf $txtfile $htmlfile
            fi
        fi
    fi
done

# -------------------- Push changes to remote server. --------------------

# SSH doesn't want to read id_dsa files which don't have 0600
# permissions.  This is getting into our way here, but we work around
# this by creating a lock directory (we need that anyway) and copying
# id_dsa to lock/id_dsa and setting the permissions of the resulting
# id_dsa file to 0600.

# Acquire lock.
if ! mkdir $sshdir/lock; then
    test $feedback && echo Waiting for lock.
    sleep 60
    if ! mkdir $sshdir/lock; then
        echo
        echo Could not create lock directory at
        echo $sshdir/lock
        echo
        echo Please ensure no other user is running this script
        echo and delete the directory.
        exit 1
    fi
fi
trap "rm -rf $sshdir/lock" 0 1 2 3 15

chmod ug+rwx $sshdir/lock
cp $sshdir/id_dsa $sshdir/lock/id_dsa
chmod 0600 $sshdir/lock/id_dsa

rm -f $htdocs_patchfile
# Create new tarball.
cd $htdocsdest
tar cf $htdocs_new_tarball .

# If the current and the new tarball differ...
if ! diff -q $htdocs_tarball $htdocs_new_tarball > /dev/null; then
    # Create patch.
    $bindir/bsdiff $htdocs_tarball $htdocs_new_tarball $htdocs_patchfile
    test $feedback && echo Patch size: `du -h $htdocs_patchfile | sed 's/\t.*//'`
    # Upload patch file.
    ssh -i $sshdir/lock/id_dsa \
        -o UserKnownHostsFile=$sshdir/known_hosts \
        docutilsupdate@shell.sourceforge.net \
        "
        set -e
        umask 002
        cat > ~/htdocs.patch
        ~/bin/bspatch ~/htdocs.tar ~/htdocs.new.tar ~/htdocs.patch
        cd $remotehtdocs
        tar xmf ~/htdocs.new.tar
        rm -f ~/htdocs.tar
        mv ~/htdocs.new.tar ~/htdocs.tar
        rm -f ~/htdocs.patch
        " \
            < $htdocs_patchfile
    rm -f $htdocs_tarball
    mv $htdocs_new_tarball $htdocs_tarball
fi

# Tidy up.
rm -f $htdocs_patchfile
rm -rf $sshdir/lock
test $feedback && echo '...docutils-update done.'

# Local Variables:
# indent-tabs-mode: nil
# End:
