#!/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 [email protected]$HOST
;;

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

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

“complete”)
ssh [email protected]$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 [email protected]$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 [email protected]$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 [email protected]$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 [email protected]$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 “[email protected]
do
var=basename "${var}"
ttt=fixtorrentname "${var}"
echo “Setting label on: ${ttt}”
ssh [email protected]$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 “[email protected]
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 [email protected]$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 “[email protected]
do
if [ -f “$var” ]; then
echo “Processing $var”
echo ” …. uploading”
scp “$var” [email protected]$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 “[email protected]
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 [email protected]$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 [email protected]$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 [email protected]$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