Adding functionality on Transmission

Watchdir and bandwidth scheduling, among others

Introduction

Ok, so after you have successfully installed transmission, you'll want to get using it.

In this part of the guide, we'll be adding some functionality to the client; for example a rtorrent-like watch directory and bandwidth scheduling, which isn't availabale by default in the daemon version of transmission.

Prerequisites

Enabled SSH access.

 

A text editor and the know-how to use it. I recommend installing nano, but vi will also do just fine.

 

The Transmission BitTorrent client installed on your MBWE. See the previous part of this guide for more information.

Note: From version 1.20 to version 1.30 the RPC/IPC protocols of Transmission were completely redefined so versions between those might not work as expected. All the scripts here have been updated to work with version 1.30 and above and all the instructions assume you have version newer than 1.30. However, old versions for transmission 1.20 and older are also available for download.

The how-to

  1. Make sure you are in superuser mode.

    # su
  2. Now, transmission doesn't support a watch folder like for example rtorrent does. Neither does its' daemon version provide bandwidth scheduling.

     

    I have put together a shell script to achieve these. Also, it is able to move completed downloads to a desired directory after seeding them to a desired ratio and shut down transmission when it is not used, in order to free up some memory.

    So, it is a bit like transmission_watchdog, only better ;)

     

    Here's the script:

    #!/bin/bash
    # 
    # torrent_helper
    # A helper script for the Transmission BitTorrent client
    # What it does:
    # - Enables watch folder functionality 
    # - Automatically removes completed torrents (after seeding to desired ratio)
    # - Moves the downloaded files to a desired directory
    # - Makes sure that there are only desired amount of concurrent downloads
    # written by kyyhkynen at gmail dot com
    #
    # note that this version of the script works only with transmission version 1.3 and newer!
    # see http://kyyhkynen.net/stuff/mybook for further info
    #
    # you may use and modify this script any way you want as long as you keep this header attached
    # last modified Sep 30th, 2008
    ################
    # Configuration
    ################
    
    # path to transmission-remote
    # if you built transmission from source, you'll need to change this
    TRANSMISSION_REMOTE=/opt/bin/transmission-remote
    
    # command to start transmission when it is not running
    TRANSMISSION_START="/etc/init.d/transmission.sh start"
    # command to stop transmission when it is running
    TRANSMISSION_STOP="/etc/init.d/transmission.sh stop"
    
    
    # transmission working directory
    # note that if you're using the transmission startup script (/etc/init.d/transmission.sh), 
    # this should should be the same as in it
    WORKDIR=/shares/internal/PUBLIC/Torrent/workdir
    
    # the directory to watch for new .torrent files
    # leave blank if you don't want to use one
    WATCHDIR=/shares/internal/PUBLIC/Torrent/watchdir
    
    # whether or not to remove completed downloads automatically at all
    # if set to 0, torrents are seeded indefinitely until you remove them manually
    # if set to 0, the following two settings won't have any effect on anything
    REMOVE_COMPLETED=1
    
    # the directory to put completed downloads into
    # leave blank if you want to keep seeding completed downloads in the working directory
    COMPLETEDIR=/shares/internal/PUBLIC/Torrent/incoming
    
    # the seeding ratio you'll want to be seeding the downloaded files to before removing them
    SEED_UNTIL_RATIO=0.5
    
    # how many torrents should be downloading at the same time
    # recommended to keep this at 1, since mbwe does have so little memory and so slow cpu
    MAX_SIMULTANEOUS=1
    
    # how often the watch directory should be checked, in seconds
    # by default 5 minutes (=300 seconds)
    FREQUENCY=300
    
    # whether or not to quit transmission, if there are no torrents in the queue.
    # if quit, it will be restarted when something is found in the watch directory
    # if you're planning on adding torrents also by other means (with clutch, for example)
    # than using the watch directory, set this to 0
    QUIT_TRANSMISSION_WHEN_INACTIVE=1
    
    # bandwidth scheduling
    # list schedules in following format
    # SCHEDULE_DOWNLOAD[[hour to start]]=[download speed in kb]
    # SCHEDULE_UPLOAD[[hour to start]]=[upload speed in kb]
    # use 24h clock hours in the hours
    # 0 as speed means unlimited
    # the following examples limit the bandwidth during daytime ( 8 - 23 ) and set them unlimited for night
    # note that your upload speed shouldn't be set to unlimited, but to
    # about 90% of your total upload bandwidth in order to keep it from limiting your download speeds also...
    SCHEDULE_DOWNLOAD[8]=600
    SCHEDULE_UPLOAD[8]=65
    SCHEDULE_DOWNLOAD[23]=0
    SCHEDULE_UPLOAD[23]=85
    
    
    # logging options
    LOG_ENABLED=true
    LOGGER="/usr/bin/logger -t torrent_helper"
    
    ############################################
    # end of configuration
    # you shouldn't need to edit anything below
    ############################################
    
    LAST_SCHEDULE_DOWNLOAD=-1
    LAST_SCHEDULE_UPLOAD=-1
    
    $LOG_ENABLED && ${LOGGER} "torrent_helper started."
    
    
    # function to try to find bandwidth schedules that should be active
    # used when starting the script and restarting transmission
    find-previous-schedules() 
    {
    	NOW_HOURS=`date +%k`;
    	while [[ -z ${SCHEDULE_DOWNLOAD[NOW_HOURS]} ]]; do
    		NOW_HOURS=$(($NOW_HOURS-1)) ;
    		if [ "${NOW_HOURS}" -lt "0" ]; then
    			NOW_HOURS=0
    			break
    		fi
    	done
    	if [ ! -z ${SCHEDULE_DOWNLOAD[NOW_HOURS]} ]; then
    		if [ "${SCHEDULE_DOWNLOAD[NOW_HOURS]}" -eq "0" ]; then
    			$TRANSMISSION_REMOTE --no-downlimit
    			$LOG_ENABLED && ${LOGGER} "initial download limit set to unlimited."
    		else
    			$TRANSMISSION_REMOTE --downlimit ${SCHEDULE_DOWNLOAD[NOW_HOURS]}
    			$LOG_ENABLED && ${LOGGER} "initial download limit set to ${SCHEDULE_DOWNLOAD[NOW_HOURS]} KiB/s."
    		fi
    		LAST_SCHEDULE_DOWNLOAD=$NOW_HOURS
    	fi
    	NOW_HOURS=`date +%k`;
    	while [[ -z ${SCHEDULE_UPLOAD[NOW_HOURS]} ]]; do
            	NOW_HOURS=$(($NOW_HOURS-1)) ;
    	        if [ "${NOW_HOURS}" -lt "0" ]; then
    			NOW_HOURS=0
            	       break
    	        fi
    	done
    	if [ ! -z ${SCHEDULE_UPLOAD[NOW_HOURS]} ]; then
            	if [ "${SCHEDULE_UPLOAD[NOW_HOURS]}" -eq "0" ]; then
    	              $TRANSMISSION_REMOTE --no-uplimit
    			$LOG_ENABLED && ${LOGGER} "initial upload limit set to unlimited."
            	else
    	              $TRANSMISSION_REMOTE --uplimit ${SCHEDULE_UPLOAD[NOW_HOURS]}
    			$LOG_ENABLED && ${LOGGER} "initial upload limit set to ${SCHEDULE_UPLOAD[NOW_HOURS]} KiB/s."
    	        fi
    	        LAST_SCHEDULE_UPLOAD=$NOW_HOURS
    	fi
    }
    
    # function to extract the downloading file name from the given line
    #get-torrent-filename() { echo `echo $1 | awk 'BEGIN {FS=" [\(][0-9\.]+ [MGKT]iB[\)]"};{print $1}' 2>/dev/null`; }
    get-torrent-filename() { echo `echo $1 | awk 'BEGIN{FS="(Downloading|Stopped|Seeding)[ ]+"};{print $NF}' 2>/dev/null`; }
    
    # function to extract the number for a given line
    get-torrent-number() { echo `echo $1 | awk '{ print $1; }'`; }
    
    # function to extract seeding ratio from the given line
    get-seeding-ratio() { echo `echo $1 | awk '{ print $6; }'`; }
    
    # function to get a real line count for a set of lines
    get-linecount() {
    	wclc=`echo "$1" | wc -l`
    	if [ "$wclc" -eq "1" ]; then
    		wcll=`echo "$1" | wc -L`
    		if [ "$wcll" -eq "0" ]; then
    			wclc=0
    		fi
    	fi
    	echo $wclc
    	return
    }
    # function to get lists of torrents with different statuses
    get-torrent-lists() {
           TORRENT_LIST=`$TRANSMISSION_REMOTE -l`;
    	
    	RUNNING_TORRENTS_LIST=`echo "$TORRENT_LIST" | grep Downloading`
    	STOPPED_TORRENTS_LIST=`echo "$TORRENT_LIST" | grep Stopped | grep -v 100%`
    	SEEDING_TORRENTS_LIST=`echo "$TORRENT_LIST" | grep 100%`
    
    	ALL_TORRENTS_COUNT=$((`get-linecount "$TORRENT_LIST"`-1));
    	RUNNING_TORRENTS_COUNT=`get-linecount "$RUNNING_TORRENTS_LIST"`
    	STOPPED_TORRENTS_COUNT=`get-linecount "$STOPPED_TORRENTS_LIST"`
    	SEEDING_TORRENTS_COUNT=`get-linecount "$SEEDING_TORRENTS_LIST"`
    }
    
    
    TRANSMISSION_IS_RUNNING=`ps -A | grep transmission-d | wc -l` ;
    if [ "$TRANSMISSION_IS_RUNNING" -gt "0" ]; then
    	find-previous-schedules ;
    fi
    
    # repeat loop forever
    while [[ 1 ]]; do
    	# check if transmission is running
    	TRANSMISSION_IS_RUNNING=`ps -A | grep transmission-d | wc -l`
    
            # check the watch directory for new torrents
            if [ -d $WATCHDIR ]; then
                    for TORRENTFILE in $WATCHDIR/*.torrent
                    do
                            if [ "$TORRENTFILE" != "$WATCHDIR/*.torrent" ]; then
    
                                    if [ "$TRANSMISSION_IS_RUNNING" -eq "0" ]; then
                                            $LOG_ENABLED && ${LOGGER} "transmission was not running; starting..."
                                            $TRANSMISSION_START ;
                                            TRANSMISSION_IS_RUNNING=1 ;
                                            find-previous-schedules ;
                                    fi
    
                                    # add found .torrents to queue
                                    $LOG_ENABLED && ${LOGGER} "$TORRENTFILE added to queue."
                                    $TRANSMISSION_REMOTE -a "$TORRENTFILE" ;
    
                                    #
                                    rm "$TORRENTFILE" ;
                                    sleep 2 ;
                            fi
                    done
            fi
    
    	if [ "$TRANSMISSION_IS_RUNNING" -gt "0" ]; then
    		# check bandwidth scheduling rules
    		NOW_HOURS=`date +%k`;
    		if [ "$LAST_SCHEDULE_DOWNLOAD" -ne "$NOW_HOURS" ]; then
    			if [ ! -z ${SCHEDULE_DOWNLOAD[NOW_HOURS]} ]; then
    				if [ "${SCHEDULE_DOWNLOAD[NOW_HOURS]}" -eq "0" ]; then
    					$TRANSMISSION_REMOTE --no-downlimit
    					$LOG_ENABLED && ${LOGGER} "download limit set to unlimited"
    				else
    					$TRANSMISSION_REMOTE --downlimit ${SCHEDULE_DOWNLOAD[NOW_HOURS]}
    					$LOG_ENABLED && ${LOGGER} "download limit set to ${SCHEDULE_DOWNLOAD[NOW_HOURS]} KiB/s"
    				fi
    				LAST_SCHEDULE_DOWNLOAD=$NOW_HOURS
    			fi	
    		fi 	
            	if [ "$LAST_SCHEDULE_UPLOAD" -ne "$NOW_HOURS" ]; then
    	                if [ ! -z ${SCHEDULE_UPLOAD[NOW_HOURS]} ]; then
            	                if [ "${SCHEDULE_UPLOAD[NOW_HOURS]}" -eq "0" ]; then
                    	              $TRANSMISSION_REMOTE --no-uplimit
                            		$LOG_ENABLED && ${LOGGER} "upload limit set to unlimited"
    				else
            	                     $TRANSMISSION_REMOTE --uplimit ${SCHEDULE_UPLOAD[NOW_HOURS]}
                    	        	$LOG_ENABLED && ${LOGGER} "upload limit set to ${SCHEDULE_UPLOAD[NOW_HOURS]} KiB/s"
    				fi                        
    				LAST_SCHEDULE_UPLOAD=$NOW_HOURS
                    	fi
    	        fi
    		
    		get-torrent-lists
    
    		# check completed downloads
    		if [[ "$REMOVE_COMPLETED" -eq "1" && "$SEEDING_TORRENTS_COUNT" -gt "0" ]] ; then
    			echo "$SEEDING_TORRENTS_LIST" | while read SEEDING_ROW; do
    				if [ ! -z "$SEEDING_ROW" ]; then
    					# get filename and hash for the torrent
    					SEEDING_FILENAME=`get-torrent-filename "$SEEDING_ROW"`
    					SEEDING_NUMBER=`get-torrent-number "$SEEDING_ROW"`
    					SEEDING_RATIO=`get-seeding-ratio "$SEEDING_ROW"`
    					
    					SEEDED_ENOUGH=`echo $SEEDING_RATIO | awk '{if($1>='$SEED_UNTIL_RATIO'){print "1"}else{print "0"}}' 2> /dev/null`
    					
    					if [ "$SEEDED_ENOUGH" -eq "1" ]; then
    
    						# remove the torrent
    						$TRANSMISSION_REMOTE -t $SEEDING_NUMBER -r
    						$LOG_ENABLED && ${LOGGER} "$SEEDING_FILENAME completed and removed from queue (seeded to ratio $SEEDING_RATIO)."
    
    						if [ -d $COMPLETEDIR ] ; then
    							# set the files' ownership so they can be accessed through samba
    							chown -R www-data:www-data "$WORKDIR/$SEEDING_FILENAME" 2> /dev/null
    
    							# move the files to the incoming directory
    							# moving files around can be really slow, if the source and destination are on different disks
    							# so we'll rename the file for the duration of the moving in order to know when it is completd
    							mv "$WORKDIR/${SEEDING_FILENAME}" "$COMPLETEDIR/${SEEDING_FILENAME}.moving"
    							mv "$COMPLETEDIR/${SEEDING_FILENAME}.moving" "$COMPLETEDIR/${SEEDING_FILENAME}"
    						fi
    
    						# sleep a little between
    						sleep 2
    					fi
    				fi
    			done
    			get-torrent-lists
    		fi
    
    		# check if there are any torrents in the queue and quit transmission for the time being if there aren't
    		if [[ "$QUIT_TRANSMISSION_WHEN_INACTIVE" -eq "1" && "$ALL_TORRENTS_COUNT" -eq "0" ]]; then
    			$LOG_ENABLED && ${LOGGER} "no torrents in the queue, exiting transmission for now..."
    			$TRANSMISSION_STOP ;
    		else
    
    			# check that the maximum number or simultaneous downloads is obeyed
    			if [[ "$RUNNING_TORRENTS_COUNT" -lt "$MAX_SIMULTANEOUS" && "$STOPPED_TORRENTS_COUNT" -gt "0" ]]; then
    				while [[ "$RUNNING_TORRENTS_COUNT" -lt "$MAX_SIMULTANEOUS" && "$STOPPED_TORRENTS_COUNT" -gt "0" ]]; do
    					STOPPED_ROW=`echo "$STOPPED_TORRENTS_LIST" | grep -m 1 ""`
    					STOPPED_FILENAME=`get-torrent-filename "$STOPPED_ROW"`
    					STOPPED_NUMBER=`get-torrent-number "$STOPPED_ROW"`
    					$TRANSMISSION_REMOTE -t $STOPPED_NUMBER --start 
    					$LOG_ENABLED && ${LOGGER} "$STOPPED_FILENAME started in order to have $MAX_SIMULTANEOUS simultaneous downloads."
    					get-torrent-lists
    				done
    			else
    
    				if [[ "$RUNNING_TORRENTS_COUNT" -gt "$MAX_SIMULTANEOUS" ]]; then
    					while [ "$RUNNING_TORRENTS_COUNT" -gt "$MAX_SIMULTANEOUS" ]; do
    						# try to find a stalled torrent first
    						RUNNING_ROW=`echo "$TORRENT_LIST" | grep -m 1 Stalled`
    						if [ -z "$RUNNING_ROW" ]; then
    							# couldn't find a stalled one, just stop the first in the list
    							RUNNING_ROW=`echo "$RUNNING_TORRENTS_LIST" | grep -m 1 ""`
    						fi
    						RUNNING_FILENAME=`get-torrent-filename "$RUNNING_ROW"`
    						RUNNING_NUMBER=`get-torrent-number "$RUNNING_ROW"`
    						$TRANSMISSION_REMOTE -t $RUNNING_NUMBER --stop
    						$LOG_ENABLED && ${LOGGER} "${RUNNING_FILENAME} stopped in order to have ${MAX_SIMULTANEOUS} simultaneous downloads."
    						get-torrent-lists
    					done
    		        	fi
    			fi
    		fi
    
    
    
    	fi
    
    	# wait FREQUENCY seconds before doing everything again
    	sleep $FREQUENCY ;
    done
    exit 0
    

    The script supports only transmission versions newer than 1.30. For the old version of the script, download
    http://kyyhkynen.net/stuff/mybook/torrent_helper.old and rename it into torrent_helper.

    You can either copy-and-paste the script into any place you want (I have it in /usr/sbin/torrent_helper) or download it directly like this:

    # wget http://kyyhkynen.net/stuff/mybook/torrent_helper
    # mv torrent_helper /usr/sbin

    Again, make sure that the script is executable;

    # chmod a+x /usr/sbin/torrent_helper
  3. Check the configuration section of the helper script. Make the WORKDIR variable point to the same directory with the variable in the /etc/init.d/transmission.sh script.

     

    WATCHDIR and COMPLETEDIR should be some place easily accessible (that is, on a samba share) and on a drive with enough free space for the downloads.

    As you can see, I have put all the directories in the default public share under a directory named Torrent.

    Note that the MBWE doesn't have much memory, so you probably don't want to be downloading lots of stuff simultaneously with it...

    The MAX_SIMULTANEOUS setting is used in keeping only that many torrents downloading simultaneously. Of course you're free to experiment with it, but I suggest you'll leave it set to 1.

     

    What the helper script does, is that it checks the WATCHDIR every FREQUENCY seconds for .torrent files and adds them into the download queue. If REMOVE_COMPLETED is set to 1, it also checks if there are completed downloads, removes them from the queue if they are seeded to the ratio defined by SEED_UNTIL_RATIO and moves the downloaded files to the COMPLETEDIR if you have provided one.

     

    The script also enables simple hour-based bandwidth scheduling rules, so you can do your serious downloading during night and keep your lines uncluttered during day. See the configuration section of the script for further information on setting the limits.

     

    After you have set up the script, test it with

    # /usr/sbin/torrent_helper

    If you don't get any errors the script should be working just fine. Stop it by pressing CTRL+C.

    Next let's make starting and stopping the script more easy.

  4. I have put together a startup/shutdown script to make starting and stopping the script in the background easy:

    #! /bin/sh
    #
    # torrent_helper.sh
    # startup/shutdown script for the Transmission Helper script on MBWE
    # written by kyyhkynen at gmail dot com
    # see http://kyyhkynen.net/stuff/mybook for further info
    #
    # you may use and modify this script any way you want as long as you keep this header attached
    # last modified May 19th, 2008
    ################
    # Configuration
    ################
    
    PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/bin/
    
    # set path to the torrent helper script (see the guide @ http://kyyhkynen.net/stuff/mybook)
    HELPER=/usr/sbin/torrent_helper
    
    # the file to keep the helper script process id
    # i'm keeping mine on my ram disk, you can change this path to whatever suits your needs
    HELPER_PID=/var/run/torrent_helper.pid
    
    # see the torrent_helper script for further configuration options
    
    ##############################################
    # end of configuration
    # you shouldn't need to edit anything below this
    
    NAME="Torrent Helper Script"
    
    test -x $DAEMON || exit 0
    
    start() {
            echo -e "Starting $NAME\r"
    
            # start the helper, if it exists and is not running
            if [[ -f "$HELPER" && ! -f "$HELPER_PID" ]]; then
                    start-stop-daemon --start --background --quiet \
                            --pidfile $HELPER_PID --make-pidfile \
                            --exec $HELPER
            fi
    }
    
    stop() {
            echo -e "Stopping $NAME\r"
            if [[ -f "$HELPER" && -f "$HELPER_PID" ]]; then
                    start-stop-daemon --stop --quiet --pidfile $HELPER_PID
    		rm "$HELPER_PID"
            fi
    }
    
    case "$1" in
    	start)
    		start
    		;;
    	stop)
    		stop
    		;;
    	restart)
    		stop
    		start
    		;;
    esac
    
    exit 0
    

    You can either copy-and-paste it into /etc/init.d/torrent_helper.sh or download it directly like this:

    # wget http://kyyhkynen.net/stuff/mybook/torrent_helper_start_stop.sh
    # mv torrent_helper_start_stop.sh /etc/init.d/torrent_helper.sh

    Just make sure the script is executable:

    # chmod a+x /etc/init.d/torrent_helper.sh

     

    Edit the file and check the paths.

     

    Now, with this script you can easily start and stop the actual torrent_helper script with

    # /etc/init.d/torrent_helper.sh start

    and

    # /etc/init.d/torrent_helper.sh stop

    You can start the script now and leave it running in the background.

     

    In order to make the torrent_helper script start and stop during startup and shutdown, add the appropiate commands to /etc/init.d/post_network_start.sh, like this:

    start() {
            if [ ! -e "$POST_NETWORK_STARTED_FILE" ]
            then
                    $SCRIPTS_PATH/crond.sh start
                    # $SCRIPTS_PATH/mionet.sh start
                    $SCRIPTS_PATH/transmission.sh start
                    $SCRIPTS_PATH/torrent_helper.sh start
                    touch $POST_NETWORK_STARTED_FILE
            fi
    }
    
    stop() {
            if [ -e "$POST_NETWORK_STARTED_FILE" ]
            then
                    # $SCRIPTS_PATH/mionet.sh stop
                    $SCRIPTS_PATH/transmission.sh stop
                    $SCRIPTS_PATH/torrent_helper.sh stop
                    $SCRIPTS_PATH/crond.sh stop
                    rm $POST_NETWORK_STARTED_FILE
            fi
    }
    

  5. Congratulations, you have working transmission torrent client with watchdir and bandwidth scheduling.

     

    Now to download stuff, you'll just have to drop a .torrent file in your watch directory and it will be automagically downloaded and moved to your completed download directory after it has been downloaded and seeded to the ratio you have defined.

    In order to be able to follow the progress of the downloads and to control the downloads manually from your web browser, see Installing Clutch.

     

    In the next remaining steps, we'll make your MBWE download .torrents automatically from RSS feeds.

  6. You can now download stuff with your MBWE quite simply, but wouldn't it be convenient to make it download for example all those TV shows automatically?

    Luckily, this problem has been addressed pretty well. We'll just need a way to follow RSS feeds and download the appropiate TV show torrents to our watch directory.

    A perfectly working shell script for achieving this can be found here. (thanks for the author)

    There other options also, but you'll have to test them on your own.

    Note: TV show torrents are extremely popular, and the most popular shows (like Lost) might have tens of thousands concurrent peers.
    Torrents with a large number of peers seem to make transmission sometimes very cpu-hungry thus slowing down your MBWE to a crawl and making the downloads very slow.
    I'm not telling not to use transmission on popular torrents, but just be aware that if your downloads seem to take forever to finish and your MBWE feels sluggish, this might be the cause...

     

    Copy-and-paste the script from above link and place it somewhere on your MBWE.

    I have it in /usr/sbin/rss_downloader.

    Make sure the script is executable.

    # chmod a+x /usr/sbin/rss_downloader

     

    Now, the script is using XMLStarlet to parse the downloaded RSS feeds. You can try to build that from the source on your MBWE, if you have a c complier (that is, if you're still running a firmware older than 2.00.15).

    Or, you can use the Perl module XML::XMLPath to do the same thing. The Perl version is a lot slower, but it works just as well. Also, you don't need the c compiler to install it.

     

    If you choose (or are forced) to use the Perl version, you can skip the next step.

  7. First, the xmlstarlet version:

    In order to compile xmlstarlet, you'll need libxml2, libxslt and libiconv. You may have some of these, or not. You can compile them also from source code, or you can just use optware, as I did.

    # ipkg install libxml2 libxslt libiconv

    If you want to build them from source, then you're on your own :)

     

    Download and decompress xmlstarlet source:

    # cd /tmp
    # wget http://xmlstar.sourceforge.net/downloads/xmlstarlet-1.0.1.tar.gz
    # tar xvfz xmlstarlet-1.0.1.tar.gz
    # cd xmlstarlet-1.0.1

     

    Next, since the optware versions of the libraries don't seem to come with the static versions, we'll edit the configure script to use the shared versions instead. If someone can tell me why this would be a bad idea, drop me a note :)

    If you were brave and built the libraries yourself, you probably won't need to edit the configurescript.

    # sed 's/\.a/\.so/g' configure > configure.edited
    # mv configure.edited configure

    Now let's build the thing. I'm not sure if you'll need all those options (if you build the libraries yourself, you probably don't), but they are what I got it built with.

    # ./configure --with-libxml-prefix=/opt --with-libxml-libs-prefix=/opt/lib --with-libxml-include-prefix=/opt/include --with-libxslt-prefix=/opt
    # make
    # make check
    # make install

    If you didn't get any fatal-looking errors, xmlstarlet should be now installed and working. You can test it with

    # xml

    Which should give you it's usage information.

     

    Now you can clean up the mess:

    # cd /tmp
    # rm -rf xmlstarlet*

     

    Next edit the rss downloader script and find the following line (should be line number 59 if you haven't made any modifications of your own in the script):

    currenturlstring=$(xmlstarlet sel -t -m "/rss/channel/item/link" -v "concat(.,' ')" "$tmpxml" 2> /dev/null)

    And change the name of the xmlstarlet executable into xml like this:

    currenturlstring=$(xml sel -t -m "/rss/channel/item/link" -v "concat(.,' ')" "$tmpxml" 2> /dev/null)

    You're done here. You can skip the next step, unless you want to install the Perl alternative too.

  8. Now the Perl version:

    Installing may seem complicated, but it really isn't. We'll just install first expat from optware since it is required by the module, and then install two Perl modules. There might be some dependencies I have installed some other time, so if you run into one, let me know.

    Here we go (note that the latest versions of the modules might have changed, the ones used below were the latest as of writing - you can check for newer versions in CPAN):

    # ipkg install expat
    # cd /tmp
    # wget perl http://search.cpan.org/CPAN/authors/id/M/MS/MSERGEANT/XML-Parser-2.36.tar.gz
    # wget perl http://search.cpan.org/CPAN/authors/id/M/MS/MSERGEANT/XML-XPath-1.13.tar.gz
    # tar xvfz XML-Parser-2.36.tar.gz
    # tar xvfz XML-XPath-1.13.tar.gz
    # cd XML-Parser-2.36
    # perl Makefile.pl EXPATLIBPATH=/opt/lib/ EXPATINCPATH=/opt/
    # make
    # make test
    # make install
    # cd ..
    # cd XML-XPath-1.13
    # perl Makefile.PL
    # make
    # make test
    # make install
    # cd ..
    # rm -rf XML-Parser-2.36* XML-XPath-1.13*

    Phew, done.

     

    Next find the following line with xmlstartlet in the script (it should be line number 59 if you haven't made any other modifications):

    currenturlstring=$(xmlstarlet sel -t -m "/rss/channel/item/link" -v "concat(.,' ')" "$tmpxml" 2> /dev/null)

    Comment it out (or just delete it) and add a line doing the same thing using xpath command, which was installed along with the perl module, so the script looks like this:

    #currenturlstring=$(xmlstarlet sel -t -m "/rss/channel/item/link" -v "concat(.,' ')" "$tmpxml" 2> /dev/null)
    currenturlstring=$(xpath -p "$tmpxml" "//rss/channel/item/link/text()[string-length(normalize-space(.)) > 0 ]" 2>/dev/null | sed -e 's/http/ http/g')

     

  9. Now, edit the configuration in the beginning of the script. Set tvrssdir to someplace convenient for you, might as well let it be the default one. Set watchdir to your transmission watch directory (created in the previous part of this guide).

     

    Next you'll have to set up some feeds for the script. Go to the tvrssdir you just set up and create a file named something like LateNightWithConanOBrien containing the feed url for the torrents of the show. You can use the tvRSS search to create feeds for individual shows. Just search with the show name and click "Search-based RSS Feed" in the top of the search results. You'll most likely end up with an url like this: http://tvrss.net/search/index.php?distribution_group=combined&show_name=Conan+O+Brien&release_group=&mode=rss.

    Like this:

    # cd /your/tvrss/dir
    # echo "url-of-your-feed" > NameOfTheShow

    You'll need a separate file for every tv show you'll want to follow.

    Note: The RSS downloader script works just fine with feeds containing something else than TV shows - as long as they are in the same format as the tvRSS feeds...

     

    Now test the script. You might want to stop transmission before doing that, unless you want to be downloading all the old shows in the feed. So, like this:

    # /etc/init.d/transmission.sh stop
    # /usr/sbin/rss_downloader

    If you get no errors, you can now stop the script by pressing CTRL+C.

    Check your transmission watch directory. It should contain a bunch of .torrent files for the tv show. You can remove them, unless you'll want to download a bunch of old episodes.

    Also remember to restart transmission if you stopped it.

     

    That is it, basically. It is up to you how you'll run the script.

     

    You can start it as a background daemon with start-stop-daemon (see for example the /etc/init.d/transmission.sh script starting the torrent_helper), or you can run it in a screen as the creator initially has meant.

     

    You can also strip the endless while loop and the sleep command from the script and set it to run as a cron job. I have set it up this way, and the cron job is run only on those days I know there might be new episodes.

     

    If someone has some spare time, it would be nice if the script could figure out (using the feeds' timestamps) when the episodes for each show are usually released and set the cron job accordingly.

  10. Now, if you did everything successfully, you have now a BitTorrent box that does your downloads conveniently without the need of keeping a desktop machine running for downloads.

    Just drop .torrent files in your watch directory and they will be downloaded automatically.

    Or add some RSS feeds and just let the whole process happen automatically :)

     

    Only one step left, installing a graphical user interface for transmission.

    Continue to Installing Clutch, the web GUI for Transmission