#!/bin/bash
#---------------------------------------------------------------------
##
##=head1 SYNOPSIS
## 
## Url handler functions for downloading rsync urls.
##
##=head1 DESCRIPTION
##
## This file contains functions for I<downloading> files through rsync.
##
## In order for rsync urls to be downloaded, the I<rsync> spell must have been
## cast. This script first determines if rsync has been installed before 
## attempting to download a rsync url.
##
##=head1 RSYNC URL Format
##
##
##      rsync://SERVER::MODULE_NAME
##
## The above url will download the latest version of the specified
## module.
##
##=head1 EXAMPLES
##
## Suppose we want to download the latest version of the sorcery
## stable grimoire via rsync.  We'd use the following url:
##
##      rsync://codex.sourcemage.org::stable
##
##=head1 IMPLEMENTATION NOTE
##
## Downloading is supported but rsync url verification is not
## currently supported.
##
##=head1 COPYRIGHT
##
## Copyright 2003 by the Source Mage Team
##
##=head1 FUNCTIONS
##
##=over 4
##
#---------------------------------------------------------------------

#---------------------------------------------------------------------
##=item dl_rsync_download <url>
## 
## Fetch the specified rsync url.
##
## This handler supports both files and trees.
##
#---------------------------------------------------------------------
function dl_rsync_get() { 
  dl_command_check rsync || return 254

  local target=$1
  local url_list=$2
  local hints=$3
  local dl_target=$4
  local dl_type=$5
  local url rc=1

  [[ $target ]] &&
  dl_connect || return 255

  local dl_file=0
  if list_find "$hints" file; then
    dl_file=1
  fi

  for url in $url_list; do
    url=`url_rsync_crack "$url"`
    dl_rsync_run_rsync "$target" "$url" "$dl_target" "$dl_type"
    rc=$?
    [[ $rc == 0 ]] && break
  done
  dl_disconnect

  return $rc
}

#---------------------------------------------------------------------
#=item dl_rsync_run_rsync <url> <to>
#
# Private function.  Calls rsync and beautifies output
#
#---------------------------------------------------------------------
function dl_rsync_run_rsync() {
  local target=$1
  local url=$2
  local dl_target=$3
  local dl_type=$4

  local TOTAL line retcode
  local COUNT=0
  local position="a"
  local use_spinner
  
  if [ "$dl_file" == 1 ]; then
    TOTAL=0 # downloading a single file, not a source tree
  else
    let TOTAL=$(find $1 -type f 2>/dev/null | wc -l)
    if [ "$TOTAL" -lt 2 ] ; then
      let TOTAL=100
      use_spinner=yes
    else
      let TOTAL+=10
    fi
  fi
  
  message "${MESSAGE_COLOR}Running rsync...${DEFAULT_COLOR}"
  if [ $TOTAL -lt 10 ] ; then
    echo rsync -rz --delete --stats --progress "$url" "$target"
    rsync -rz --delete --stats --progress "$url" "$target" #few files - big files
    retcode=$?
  else
    echo rsync -rz --delete --stats -vv "$url" "$target"
    {
      rsync -rz --delete --stats -vv "$url" "$target" 
      echo $? > $TMP_DIR/rsync.rc
    } | tee $TMP_DIR/rsyncout$$ |
    while read line ; do
      if [ "$position" == "c" ] ;then
        #make the progress bar - as quick as possible
        let COUNT=($COUNT+1)%$TOTAL
        if [[ $use_spinner ]] ; then
          progress_spinner
        else
          progress_bar $COUNT $TOTAL 50
        fi
      elif [ "$position" == "a" ] ;then
        echo "$line" | grep -q 'receiving file list ...' && position="b"
        echo "$line" #print welcome message until filelist almost starts
      elif [ "$position" == "b" ] ;then
        echo "$line" | grep -q 'done' && position="c"
        echo "$line" #only now look for done = only filenames following
      fi
    done
    retcode=$(<$TMP_DIR/rsync.rc)
    [[ $retcode == 0 ]] &&
    [[ $use_spinner ]] ||
    progress_bar $TOTAL $TOTAL 50 # make the progress bar show 100, on success

    echo
    tail -n 25 $TMP_DIR/rsyncout$$ | head -n 12 #stats w/o useless stack stats
    echo
    rm -f $TMP_DIR/rsyncout$$
  fi
  if test -d $target; then
    eval "$dl_type=\"tree\""
  else
    eval "$dl_type=\"file\""
  fi
  eval "$dl_target=\"$target\""
  return $retcode
}



#---------------------------------------------------------------------
##=back
##
##=head1 LICENSE
##
## This software is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This software is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this software; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
##
#---------------------------------------------------------------------
