Script to add torrent and change tracker with Python

Suggest, post, or discuss plugins for Deluge
Post Reply
witwolf
New User
New User
Posts: 4
Joined: Sat Jan 08, 2011 11:34 am

Script to add torrent and change tracker with Python

Post by witwolf »

Hi,

I am a complete noob with python as well as with the UI of deluge. I am trying to create a script in Python which could be called in the command line by a bash script to add a created torrent file and then change the tracker to another entry. I have started to play with the script but are unable to continue due to my lack of knowledge of python and deluge.

This is what I have done so far.

Code: Select all

#!/usr/bin/env python
# Import the client module
from deluge.ui.client import client
# Import the reactor module from Twisted - this is for our mainloop
from twisted.internet import reactor
import sys
import base64
import os

#Set variables
filetest = sys.argv[1]
print filetest
title = 'Test'
opts = {}
opts['download_location'] = '/mnt/raid5/Media/'
tracker = [ 'http://example.com/announce.php', '0']

# Connect to a daemon running on the localhost
# We get a Deferred object from this method and we use this to know if and when
# the connection succeeded or failed.
d = client.connect(host='127.0.0.1',port=58846,username='deluge',password='deluge')

# We create a callback function to be called upon a successful connection
def on_connect_success(result):
    print "Connection was successful!"
    print "result:", result
    # Disconnect from the daemon once we successfully connect
    
    
    file = sys.argv[1]
    if not os.path.exists(file):
        print 'file does not exist'
    else:
        print 'file does exist'
    
    
    
    torrentid = client.core.add_torrent_file(title, file, opts)
    client.core.set_torrent_trackers(torrentid, tracker)
    print torrentid
    
    
    client.disconnect()
    # Stop the twisted main loop and exit
    reactor.stop()

# We add the callback to the Deferred object we got from connect()
d.addCallback(on_connect_success)

# We create another callback function to be called when an error is encountered
def on_connect_fail(result):
    print "Connection failed!"
    print "result:", result

# We add the callback (in this case it's an errback, for error)
d.addErrback(on_connect_fail)

# Run the twisted main loop to make everything go
reactor.run()
Would anyone be able to help me getting the command right to submit the torrent file?
witwolf
New User
New User
Posts: 4
Joined: Sat Jan 08, 2011 11:34 am

Re: Script to add torrent and change tracker with Python

Post by witwolf »

I now have the following.

Code: Select all

path = "/home/test/test.torrent"
opts = {}
opts['download_location'] = "/home/test/"

f = open(path, 'rb')
filedump = base64.encodestring(f.read())
f.close()

filename = os.path.basename(path)

addresult = client.core.add_torrent_file(filename, filedump, opts)
print addresult
With this nothing get added and and I get the following back from the terminal:

Code: Select all

<Deferred at 0x15cfd40>
Not sure what is wrong. Could it be that I don't have all the options set?
gazpachoking
Moderator
Moderator
Posts: 315
Joined: Sat Aug 18, 2007 2:28 pm
Location: Pittsburgh, USA

Re: Script to add torrent and change tracker with Python

Post by gazpachoking »

You could use FlexGet for this purpose, if you make a config like:

Code: Select all

feeds:
  mytracker:
    accept_all: yes
    remove_trackers:
      - .
    add_trackers:
      - http://mytracker.org/announce
    deluge: yes
This would remove all trackers and add your desired tracker to the torrent before sending it to deluge. You could then use --inject to run FlexGet like:

Code: Select all

flexget --feed mytracker --inject "Fake Title" "http://place.the.url/to/the/torrent.here"
whenever you want to add a torrent to deluge.

Might not be the optimal solution, but may be easier than writing your own script. If you want to get your script working, maybe you should look here to see how to use the Deferred model.
Last edited by gazpachoking on Sun Jan 09, 2011 9:25 pm, edited 1 time in total.
witwolf
New User
New User
Posts: 4
Joined: Sat Jan 08, 2011 11:34 am

Re: Script to add torrent and change tracker with Python

Post by witwolf »

Thank you for your reply gazpachoking.

I had a look into the flexget solution. Although it is much simpler to do it this way I am unable to instruct it where to download the files on a torrent to torrent basis.

My work flow is as follows:

TV series get added by sickbeard to SABNZBD. This downloads them and on completion it runs a script with sickbeard which renames the files and put them in their appropriate directories. The directory structure is something like this Series/Season/SeasonFiles. After the sickbeard script finish, it runs another script that create a torrent file of that new file. It will then upload it to a torrent tracker. Since this tracker requires you to have a passkey in the tracker URL of the torrent, we need to change the tracker in the torrent before or after we add it to deluge. The script would now have to add it to deluge, make sure its download location is the same as the file, and then change the tracker to the tracker with the passkey.

Flexget would have worked perfectly if I could set the download location on a file to file basis.

Is there not another simple solution of doing this?
witwolf
New User
New User
Posts: 4
Joined: Sat Jan 08, 2011 11:34 am

Re: Script to add torrent and change tracker with Python

Post by witwolf »

Flexget would have worked perfectly if I could set the download location on a file to file basis.
Ok maybe I was wrong. CLI-CONFIG might be the solution.
godlike
New User
New User
Posts: 7
Joined: Tue Aug 03, 2010 11:46 pm

Re: Script to add torrent and change tracker with Python

Post by godlike »

I stumbled upon this while trying to toy around with deluge's RPC API. Which is not particularly well documented. And I am not particularly fond of. And I personally think that twisted sucks (on the other hand, I've been using Deluge for 5+ years and I personally think that Deluge rocks).

But anyway, the problem is that you have to add a callback for EVERY THING you are going to do when interacting with the server. EVERY function call that you perform that returns a Deferred object (which I think pretty much everything under deluge.ui.client.client does) MUST HAVE a callback (specified with Deferred.addCallback), wherein you can do something (or nothing at all). But if the callback is not specified with addCallback, given the asynchronic nature of twisted, the function in question will never get called.

I got the additional info I needed from here: http://dev.deluge-torrent.org/wiki/Deve ... iClient1.2

EDIT: as an example, here's what I did, based off your initial script:

Code: Select all

#!/usr/bin/env python
# Import the client module
from deluge.ui.client import client
# Import the reactor module from Twisted - this is for our mainloop
from twisted.internet import reactor
from deluge.log import setupLogger
setupLogger()

# This is a sample script to add a magnet link to a running instance of deluge

# Connect to a daemon running on the localhost
# We get a Deferred object from this method and we use this to know if and when
# the connection succeeded or failed.
d = client.connect(host='127.0.0.1',port=58846,username='yourusername',password='yourpassword')

# We create a callback function to be called upon a successful connection
def on_connect_success(result):
    print "Connection was successful!"
    print "result:", result
    # Disconnect from the daemon once we successfully connect
   
    def on_added_torrent(value, key):
        print "got something..."
        print "%s: %s" % (key, value)
        client.disconnect()
        reactor.stop()
   
   
    magnetlink = "a magnet link here, in the form of magnet:?*"
    client.core.add_torrent_magnet(magnetlink, {}).addCallback(on_added_torrent, magnetlink)
   
   
    #client.core.get_config_value("download_location").addCallback(on_get_config_value, "download_location")
    # Stop the twisted main loop and exit

# We add the callback to the Deferred object we got from connect()
d.addCallback(on_connect_success)

# We create another callback function to be called when an error is encountered
def on_connect_fail(result):
    print "Connection failed!"
    print "result:", result
    reactor.stop()

# We add the callback (in this case it's an errback, for error)
d.addErrback(on_connect_fail)

# Run the twisted main loop to make everything go
reactor.run()
Tested on a running deluge 1.3.6 instance, both client and server.

Cheers,
Post Reply