diff --git a/sickbeard/providers/__init__.py b/sickbeard/providers/__init__.py index 05dc3407394a3608b1c00bfd15bb01485ebffac3..4fc2d65261e5b78cf41d827cf1b39b9c38caed16 100644 --- a/sickbeard/providers/__init__.py +++ b/sickbeard/providers/__init__.py @@ -25,18 +25,21 @@ import sickbeard from sickbeard import logger from sickbeard.providers import btn, newznab, rsstorrent, womble, thepiratebay, torrentleech, kat, iptorrents, torrentz, \ omgwtfnzbs, scc, hdtorrents, torrentday, hdbits, hounddawgs, speedcd, nyaatorrents, animenzb, bluetigers, cpasbien, fnt, xthor, torrentbytes, \ - freshontv, titansoftv, morethantv, bitsoup, t411, tokyotoshokan, shazbat, rarbg, alpharatio, tntvillage, binsearch, torrentproject, extratorrent, \ + freshontv, titansoftv, morethantv, bitsoup, t411, tokyotoshokan, shazbat, rarbg, tntvillage, binsearch, torrentproject, extratorrent, \ scenetime, btdigg, transmitthenet, tvchaosuk, bitcannon, pretome, gftracker, hdspace, newpct, elitetorrent, bitsnoop, danishbits, hd4free +from sickrage.providers import AlphaRatio __all__ = [ 'womble', 'btn', 'thepiratebay', 'kat', 'torrentleech', 'scc', 'hdtorrents', 'torrentday', 'hdbits', 'hounddawgs', 'iptorrents', 'omgwtfnzbs', 'speedcd', 'nyaatorrents', 'animenzb', 'torrentbytes', 'freshontv', 'titansoftv', - 'morethantv', 'bitsoup', 't411', 'tokyotoshokan', 'alpharatio', + 'morethantv', 'bitsoup', 't411', 'tokyotoshokan', 'shazbat', 'rarbg', 'tntvillage', 'binsearch', 'bluetigers', 'cpasbien', 'fnt', 'xthor', 'scenetime', 'btdigg', 'transmitthenet', 'tvchaosuk', 'torrentproject', 'extratorrent', 'bitcannon', 'torrentz', 'pretome', 'gftracker', 'hdspace', 'newpct', 'elitetorrent', 'bitsnoop', 'danishbits', 'hd4free' +] + [ + 'AlphaRatio' ] @@ -200,12 +203,13 @@ def getDefaultNewznabProviders(): def getProviderModule(name): - name = name.lower() - prefix = "sickbeard.providers." - if name in __all__ and prefix + name in sys.modules: - return sys.modules[prefix + name] - else: - raise Exception("Can't find " + prefix + name + " in " + "Providers") + prefixes = ['sickbeard.providers.', 'sickrage.providers.'] + + for prefix in prefixes: + if name in __all__ and prefix + name in sys.modules: + return sys.modules[prefix + name] + + raise Exception(u'Can\'t find %s in %s' % (name, prefixes)) def getProviderClass(provider_id): diff --git a/sickbeard/providers/alpharatio.py b/sickrage/providers/AlphaRatio.py similarity index 52% rename from sickbeard/providers/alpharatio.py rename to sickrage/providers/AlphaRatio.py index d500d771cf24ecbda5ab576d80be7ad9c7a6bfad..9e24dcfef02853f9fb967156d290c1c7c16bf7c3 100644 --- a/sickbeard/providers/alpharatio.py +++ b/sickrage/providers/AlphaRatio.py @@ -1,10 +1,8 @@ -# coding=utf-8 - -# Author: Bill Nasty -# URL: https://github.com/SickRage/SickRage -# # This file is part of SickRage. # +# URL: https://sickrage.github.io +# Git: https://github.com/SickRage/SickRage.git +# # SickRage is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or @@ -12,95 +10,98 @@ # # SickRage 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 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with SickRage. If not, see <http://www.gnu.org/licenses/>. +# along with SickRage. If not, see <http://www.gnu.org/licenses/>. import re import traceback from sickbeard import logger -from sickbeard import tvcache from sickbeard.bs4_parser import BS4Parser +from sickbeard.tvcache import TVCache from sickrage.providers.TorrentProvider import TorrentProvider class AlphaRatioProvider(TorrentProvider): - def __init__(self): + TorrentProvider.__init__(self, 'AlphaRatio') - TorrentProvider.__init__(self, "AlphaRatio") - - self.username = None + self.cache = AlphaRatioCache(self) + self.categories = '&filter_cat[1]=1&filter_cat[2]=1&filter_cat[3]=1&filter_cat[4]=1&filter_cat[5]=1' + self.minleech = None + self.minseed = None self.password = None + self.proper_strings = ['PROPER', 'REPACK'] self.ratio = None - self.minseed = None - self.minleech = None - - self.urls = {'base_url': 'http://alpharatio.cc/', - 'login': 'http://alpharatio.cc/login.php', - 'detail': 'http://alpharatio.cc/torrents.php?torrentid=%s', - 'search': 'http://alpharatio.cc/torrents.php?searchstr=%s%s', - 'download': 'http://alpharatio.cc/%s'} - + self.urls = { + 'base_url': 'http://alpharatio.cc/', + 'detail': 'http://alpharatio.cc/torrents.php?torrentid=%s', + 'download': 'http://alpharatio.cc/%s', + 'login': 'http://alpharatio.cc/login.php', + 'search': 'http://alpharatio.cc/torrents.php?searchstr=%s%s', + } self.url = self.urls['base_url'] - - self.categories = "&filter_cat[1]=1&filter_cat[2]=1&filter_cat[3]=1&filter_cat[4]=1&filter_cat[5]=1" - - self.proper_strings = ['PROPER', 'REPACK'] - - self.cache = AlphaRatioCache(self) + self.username = None def login(self): - login_params = {'username': self.username, - 'password': self.password, - 'remember_me': 'on', - 'login': 'submit'} + login_params = { + 'login': 'submit', + 'password': self.password, + 'remember_me': 'on', + 'username': self.username, + } response = self.get_url(self.urls['login'], post_data=login_params, timeout=30) + if not response: - logger.log(u"Unable to connect to provider", logger.WARNING) + logger.log(u'Unable to connect to %s' % self.name, logger.WARNING) return False if re.search('Invalid Username/password', response) \ or re.search('<title>Login :: AlphaRatio.cc</title>', response): - logger.log(u"Invalid username or password. Check your settings", logger.WARNING) + logger.log(u'Invalid username or password. Check your settings for %s' % self.name, logger.WARNING) return False return True - def search(self, search_strings, age=0, ep_obj=None): - + def search(self, search_params, age=0, ep_obj=None): results = [] - items = {'Season': [], 'Episode': [], 'RSS': []} + items = { + 'Episode': [], + 'RSS': [], + 'Season': [], + } if not self.login(): return results - for mode in search_strings.keys(): - logger.log(u"Search Mode: %s" % mode, logger.DEBUG) - for search_string in search_strings[mode]: + for mode in search_params.keys(): + logger.log(u'Search mode: %s' % mode, logger.DEBUG) + for search_param in search_params[mode]: if mode != 'RSS': - logger.log(u"Search string: %s " % search_string, logger.DEBUG) + logger.log(u'Search string: %s' % search_param, logger.DEBUG) + + search_url = self.urls['search'] % (search_param, self.categories) - searchURL = self.urls['search'] % (search_string, self.categories) - logger.log(u"Search URL: %s" % searchURL, logger.DEBUG) + logger.log(u'Search URL: %s' % search_url, logger.DEBUG) - data = self.get_url(searchURL) - if not data: + response = self.get_url(search_url) + + if not response: continue try: - with BS4Parser(data, 'html5lib') as html: + with BS4Parser(response, 'html5lib') as html: torrent_table = html.find('table', attrs={'id': 'torrent_table'}) torrent_rows = torrent_table.find_all('tr') if torrent_table else [] # Continue only if one Release is found if len(torrent_rows) < 2: - logger.log(u"Data returned from provider does not contain any torrents", logger.DEBUG) + logger.log(u'Data returned from %s does not contain any torrents' % self.name, logger.DEBUG) continue for result in torrent_rows[1:]: @@ -111,32 +112,35 @@ class AlphaRatioProvider(TorrentProvider): try: title = link.contents[0] download_url = self.urls['download'] % (url['href']) - seeders = cells[len(cells)-2].contents[0] - leechers = cells[len(cells)-1].contents[0] + seeders = cells[len(cells) - 2].contents[0] + leechers = cells[len(cells) - 1].contents[0] # FIXME size = -1 except (AttributeError, TypeError): continue - if not all([title, download_url]): + if not all([download_url, title]): continue # Filter unseeded torrent if seeders < self.minseed or leechers < self.minleech: if mode != 'RSS': - logger.log(u"Discarding torrent because it doesn't meet the minimum seeders or leechers: {0} (S:{1} L:{2})".format(title, seeders, leechers), logger.DEBUG) + logger.log(u'Discarding torrent because it doesn\'t meet the minimum seeders or ' + u'leechers: %s (S: %s, L: %s))' % (title, seeders, leechers), + logger.DEBUG) continue item = title, download_url, size, seeders, leechers + if mode != 'RSS': - logger.log(u"Found result: %s " % title, logger.DEBUG) + logger.log(u'Found result: %s' % title, logger.DEBUG) items[mode].append(item) - except Exception: - logger.log(u"Failed parsing provider. Traceback: %s" % traceback.format_exc(), logger.WARNING) + logger.log(u'Failed parsing %s. Traceback: %s' % (self.name, traceback.format_exc()), + logger.WARNING) - # For each search mode sort all the items by seeders if available + # For each search mode, sort all the items by seeders, if available items[mode].sort(key=lambda tup: tup[3], reverse=True) results += items[mode] @@ -147,17 +151,21 @@ class AlphaRatioProvider(TorrentProvider): return self.ratio -class AlphaRatioCache(tvcache.TVCache): - +class AlphaRatioCache(TVCache): def __init__(self, provider_obj): + TVCache.__init__(self, provider_obj) - tvcache.TVCache.__init__(self, provider_obj) - - # only poll AlphaRatio every 20 minutes max + # Only poll AlphaRatio every 20 minutes max self.minTime = 20 def _getRSSData(self): - search_strings = {'RSS': ['']} - return {'entries': self.provider.search(search_strings)} + search_strings = { + 'RSS': [''] + } + + return { + 'entries': self.provider.search(search_strings) + } + provider = AlphaRatioProvider()