#!/bin/bash

# temporary file, no need to change
TFILE=”/tmp/seedbox-notcomplete”
EXCLUDES=””
NOW=`date`
# check how I was invoked
ME=`basename $0`
MEHOST=”${ME} – `hostname`”
LFTPOPTS=”–continue –verbose –parallel=5 –use-pget-n=5 ”
CONFIGFILE=~/.config/${ME}.config
# output format, basic
OFORMAT=”{{default ESC = ‘\x1B’}}{{#
}}{{if d.done == 100.0 }}{{ESC}}[92m{{\\\”%5.1f\\\” % d.done}}{{ESC}}[0m {{ESC}}[92m{{d.name}}{{ESC}}[0m{{#
}}{{elif d.done == 0.0 }}{{ESC}}[91m{{\\\”%5.1f\\\” % d.done}}{{ESC}}[0m {{ESC}}[91m{{d.name}}{{ESC}}[0m{{#
}}{{else}}{{ESC}}[93m{{\\\”%5.1f\\\” % d.done}}{{ESC}}[0m {{ESC}}[93m{{d.name}}{{ESC}}[0m{{endif}}”
#OFORMAT=”{{\\\”%5.1f\\\” % d.done}}|{{d.name}}”
# Colored output for detail listing (size,uploaded,ratio,tracker,name)
DETAIL=”{{default ESC = ‘\x1B’}}{{#
}}{{if d.ratio >= 1.0}}{{ESC}}[92m{{elif d.ratio==0.0}}{{ESC}}[91m{{else}}{{ESC}}[93m{{endif}}{{#
}}{{d.size|sz}}{{#
}}{{d.uploaded|sz}}{{#
}}{{str(pc(d.ratio)).rjust(8)}} {{#
}}{{(d.alias or ”).ljust(20)}} {{d.name or ”}}{{ #
}}{{ESC}}[0m”
# colored output detail listing (name, size, done, uploaded, ratio, tracker)
DETAIL=”{{default ESC = ‘\x1B’}}{{#
}}{{if d.ratio >= 1.0}}{{ESC}}[92m{{elif d.ratio==0.0}}{{ESC}}[91m{{else}}{{ESC}}[93m{{endif}}{{#
}}{{(d.name)[:45].ljust(45)}} {{#
}}{{d.size|sz}} {{#
}}{{\\\”%5.0f\\\” % d.done}}{{chr(37)}} {{#
}}{{d.uploaded|sz}} {{#
}}{{str(pc(d.ratio/100)).rjust(8)}} {{#
}}{{(d.alias or ”).ljust(20)}} {{#
}}{{ESC}}[0m”
IGNORELABEL=”dontdownload”

# display some usage information
usage() {
echo
echo “Needs to be invoked as one of the following:”
echo
echo “${ME} ssh”
echo ” ssh into the seedbox”
echo
echo “${ME} ftp [delete|all|test]”
echo ” copy all completed files from the seedbox”
echo ” optionally, ‘delete’ the files that have been removed from the seedbox”
echo ” optionally, download ‘all’ files regardless of completion status”
echo ” optionally, just ‘test’ to see what would be done”
echo ” note that delete|all|test are mutually exclusive”
echo
echo “${ME} complete”
echo ” List the files that are complete on the seedbox”
echo
echo “${ME} incomplete”
echo ” List the files that are incomplete on the seedbox”
echo
echo “${ME} dontdownload”
echo ” List the files that should not be downloaded due to their tag”
echo
echo “${ME} detail”
echo ” List the details of all torrents”
echo
echo “${ME} label [label]”
echo ” List the torrents with a specific label”
echo ” note, if you do not proved the label, a list of torrents with no label is returned”
echo
echo “${ME} setlabel <label> <torrent> <torrent> <…>”
echo ” Sets the label on one or more torrents”
echo
echo “${ME} delete <torrent> <torrent> <…>”
echo ” Deletes one or more torrent and associated data”
echo
echo “${ME} seed <torrent files>”
echo ” Add torrent files to blackhole directory (${WATCHDIR})”
echo
echo “${ME} wget <filenames>”
echo ” get one or more files/directories over http”
echo ” <filenames> names of the file/dir to get (path is relative to ${HTTPDIR})”
echo
echo “${ME} info”
echo ” shows the seedbox host and credentials”
echo
echo “${ME} edit”
echo ” Edit the configuration”
echo
}

message() {
echo “$*”
}

# fixup the torrent name, escaping properly
fixtorrent() {
fixed=”${1}”
fixed=$(echo $fixed | sed ‘s/\[/\\\[/g’)
fixed=$(echo $fixed | sed ‘s/\]/\\\]/g’)
fixed=$(echo $fixed | sed ‘s/(/\\(/g’)
fixed=$(echo $fixed | sed ‘s/)/\\)/g’)
fixed=$(echo $fixed | sed ‘s/&/\\&/g’)
fixed=$(echo $fixed | sed ‘s/|/\\|/g’)
fixed=$(echo $fixed | sed “s/’/\\’/g”)
fixed=$(echo $fixed | sed ‘s/ /\\ /g’)
fixed=$(echo $fixed | sed ‘s/;/?/g’)
echo “${fixed}”
}

# fixup the torrent name, escaping properly
fixtorrentname() {
fixed=”${1}”
#echo “Fixed 0: ${fixed}”
fixed=${fixed#”/”}
#echo “Fixed 0.1: ${fixed}”
fixed=${fixed%”/”}
#echo “Fixed 0.2: ${fixed}”
# when sending a torrent name to rtcontrol, it does not like some characters (wildcard/escape them)
# wildcards…
fixed=$(echo “${fixed}” | sed ‘s/\]/?/g’)
#echo “Fixed 1: ${fixed}”
fixed=$(echo “${fixed}” | sed ‘s/\[/?/g’)
#echo “Fixed 2: ${fixed}”
fixed=$(echo “${fixed}” | sed ‘s/{/?/g’)
#echo “Fixed 3: ${fixed}”
fixed=$(echo “${fixed}” | sed ‘s/}/?/g’)
#echo “Fixed 2: ${fixed}”
fixed=$(echo “${fixed}” | sed ‘s/(/?/g’)
#echo “Fixed 3: ${fixed}”
fixed=$(echo “${fixed}” | sed ‘s/)/?/g’)
#echo “Fixed 4: ${fixed}”
fixed=$(echo “${fixed}” | sed ‘s/&/?/g’)
#echo “Fixed 5: ${fixed}”
fixed=$(echo “${fixed}” | sed ‘s/,/?/g’)
#echo “Fixed 6: ${fixed}”
fixed=$(echo “${fixed}” | sed ‘s/;/?/g’)
fixed=$(echo “${fixed}” | sed ‘s/|/?/g’)
# escaping…
fixed=$(echo “${fixed}” | sed “s/’/\\’/g”)

echo “${fixed}”
}

# source the .profile (in case we were executed from a cron job)
if [ -f ~/.profile ]; then
. ~/.profile
fi

if [ ! -f ${CONFIGFILE} ]; then
# create a template configfile
cat<<EOF > ${CONFIGFILE}
# Put all the seedbox information here
# seedbox hostname
HOST=seedbox.host.com
# username
USER=username
# password (unencrypted)
PASS=password
# the home directory on the seedbox
HOMEDIR=/home/\${USER}
# The directory where completed torrents are stored (full path)
COMPLETEDIR=\$HOMEDIR/torrents/downloads
# the seedbox blackhole/watch directory (full path)
WATCHDIR=\$HOMEDIR/torrents/watch
# the HTTP download directory (https://HOST/HTTPDIR)
HTTPDIR=/dracula/downloads
# The local directory where completed torrents get downloaded to (full path)
TO=/mnt/save
# Webclient URL
WEBURL=http://\$HOST/\$USER/rutorrent
EOF

message “Could not find the configfile, ${CONFIGFILE}”
message “but a template file was created.”
message “Please edit ${CONFIGFILE} and rerun your command”
exit 2

else
# source the config file
. ${CONFIGFILE}
fi
# command is the second argument
if [ -z “$1” ]; then
usage
exit 1
fi

OPERATION=$1
shift

if [ “${OPERATION}” = “list” ]; then
OPERATION=”label”
fi

case “$OPERATION” in
“edit”)
vi ${CONFIGFILE}
;;

“info”)
message “From ${CONFIGFILE}:”
message “——————”
# cat ${CONFIGFILE} | grep -v “^#”
for a in “HOST” “HOMEDIR” “COMPLETEDIR” “WATCHDIR” “HTTPDIR” “TO” “USER” “PASS” “WEBURL”
do
printf “%-12s %s\n” “${a}:” “${!a}”
done
;;

“ssh”)
ssh $USER@$HOST
;;

“cd”)
cd “${TO}”
gnome-terminal –title=”${ME}” –geometry=132×24
;;

“browse”)
nautilus “${TO}/downloads”
;;

“complete”)
ssh $USER@$HOST “bin/rtcontrol is_complete=yes -s done,name -o \”${OFORMAT}\”” | grep -v “^INFO ”
if [ $? -ne 0 ]; then
echo “Error running bin/rtcontrol though ssh”
exit 1
fi
;;

“incomplete”)
ssh $USER@$HOST “bin/rtcontrol is_complete=no -s done,name -o \”${OFORMAT}\”” | grep -v “^INFO ”
if [ $? -ne 0 ]; then
echo “Error running bin/rtcontrol though ssh”
exit 1
fi
;;
“dontdownload”)
ssh $USER@$HOST “bin/rtcontrol custom_1=\”${IGNORELABEL}\” -o name” | grep -v “^INFO ”
if [ $? -ne 0 ]; then
echo “Error running bin/rtcontrol though ssh”
exit 1
fi
;;
“detail”)
ssh $USER@$HOST “bin/rtcontrol name=\* -s ratio -o \”${DETAIL}\”” | grep -v “^INFO ”
if [ $? -ne 0 ]; then
echo “Error running bin/rtcontrol though ssh”
exit 1
fi
;;

“label”)
if [ $# -gt 1 ]; then
message “No more than one argument can be supplied to label”
usage
exit 1
fi

ssh $USER@$HOST “bin/rtcontrol custom_1=\”${1}\” -s done,name -o \”${OFORMAT}\”” | grep -v “^INFO ”
if [ $? -gt 1 ]; then
echo “Error running bin/rtcontrol though ssh”
exit 1
fi
;;

“setlabel”)
if [ $# -eq 1 ]; then
message “A label and at least one torrent must be specified”
usage
exit 1
fi

label=”${1}”
shift

for var in “$@”
do
var=`basename “${var}”`
ttt=`fixtorrentname “${var}”`
echo “Setting label on: ${ttt}”
ssh $USER@$HOST “bin/rtcontrol –custom=1=\”${label}\” \”${ttt}\” ”
if [ $? -gt 1 ]; then
echo “Error running bin/rtcontrol though ssh”
exit 1
fi
done
;;

“delete”)
if [ $# -eq 0 ]; then
message “At least one argument must be supplied”
usage
exit 1
fi
for var in “$@”
do
# make sure the torrent doesn’t start or end in a forward slash
#echo “Before basename: ${var}”
var=`basename “${var}”`
#echo “Before fixtorrentname: ${var}”
# var=`fixtorrentname “${var}”`
var=$(fixtorrentname “${var}”)
echo “Deleting: ${var}”
ssh $USER@$HOST “bin/rtcontrol –yes –cull \”${var}\” ”
if [ $? -gt 1 ]; then
echo “Error running bin/rtcontrol though ssh”
exit 1
fi
done
;;

“seed”)
if [ $# -eq 0 ]; then
message “At least one argument must be supplied to seed”
usage
exit 1
fi

for var in “$@”
do
if [ -f “$var” ]; then
echo “Processing $var”
echo ” …. uploading”
scp “$var” $USER@$HOST:$WATCHDIR
if [ $? -eq 0 ]; then
echo ” …. success, deleting”
rm “$var”
else
echo ” …. failed”
fi
fi
done
;;

“wget”)
if [ $# -eq 0 ]; then
message “At least one argument must be supplied to wget”
usage
exit 1
fi

# find the number of cut directories
# should be the number of tokens found by tokenizing the HTTPDIR on “/” characters
# we also want to ensure that HTTPDIR does not start or end in a “/”
HTTPDIR=${HTTPDIR#”/”}
HTTPDIR=${HTTPDIR%”/”}
CUTDIRS=`echo “${HTTPDIR}” | awk -F ‘/’ ‘{print NF}’`

WGETOPTS=”–no-check-certificate -nH –no-parent -r –cut-dirs=${CUTDIRS}”

for var in “$@”
do
# if we want to get a directory, we need to add a trailing “/” on $var or it will recursively get
# everything, including the parent directory
var=${var%”/”}
echo “Processing $var”
TYPE=$(ssh $USER@$HOST “file -b \”${HOMEDIR}/${COMPLETEDIR}/${var}\””)
if [ “${TYPE}” = “directory” ]; then

var=”${var}/”
echo “getting a directory:”
else
echo “getting a file:”
fi
wget –user=$USER –password=$PASS ${WGETOPTS} –reject “index.html*” “https://${HOST}/${HTTPDIR}/${var}”
done
;;

“ftp”)

if [ $# -gt 1 ]; then
message “${OPERATION} only accepts, at most, one argument”
usage
exit 1
fi

if [ ! -z `which lockme` ]; then
. lockme
else
message “Cannot find the lockme script, running without a process lock”
message “This means that more than one instance of this script could be run”
fi

if [ ! -d “${TO}” ]; then
echo “Target directory, ${TO}, does not exist. Exiting”
exit 1
fi

STATUSFILE=”${TO}/${MEHOST} – ${NOW}”
touch “${STATUSFILE}”

# first get the list of non-complete torrents
if [ -f “${TFILE}” ]; then
rm “${TFILE}”
fi

# if we’re not getting all files, build the list of files to NOT get
if [ “$1” != “all” ]; then
# get the list of incomplete files
ssh $USER@$HOST “bin/rtcontrol is_complete=no -o name” | grep -v “INFO ” > $TFILE
rc=$?
# we should really check the return code here to see if the command ran correctly
if [ $rc -gt 1 ]; then
echo “Error running bin/rtcontrol though ssh, return code is: $rc”
exit 1
fi

# maybe we should also exclude torrents with a specific predefines tag?
ssh $USER@$HOST “bin/rtcontrol custom_1=\”${IGNORELABEL}\” -o name” | grep -v “^INFO ” >> $TFILE
rc=$?
if [ $rc -gt 1 ]; then
echo “Error running bin/rtcontrol though ssh, return code is: $rc”
exit 1
fi

# if we got back a list, add each line to the excludes list for rsync
if [ -f “${TFILE}” ]; then

echo
echo “Note: Some files will be excluded because they are incomplete or labeled as ‘${IGNORELABEL}'”
cat “${TFILE}” | sort -u
echo

# note that any ‘odd’ characters in this file cause problems, try escaping them
sed -i ‘s/\[/\\\[/g’ $TFILE
sed -i ‘s/\]/\\\]/g’ $TFILE

sed -i “s|{|\\\{|g” $TFILE
sed -i ‘s|}|\\}|g’ $TFILE

sed -i ‘s/(/\\(/g’ $TFILE
sed -i ‘s/)/\\)/g’ $TFILE
sed -i ‘s/&/\\&/g’ $TFILE
sed -i “s/’/\\’/g” $TFILE
sed -i “s/\;/\\\;/g” $TFILE
sed -i “s/|/?/g” $TFILE

while read -r line
do
EXCLUDES=”$EXCLUDES -x \”${line}\” ”
done < “${TFILE}”

fi
fi

# maybe we should also exclude torrents with a specific predefined tag?

if [ “$1” = “delete” ]; then
LFTPOPTS=”$LFTPOPTS –delete ”
fi

if [ “$1” = “test” ]; then
LFTPOPTS=”$LFTPOPTS –dry-run ”
fi

MIRRORCMD=”mirror ${LFTPOPTS} ${EXCLUDES} ${COMPLETEDIR} ${TO} ; bye”
#echo $MIRRORCMD

echo “Starting lftp sync”
lftp -e “${MIRRORCMD}” -u $USER,$PASS sftp://$HOST
echo “Done”

# if we excluded files, print a message
if [ -s “${TFILE}” ]; then
rm “${TFILE}”
fi

rm “${STATUSFILE}”

;;

*)
message “An invalid command was specified: $OPERATION”
usage
exit 1
;;
esac

exit 0