#!/bin/bash
#---------------------------------------------------------------------
##
##=head1 SYNOPSIS
## 
## Url handler functions for grabbing 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 url_rsync_strip_prefix <url>
# 
# Private function.  Strips off the rsync:// prefix from rsync urls
#
#---------------------------------------------------------------------
function url_rsync_strip_prefix() {
  echo $1 | sed 's/^rsync:\/\///'
}


#---------------------------------------------------------------------
#=item url_rsync_run_rsync <url> <to>
#
# Private function.  Calls rsync and beautifies output
#
#---------------------------------------------------------------------
function url_rsync_run_rsync() {
  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 $2 -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
    rsync -rz --delete --stats --progress "$1" "$2" #few files - big files
  else
    rsync -rz --delete --stats -vv "$1" "$2" | 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=$?
    [[ $retcode == 0 ]] &&
    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
  return $retcode
}


#---------------------------------------------------------------------
##=item url_rsync_download <url>
## 
## Fetch the specified rsync url.
##
#---------------------------------------------------------------------
function url_rsync_download() { 
  if [ ! -x  /usr/bin/rsync ]; then
    message "${PROBLEM_COLOR}rsync is not installed, please cast it..." \
            "${DEFAULT_COLOR}"
    return 1
  fi

  local  URL=`url_rsync_strip_prefix "$1"`
  local  DEST=`echo $URL | cut -d':' -f 3-`

  [ -z "$FILE" ]  &&  FILE=`basename  $DEST`


  if  echo  $URL  |  grep  -q  sourcemage.org;  then
    local  WWW="sourcemage.org::"
    # check for which url to codex is to be used... based on rsync module given.
    case  $DEST  in
      test)       URL="${WWW}codex/test/"
                  DEST="$CODEX_ROOT/$DEST/"
                  ;;
      stable)     URL="${WWW}codex/stable/"
                  DEST="$CODEX_ROOT/$DEST/"
                  ;;
      games)      URL="${WWW}codex/games/"
                  DEST="$CODEX_ROOT/$DEST/"
                  ;;
      z-rejected) URL="${WWW}codex/z-rejected/"
                  DEST="$CODEX_ROOT/$DEST/"
                  ;;
      *)          message "${MESSAGE_COLOR}Not an available rsync package (test | stable | games | z-rejected), try again.${DEFAULT_COLOR}"
                  return 1
                  ;;
    esac
  else
    if echo $DEST | grep -q \/;  then
      DEST=\.
    fi
  fi
	
  local S_FILE=`echo $FILE            |
                sed "s/\.tar\.gz$//"  |
                sed "s/\.tgz$//"      |
                sed "s/\.tar\.bz2$//"`

  local dl_file
  if [[ "$FILE" == "$S_FILE" ]] ; then
    dl_file=0 # if it doesnt look like we're getting a file then we're probably
              # getting a source tree...
  else
    dl_file=1
  fi

  local rc
  # why isnt this using the uncompress functions?
  if [ ! $dl_file ] && [ -f $SOURCE_CACHE/$S_FILE.tar.bz2 ] ; then
    message "${MESSAGE_COLOR}Previous source found. Extracting package $S_FILE.tar.bz2...${DEFAULT_COLOR}"
    tar --bzip2 -xf $SOURCE_CACHE/$S_FILE.tar.bz2
    if cd $S_FILE ; then
        url_rsync_run_rsync "$URL" .
        rc=$?
        cd ..
    else
      message "Failed to unpack $SOURCE_CACHE/$S_FILE.tar.bz2 into $S_FILE..."
      rc=1
    fi
  else
    url_rsync_run_rsync "$URL" "$DEST"
    rc=$?
  fi

  if [[ $nocache == 1 ]] ; then
    return $rc
  fi

  if [ $rc == 0 ]; then
    message "${MESSAGE_COLOR}Creating package $S_FILE.tar.bz2...${DEFAULT_COLOR}"
    tar --bzip2 --remove-files -cf $S_FILE.tar.bz2 $S_FILE
    FILE=$S_FILE.tar.bz2
  else
    false
  fi
}


#---------------------------------------------------------------------
##=item url_rsync_verify <url>
## 
## Verifies the specified rsync url exists.  Returns true for now until
## I get around to implementing it.
##
#---------------------------------------------------------------------u
function url_rsync_verify() {
  true
}


#---------------------------------------------------------------------
##=item url_rsync_set_options <option>
##
## Set options for url handling
##
#---------------------------------------------------------------------
function url_rsync_set_options() {
  eval "$1=1"
}


#---------------------------------------------------------------------
##=item url_rsync_hostname <url>
##
## Gets the hostname for this rsync type url
##
#---------------------------------------------------------------------
function url_rsync_hostname() {
  echo $1|sed 's|^.*//\(.*\)::.*$|\1|'
}

#---------------------------------------------------------------------
##=item url_rsync_netselect <url>
##
## run netselect on the url, this will also expand and rank when there
## are multiple A records
##
#---------------------------------------------------------------------
function url_rsync_netselect() {
  netselect -s 1000 $@ 2>/dev/null
}

#---------------------------------------------------------------------
##=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
##
#---------------------------------------------------------------------

