lørdag 27. februar 2010

rTorrent Queuing system.

I've created a python script (my very first python project) for handling some simple queuing functinality for rTorrent. When rTorrent is used in conjunction with a rss aggregator you could risk getting too many active torrents which creates overhead in the form of memory, file locks and cpu. The script limits the concurrent active torrents and downloading torrents based on a limit defined in the script config and the creation date of the torrent so that the oldest torrents are removed if any of the limits kicks in.

#!/usr/bin/env python
'''
Created on 27. feb. 2010
@author: Kim Eik
'''

#################################################
#    CONFIG
#################################################

CONNECT_URI = "scgi://localhost:5000"
MAX_LEECHING = 2
MAX_SEEDING = 15

#################################################
#    IMPORT
#################################################

import datetime
from xmlrpc2scgi import do_scgi_xmlrpc_request_py

#################################################
# CLASSES
#################################################

class Torrent:
    def __init__(self, hash):
        self._hash = hash
    def getHash(self):
        return self._hash
    def isStarted(self):
        return self._started;
    def setStarted(self,started):
        self._started = started
    def setCreationDate(self,date):
        self._creationDate = date
    def getCreationDate(self):
        return self._creationDate
    def setCompleted(self, completed):
        self._completed = completed
    def isCompleted(self):
        return self._completed
    def __repr__(self):
        return ("<Torrent %s>" % (self.getHash()))
    def __str__(self):
        return self._hash
        

################################################
#    LOGIC
################################################

torrents = []
rawTorrents = do_scgi_xmlrpc_request_py(CONNECT_URI, "d.multicall", ("","d.get_hash=", "d.get_state=", "d.get_creation_date=","d.get_complete="))
for x,rawTorrent in enumerate(rawTorrents):
    torrent = Torrent(rawTorrent[0])
    torrent.setStarted(rawTorrent[1])
    torrent.setCreationDate(datetime.datetime.fromtimestamp(rawTorrent[2]))
    torrent.setCompleted(rawTorrent[3])
    torrents.append(torrent)
    
downloading = []
started = []
queued = []

for x,torrent in enumerate(torrents):
    if(torrent.isStarted()):
        if(not torrent.isCompleted()):
            downloading.append(torrent)
        else:
            started.append(torrent)
    else:
        if(not torrent.isCompleted()):
            queued.append(torrent)

downloading.sort(key=lambda obj: obj.getCreationDate())
started.sort(key=lambda obj: obj.getCreationDate())
queued.sort(key=lambda obj: obj.getCreationDate())

while(len(downloading) < MAX_LEECHING and len(queued) > 0):
    torrent = queued.pop(0)
    do_scgi_xmlrpc_request_py(CONNECT_URI,"d.open",(torrent.getHash(),''))
    do_scgi_xmlrpc_request_py(CONNECT_URI,"d.start",(torrent.getHash(),''))    
    downloading.append(torrent)
    print 'starting torrent: ' + torrent.getHash()
    
while(len(downloading) > MAX_LEECHING):
    torrent = downloading.pop(0)
    do_scgi_xmlrpc_request_py(CONNECT_URI,"d.stop",(torrent.getHash(),''))
    do_scgi_xmlrpc_request_py(CONNECT_URI,"d.close",(torrent.getHash(),''))   
    print 'queueing torrent: ' + torrent.getHash()
    
while(len(started) > MAX_SEEDING):
    torrent = started.pop(0)
    do_scgi_xmlrpc_request_py(CONNECT_URI,"d.stop",(torrent.getHash(),''))
    do_scgi_xmlrpc_request_py(CONNECT_URI,"d.close",(torrent.getHash(),''))
    print 'stopping torrent: ' + torrent.getHash()
            
        


This script depends on another python script created by Glenn Washburn. xmlrpc2scgi.py which can be fetched from http://libtorrent.rakshasa.no/wiki/UtilsXmlrpc2scgi

You execute this script through a cron job, or through the rtorrent event handling system. Whatever suits your use the best. Good luck!

Ingen kommentarer:

Legg inn en kommentar