SOHO : Small Office Home Office
Freeware - Opensource software tips, tricks, tweaks & fixes for managing, securing, improving the performance of SOHO Desktop, Laptop, Networks

Thursday, April 5, 2012

rtorrent queue manager python script

The complete story...

*** RTorrent as a torrent download manager ***

RTorrent is a very powerful console based torrent client.
You can find pretty advanced documentation on
I wanted to use rtorrent as my only torrent download manager, for that I needed to able to:

1) configure the total number of concurrent active torrent downloads;
2) add a queue of torrents to be automatically downloaded as soon as possible, provided the total number of active downloads before;
3) move the downloaded files to another directory and delete any related torrent;
4) limit the total amount of upload and download bandwidth not to choke my adsl connection.

while rtorrent provides built-in capabilities to accomplish 3) and 4), it doesn't provide a direct method to accomplish the first two points.
Fortunately rtorrent is able to watch a directory for torrents, meaning that automatically downloads any torrent added to that directory and automatically cancels any download related to a torrent that has been deleted from that directory.
I used this capability together with a little external script to solve 1) and 2).

First of all I created the following directory structure under /path (substitute /path with whatever you want):


loading contains the queued torrents;
session contains all the torrents rtorrent is downloading, this directory is managed by rtorrent and rtorrent only;
temp contains the uncompleted downloads, again this directory is managed my rtorrent;
completed contains all the completed downloads.

Then I configured rtorrent as follows:

--- .rtorrent.rc ---

directory = /path/temp
session = /path/session

schedule = watch_directory,10,10,load_start=/path/watch/*.torrent
schedule = untied_directory,5,5,"remove_untied="
schedule = low_diskspace,60,60,"close_low_diskspace=500M"

on_finished = rm_torrent,"execute=rm,$d.get_tied_to_file="
on_finished = move_complete,"execute=mv,-u,$d.get_base_path=,/path/completed/ ;d.set_directory=/path/

upload_rate = 15
download_rate = 50

port_range = 6881-6889

--- .rtorrent.rc ---

Save this as .rtorrent.rc in your home directory.
directory specifies the temporary downloads directory;
session specifies where to put the torrents related to the active downloads;
upload_rate is for limiting the upload bandwidth;
download_rate is for limiting the download bandwidth;
I also specified the port_range for compatibility with the other torrent clients.
The other options are more difficult to understand:
the first two schedule commands are to configure a watch directory as described above, the third is to stop any download when the disk is full.
The two on_finished commands are to move all the finished downloads to the completed directory and to delete their torrents from the watch directory too.

These configurations alone accomplish 3) and 4), but we are not finished yet with 1) and 2):
we need a script to move torrents from the loading directory to the watch directory, so that the total number of concurrent downloads is lower or equal to the specified value. As a consequence there must be no more than that number of torrents in the watch directory.
When a torrent download is completed, it is removed from the session and the watch directories; the script can recognise this event and move another torrent to the watch directory and so on.
I wrote this script in Python:

--- ---

#!/usr/bin/env python

# Now you can dynamically change the maximum number of simultaneous
# downloads writing the new number to the file "max_downloads_file" and
# then sending a signal SIGHUP to the rtorrentqueuemanager process.

import glob
import stat
import os
import shutil
import time
import signal

watch = "/share/storage/rtorrent/watch"
session = "/share/storage/rtorrent/session"
queue = "/share/storage/rtorrent/loading"
max_downloads_file = "/share/storage/rtorrent/max_downloads"
max_downloads = 2

def handler_sighup(signum, frame):
    f = open(max_downloads_file, "r")
    max_downloads = int(f.readline())

#### START
signal.signal(signal.SIGHUP, handler_sighup)
while True:
    bz2files = glob.glob(queue + "/*.torrent.bz2")
    for i in bz2files :
        os.system('bzip2 -d ' + i)
    gzipfiles = glob.glob(queue + "/*.torrent.gz")
    for i in gzipfiles :
        os.system('gunzip ' + i)
    sfiles = glob.glob(session + "/*.torrent")
    oldesttime = 0
    oldestfile = ""
    if len(sfiles) < max_downloads :
        qfiles = glob.glob(queue + "/*.torrent")
        for i in qfiles :
            ftime = os.stat(i)[stat.ST_MTIME]
            if oldesttime == 0 or ftime < oldesttime :
                oldesttime = ftime
                oldestfile = i
        if oldestfile != "" :
            shutil.move(oldestfile, watch)

--- ---

save it as
Now you can start rtorrent with the screen utility:

screen rtorrent

detach the screen pressing Ctrl-A-D.
Then start the script:

python &

From now on you can copy any torrent you want to download to the loading directory and rtorrent plus this script will take care of the rest!

Thanks to Jari Sundell for this great peace of software and to Shaun Dennie for giving me the idea of the queue manager script.

Stefano Stabellini

Credit & Source :

No comments:

Post a Comment