mlDonkey torrents plugin in development, help needed...
#1
This is my third day using python (so kindly excuse my poor code), but i wanted to have a plugin that can read the rss feeds off some torrent sites and allow me to add such torrents to my mlDonkey, so here it is (again i did not know where to upload the py file itself so i will just paste it here):
Code:
import xbmc, xbmcgui, xbmcplugin, urllib2, urllib, re, string, telnetlib
from xml.dom import minidom
from xml.dom.minidom import parse


def showRoot():
        ri=[
                ("BiteNova"),
                ("ExtraTorrent"),
                ("NewTorrents"),
                ("TorrentPortal"),
                ("BTJunkie"),
                ## ("AliveTorrents"),
                ("YourBitTorrent")
                ]
        ## add root list in xbmc gui
        for site in ri:
                li = xbmcgui.ListItem(site)
                u = sys.argv[0] + "?mode=0&site=" + urllib.quote_plus(site)
                xbmcplugin.addDirectoryItem(int(sys.argv[1]),u,li,True)
                
def showCats(site):
        if site == "BiteNova":
                ri=[
                        ("Movies", "http://bitenova.nl/rss/cat.4.xml"),
                        ("TV Series", "http://bitenova.nl/rss/cat.9.xml"),
                        ("Other", "http://bitenova.nl/rss/cat.6.xml")
                        ]
        elif site == "ExtraTorrent":
                ri=[
                        ("Movies", "http://extratorrent.com/rss.xml?type=popular&cid=4"),
                        ("TV Series", "http://extratorrent.com/rss.xml?type=popular&cid=8"),
                        ("Music", "http://extratorrent.com/rss.xml?type=popular&cid=5"),
#                ("Adult", "http://extratorrent.com/rss.xml?type=popular&cid=533")
                        ]
        elif site == "NewTorrents":
                ri=[
                        ("Movies", "http://www.newtorrents.info/rss2.php?cat=movies"),
                        ("TV Series", "http://www.newtorrents.info/rss2.php?cat=tv"),
                        ("Music", "http://www.newtorrents.info/rss2.php?cat=music")
                        ]
        elif site == "TorrentPortal":
                ri=[
                        ("Movies", "http://www.torrentportal.com/rssfeed.php?cat=2"),
                        ("TV Series", "http://www.torrentportal.com/rssfeed.php?cat=3"),
                        ("Music", "http://www.torrentportal.com/rssfeed.php?cat=7"),
                        ("Videos", "http://www.torrentportal.com/rssfeed.php?cat=4"),
                        ("Adult", "http://www.torrentportal.com/rssfeed.php?cat=10")
                        ]
        elif site == "BTJunkie":
                ri=[
                        ("Movies", "http://btjunkie.org/rss.xml?c=6"),
                        ("TV Series", "http://btjunkie.org/rss.xml?c=4"),
                        ("Music", "http://btjunkie.org/rss.xml?c=1"),
                        ("Unsorted", "http://btjunkie.org/rss.xml?c=5")
                        ]
        ## elif site == "AliveTorrents":
                ## ri=[
                        ## ("Movies", "http://www.alivetorrents.com/rss/cat/4"),
                        ## ("TV Series", "http://www.alivetorrents.com/rss/cat/8"),
                        ## ("Music", "http://www.alivetorrents.com/rss/cat/5"),
                        ## ("Other", "http://www.alivetorrents.com/rss/cat/9")
                        ## ]
        elif site == "YourBitTorrent":
                ri=[
                        ("Movies", "http://www.yourbittorrent.com/movies/rss.xml"),
                        ("TV Series", "http://www.yourbittorrent.com/television/rss.xml"),
                        ("Music", "http://www.yourbittorrent.com/music/rss.xml")
                        ]

            

        ## list site categories in xbmc gui
        for name, url in ri:
                li = xbmcgui.ListItem(name)
                u = sys.argv[0] + "?mode=1&name=" + urllib.quote_plus(name) + "&url=" + urllib.quote_plus(url) + "&site=" + urllib.quote_plus(site)
                xbmcplugin.addDirectoryItem(int(sys.argv[1]),u,li,True)



def showList(site, url):
        ## get rss feed
        usock = urllib2.urlopen(url)
        doc = minidom.parse(usock)
        usock.close()

        ##parse rss feed for torrents
        for node in doc.getElementsByTagNameNS('*', 'item'):
                name = node.getElementsByTagName('title')[0].firstChild.data
                ## the torrent url is different in some feeds
                if site == "ExtraTorrent":
                        link = node.getElementsByTagName('enclosure')[0].getAttribute('url')
                else:
                        link = node.getElementsByTagName('link')[0].firstChild.data

                ## list torrents in xbmc gui
                try:
                        li = xbmcgui.ListItem(name)
                        u = sys.argv[0] + "?mode=2&name=" + urllib.quote_plus(name) + "&url=" + urllib.quote_plus(link) + "&site=" + urllib.quote_plus(site)
                        xbmcplugin.addDirectoryItem(int(sys.argv[1]),u,li,True)
                except:
                        pass



def getTorrent(site, url, name):
        if site in ("BiteNova", "BTJunkie"):
                nsock = urllib2.urlopen(url)
                ndoc = nsock.read()
                nsock.close()
                
                if site == "BiteNova":
                        nmat = re.compile('<em><a href="(.+?)" title="Download this torrent">(.+?)</a></em>').findall(ndoc)
                        for t_link, t_name in nmat:
                            t_url = "http://www.bitenova.nl" + t_link
                elif site == "TorrentPortal":
                        nmat = re.compile('<a href="(.+?)"  ><font size=3><b>Download This Torrent<b></font></a>').findall(ndoc)
                        for t_link in nmat:
                            t_url = t_link
                elif site == "BTJunkie":
                        nmat = re.compile('<a href="(.+?)" rel="nofollow" class="blocked_black">Torrent Download</a>').findall(ndoc)
                        for t_link in nmat:
                            t_url = t_link
                            
                
                tn = telnetlib.Telnet(mldonkey_ip, mldonkey_port)
                tn.read_until("MLdonkey command-line:")
                tn.write("startbt " + t_url + "\n")
                tn.write("exit\n")
        elif site in ("ExtraTorrent", "YourBitTorrent"):
                urllib.urlretrieve(url, tor_dir + name + ".torrent")
        elif site == "NewTorrents":
                t_url = url.replace("http://www.newtorrents.info/torrent/","http://www.NewTorrents.info/down.php?id=")
                t_url = t_url.replace("/" + name + ".html", "")
                urllib.urlretrieve(t_url, tor_dir + name + ".torrent")


def get_params():
        param=[]
        paramstring=sys.argv[2]
        if len(paramstring)>=2:
                params=sys.argv[2]
                cleanedparams=params.replace('?','')
                if (params[len(params)-1]=='/'):
                        params=params[0:len(params)-2]
                pairsofparams=cleanedparams.split('&')
                param={}
                for i in range(len(pairsofparams)):
                        splitparams={}
                        splitparams=pairsofparams[i].split('=')
                        if (len(splitparams))==2:
                                param[splitparams[0]]=splitparams[1]
                                
        return param






## mldonkey server ip & port
mldonkey_ip = "127.0.0.1"
mldonkey_port = 4000

## mldonkey torrents incoming folder
## this is used since the startbt in mldonkey does
## not work very well with capturing torrents
tor_dir = "/home/mega/.mldonkey/torrents/incoming/"
    
params = get_params()
mode = None
site = None
name = None
url = None
page = 1

try:
        url=urllib.unquote_plus(params["url"])
except:
        pass
try:
        name=urllib.unquote_plus(params["name"])
except:
        pass
try:
        site=urllib.unquote_plus(params["site"])
except:
        pass
try:
        mode=int(params["mode"])
except:
        pass
try:
        page=int(params["page"])
except:
        pass



if mode == None:
    showRoot()
elif mode == 0:
        showCats(site)
elif mode == 1:
    showList(site, url)
elif mode == 2:
    getTorrent(site, url, name)

xbmcplugin.endOfDirectory(int(sys.argv[1]))

i tried to comment the code to make it readable to those who are like me new to python. All you need to do is:
1. of course have mlDonkey (although with very little alteration to the code you can just use it to grab the torrent file and then manually add it to your fav. downloader)
2. set the IP and port of your mldonkey server (right now its set to 127.0.0.1 - same machine as where xbmc is - and port 4000 - the default for telnet)
3. set your local mldonkey incoming torrents dir (tor_dir) since sometimes the mldonkey's "startbt url" does not work, so i found out that if you just copy the torrent file into this dir, mldonkey will automatically pick it up (it scans it every 60sec. by default)
4. create a folder in your xbmc dir under plugins -> video (you can name it anything you want)
5. name the python file "default.py" and copy it there

and that's it

please understand that this is purely done as an exercise for me to understand the inner workings of xbmc better (and learn some python on the way) and if anyone can add to it, it will be great

cheers
Reply
#2
This is the same script but going about in a different order:
instead of: website -> category -> torrents
this is just: category -> torrents
where each category reads the corresponding rss feed from all sites and displays them all together

also removed the telnet / startbt and made all put the files into the incoming folder of mldonkey

cleaned up the code a bit and added timeouts and error-handling to skip offline / unreachable sites

update: added sorting to the listed items.

Code:
import xbmc, xbmcgui, xbmcplugin, urllib2, urllib, re, string, socket
from xml.dom import minidom
from xml.dom.minidom import parse


def showRoot():
        ri=[
                ("Movies"),
                ("TV Series"),
                ("Music"),
                ("Unsorted"),
                ("Adult")
                ]
        ## add root list in xbmc gui
        for cat in ri:
                li = xbmcgui.ListItem(cat)
                u = sys.argv[0] + "?mode=0&cat=" + urllib.quote_plus(cat)
                xbmcplugin.addDirectoryItem(int(sys.argv[1]),u,li,True)
                
def showTorrents(cat):
        if cat == "Movies":
                ri=[
                        ("BiteNova", "http://bitenova.nl/rss/cat.4.xml"),
                        ("ExtraTorrent", "http://extratorrent.com/rss.xml?type=popular&cid=4"),
                        ("NewTorrents", "http://www.newtorrents.info/rss2.php?cat=movies"),
                        ("TorrentPortal", "http://www.torrentportal.com/rssfeed.php?cat=2"),
                        ("BTJunkie", "http://btjunkie.org/rss.xml?c=6"),
                        ("YourBitTorrent", "http://www.yourbittorrent.com/movies/rss.xml"),
                        ("Fenopy", "http://fenopy.com/rss.xml?row=50&cat=3&type=2")
                        ]
        elif cat == "TV Series":
                ri=[
                        ("BiteNova", "http://bitenova.nl/rss/cat.9.xml"),
                        ("ExtraTorrent", "http://extratorrent.com/rss.xml?type=popular&cid=8"),
                        ("NewTorrents", "http://www.newtorrents.info/rss2.php?cat=tv"),
                        ("TorrentPortal", "http://www.torrentportal.com/rssfeed.php?cat=3"),
                        ("BTJunkie", "http://btjunkie.org/rss.xml?c=4"),
                        ("YourBitTorrent", "http://www.yourbittorrent.com/television/rss.xml"),
                        ("Fenopy", "http://fenopy.com/rss.xml?row=50&cat=78&type=2")
                        ]
        elif cat == "Music":
                ri=[
                        ("ExtraTorrent", "http://extratorrent.com/rss.xml?type=popular&cid=5"),
                        ("NewTorrents", "http://www.newtorrents.info/rss2.php?cat=music"),
                        ("TorrentPortal", "http://www.torrentportal.com/rssfeed.php?cat=7"),
                        ("BTJunkie", "http://btjunkie.org/rss.xml?c=1"),
                        ("YourBitTorrent", "http://www.yourbittorrent.com/music/rss.xml"),
                        ("Fenopy", "http://fenopy.com/rss.xml?row=50&cat=1&type=2")
                        ]
        elif cat == "Unsorted":
                ri=[
                        ("BiteNova", "http://bitenova.nl/rss/cat.6.xml"),
                        ("TorrentPortal", "http://www.torrentportal.com/rssfeed.php?cat=4"),
                        ("BTJunkie", "http://btjunkie.org/rss.xml?c=5"),
                        ("Fenopy", "http://fenopy.com/rss.xml?row=50&cat=72&type=2")
                        ]
        elif cat == "Adult":
                ri=[
                        ("TorrentPortal", "http://www.torrentportal.com/rssfeed.php?cat=10"),
                        ("Fenopy", "http://fenopy.com/rss.xml?row=50&cat=2&subcat=29&type=2")
                        ]

        ## list site categories in xbmc gui
        for site, url in ri:
            try:
                timeout = 10
                socket.setdefaulttimeout(timeout)
                sock = urllib2.urlopen(url)
                doc = minidom.parse(sock)
                sock.close()
            
                ##parse rss feed for torrents
                for node in doc.getElementsByTagNameNS('*', 'item'):
                        name = node.getElementsByTagName('title')[0].firstChild.data
                        ## the torrent url is different in some feeds
                        if site in ("ExtraTorrent", "Fenopy"):
                                link = node.getElementsByTagName('enclosure')[0].getAttribute('url')
                        else:
                                link = node.getElementsByTagName('link')[0].firstChild.data

                        ## list torrents in xbmc gui
                        try:
                                li = xbmcgui.ListItem(name + " [" + site + "]")
                                u = sys.argv[0] + "?mode=1&name=" + urllib.quote_plus(name) + "&url=" + urllib.quote_plus(link) + "&site=" + urllib.quote_plus(site)
                                xbmcplugin.addDirectoryItem(int(sys.argv[1]),u,li,True)
                        except:
                                pass
                xbmcplugin.addSortMethod(int(sys.argv[1]), xbmcplugin.SORT_METHOD_LABEL)
                        except:
                                pass
            except:
                pass

def getTorrent(site, url, name):
        timeout = 60
        socket.setdefaulttimeout(timeout)
    
        if site in ("BiteNova", "TorrentPortal", "BTJunkie"):
                nsock = urllib2.urlopen(url)
                ndoc = nsock.read()
                nsock.close()
                t_url = None
                if site == "BiteNova":
                        nmat = re.compile('<em><a href="(.+?)" title="Download this torrent">(.+?)</a></em>').findall(ndoc)
                        for t_link, t_name in nmat:
                            url = "http://www.bitenova.nl" + t_link
                elif site == "TorrentPortal":
                        nmat = re.compile('<a href="(.+?)"  ><font size=3><b>Download This Torrent<b></font></a>').findall(ndoc)
                        for t_link in nmat:
                            url = t_link
                elif site == "BTJunkie":
                        nmat = re.compile('<a href="(.+?)" rel="nofollow" class="blocked_black">Torrent Download</a>').findall(ndoc)
                        for t_link in nmat:
                            url = t_link
                
        elif site == "NewTorrents":
                url = url.replace("http://www.newtorrents.info/torrent/","http://www.NewTorrents.info/down.php?id=")
                url = url.replace("/" + name + ".html", "")

        name = name.replace(" ", ".")
        name = name.replace("[", "")
        name = name.replace("]", "")
        name = name.replace("/", "")
        name = name.replace("..", ".")
        
        urllib.urlretrieve(url, tor_dir + name + ".torrent")

def get_params():
        param=[]
        paramstring=sys.argv[2]
        if len(paramstring)>=2:
                params=sys.argv[2]
                cleanedparams=params.replace('?','')
                if (params[len(params)-1]=='/'):
                        params=params[0:len(params)-2]
                pairsofparams=cleanedparams.split('&')
                param={}
                for i in range(len(pairsofparams)):
                        splitparams={}
                        splitparams=pairsofparams[i].split('=')
                        if (len(splitparams))==2:
                                param[splitparams[0]]=splitparams[1]
                                
        return param






## mldonkey torrents incoming folder
## this is used since the startbt in mldonkey does
## not work very well with capturing torrents
tor_dir = "/home/mega/.mldonkey/torrents/incoming/"
    
params = get_params()
mode = None
site = None
name = None
url = None
cat = None
page = 1

try:
        url=urllib.unquote_plus(params["url"])
except:
        pass
try:
        name=urllib.unquote_plus(params["name"])
except:
        pass
try:
        site=urllib.unquote_plus(params["site"])
except:
        pass
try:
        cat=urllib.unquote_plus(params["cat"])
except:
        pass
try:
        mode=int(params["mode"])
except:
        pass
try:
        page=int(params["page"])
except:
        pass



if mode == None:
    showRoot()
elif mode == 0:
        showTorrents(cat)
elif mode == 1:
    getTorrent(site, url, name)

xbmcplugin.endOfDirectory(int(sys.argv[1]))
Reply
#3
interesting script. im not that new to python but i've never written anything for xbmc so this is pretty interesting. since you've done away with the mldonkey-specific stuff you could really use any bittorrent client that lets you just drop torrent files in a directory, so you might as well get rid of all mldonkey references. additionally, there's no need for this any more:

Code:
## mldonkey server ip & port
mldonkey_ip = "127.0.0.1"
mldonkey_port = 4000


perhaps as an added exercise you can have your script look at a config file, where you can specify a list of shows and then your script could look at your existing episodes (that are in the xbmc library) and search for the next one.
Reply
#4
aeiah Wrote:perhaps as an added exercise you can have your script look at a config file, where you can specify a list of shows and then your script could look at your existing episodes (that are in the xbmc library) and search for the next one.

this is exactly what i want to do .. the problem is with the different naming formats the files are posted with, most of them follow the same pattern. but this is definitely what i will try to do next.

and yes, the second post does not necessarily require mldonkey, it can be used with any client you want, the telnet part is taken out, and it only grabs the torrent files to the folder you select inside the script:
Code:
## mldonkey torrents incoming folder
## this is used since the startbt in mldonkey does
## not work very well with capturing torrents
tor_dir = "/home/mega/.mldonkey/torrents/incoming/"
Reply

Logout Mark Read Team Forum Stats Members Help
mlDonkey torrents plugin in development, help needed...0