diff --git a/modules/btmon/__init__.py b/modules/btmon/__init__.py new file mode 100644 index 00000000..b88fb31a --- /dev/null +++ b/modules/btmon/__init__.py @@ -0,0 +1,3 @@ +from .backend import BtmonBackend + +__all__ = ['BtmonBackend'] diff --git a/modules/btmon/backend.py b/modules/btmon/backend.py new file mode 100644 index 00000000..4641fce2 --- /dev/null +++ b/modules/btmon/backend.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2010-2011 Julien Veyssier +# +# This file is part of weboob. +# +# weboob is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# weboob is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with weboob. If not, see . + +from weboob.capabilities.torrent import ICapTorrent +from weboob.tools.backend import BaseBackend + +from .browser import BtmonBrowser + +from urllib import quote_plus + +__all__ = ['KickassBackend'] + + +class BtmonBackend(BaseBackend, ICapTorrent): + NAME = 'btmon' + MAINTAINER = u'Julien Veyssier' + EMAIL = 'julien.veyssier@aiur.fr' + VERSION = '0.f' + DESCRIPTION = 'Btmon BitTorrent tracker' + LICENSE = 'AGPLv3+' + BROWSER = BtmonBrowser + + def create_default_browser(self): + return self.create_browser() + + def get_torrent(self, id): + return self.browser.get_torrent(id) + + def get_torrent_file(self, id): + torrent = self.browser.get_torrent(id) + if not torrent: + return None + return self.browser.openurl(torrent.url.encode('utf-8')).read() + + def iter_torrents(self, pattern): + return self.browser.iter_torrents(quote_plus(pattern.encode('utf-8'))) diff --git a/modules/btmon/browser.py b/modules/btmon/browser.py new file mode 100644 index 00000000..52c78c01 --- /dev/null +++ b/modules/btmon/browser.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2010-2011 Julien Veyssier +# +# This file is part of weboob. +# +# weboob is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# weboob is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with weboob. If not, see . + + +from weboob.tools.browser import BaseBrowser + +from .pages import TorrentsPage, TorrentPage + + +__all__ = ['BtmonBrowser'] + + +class BtmonBrowser(BaseBrowser): + DOMAIN = 'www.btmon.com' + PROTOCOL = 'http' + ENCODING = 'utf-8' + USER_AGENT = BaseBrowser.USER_AGENTS['wget'] + PAGES = { + 'http://www.btmon.com/torrent/\?f=.*': TorrentsPage, + 'http://www.btmon.com/.*torrent.html': TorrentPage, + } + + def iter_torrents(self, pattern): + self.location('http://www.btmon.com/torrent/?f=%s' % pattern.encode('utf-8')) + assert self.is_on_page(TorrentsPage) + return self.page.iter_torrents() + + def get_torrent(self, id): + self.location('http://www.btmon.com/%s.html' % id) + assert self.is_on_page(TorrentPage) + return self.page.get_torrent() diff --git a/modules/btmon/favicon.png b/modules/btmon/favicon.png new file mode 100644 index 00000000..f7976cbe Binary files /dev/null and b/modules/btmon/favicon.png differ diff --git a/modules/btmon/pages.py b/modules/btmon/pages.py new file mode 100644 index 00000000..9c83b5d2 --- /dev/null +++ b/modules/btmon/pages.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2010-2012 Julien Veyssier +# +# This file is part of weboob. +# +# weboob is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# weboob is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with weboob. If not, see . + + +try: + from urlparse import parse_qs +except ImportError: + from cgi import parse_qs # NOQA + +from urlparse import urlsplit +import string + +from weboob.capabilities.torrent import Torrent +from weboob.capabilities.base import NotAvailable +from weboob.tools.browser import BasePage +from weboob.tools.misc import get_bytes_size + + +__all__ = ['TorrentsPage','TorrentPage'] + + +class TorrentsPage(BasePage): + def iter_torrents(self): + for div in self.parser.select(self.document.getroot(),'div.list_tor'): + a = self.parser.select(div,'a.list_tor_title',1) + href = a.attrib.get('href','') + self.browser.location('http://%s%s'%(self.browser.DOMAIN,href)) + assert self.browser.is_on_page(TorrentPage) + yield self.browser.page.get_torrent() + + +class TorrentPage(BasePage): + def get_torrent(self): + seed = 0 + leech = 0 + description = NotAvailable.__unicode__() + url = NotAvailable + magnet = NotAvailable + title = NotAvailable + id = self.browser.geturl().split('.html')[0].split('/')[-1] + + div = self.parser.select(self.document.getroot(),'div#middle_content',1) + title = u'%s'%self.parser.select(self.document.getroot(),'div#middle_content > h1',1).text + slblock_values = self.parser.select(div,'div.sl_block b') + if len(slblock_values) >= 2: + seed = slblock_values[0].text + leech = slblock_values[1].text + href_t = self.parser.select(div,'a.down',1).attrib.get('href','') + url = 'http://%s%s'%(self.browser.DOMAIN,href_t) + magnet = self.parser.select(div,'a.magnet',1).attrib.get('href','') + + divtabs = self.parser.select(div,'div#tabs',1) + files_div = self.parser.select(divtabs,'div.body > div.doubleblock > div.leftblock') + files = [] + if len(files_div) > 0: + size_text = self.parser.select(files_div,'h5',1).text + for b in self.parser.select(files_div,'b'): + div = b.getparent() + files.append(div.text_content()) + else: + size_text = self.parser.select(divtabs,'h5',1).text_content() + size_text = size_text.split('(')[1].split(')')[0].strip() + size = float(size_text.split(',')[1].strip(string.letters)) + u = size_text.split(',')[1].strip().translate(None,string.digits).strip('.').strip().upper() + div_desc = self.parser.select(divtabs,'div#descriptionContent') + if len(div_desc) > 0: + description = div_desc[0].text_content() + + torrent = Torrent(id, title) + torrent.url = url + torrent.filename = id + torrent.magnet = magnet + torrent.size = get_bytes_size(size, u) + torrent.seeders = int(seed) + torrent.leechers = int(leech) + torrent.description = description + torrent.files = files + return torrent diff --git a/modules/btmon/test.py b/modules/btmon/test.py new file mode 100644 index 00000000..3d463149 --- /dev/null +++ b/modules/btmon/test.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2010-2011 Julien Veyssier, Laurent Bachelier +# +# This file is part of weboob. +# +# weboob is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# weboob is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with weboob. If not, see . + +from weboob.tools.test import BackendTest +from weboob.capabilities.base import NotLoaded + +import urllib +from random import choice + +class BtmonTest(BackendTest): + BACKEND = 'btmon' + + def test_torrent(self): + torrents = list(self.backend.iter_torrents('spiderman')) + for torrent in torrents: + path, qs = urllib.splitquery(torrent.url) + assert path.endswith('.torrent') + assert torrent.id + assert torrent.name + assert torrent.description is NotLoaded + + # get the file of a random torrent + # from the list (getting them all would be too long) + if len(torrents): + torrent = choice(torrents) + self.backend.get_torrent_file(torrent.id)