diff --git a/gui/slick/images/providers/bithdtv.png b/gui/slick/images/providers/bithdtv.png new file mode 100644 index 0000000000..aecf0ed6b1 Binary files /dev/null and b/gui/slick/images/providers/bithdtv.png differ diff --git a/sickbeard/providers/bithdtv.py b/sickbeard/providers/bithdtv.py index 821b423cd1..aaf187528a 100644 --- a/sickbeard/providers/bithdtv.py +++ b/sickbeard/providers/bithdtv.py @@ -16,7 +16,9 @@ # You should have received a copy of the GNU General Public License # along with Medusa. If not, see . -import re +from __future__ import unicode_literals + +from requests.compat import urljoin from requests.utils import dict_from_cookiejar from sickbeard import logger, tvcache @@ -31,7 +33,7 @@ class BithdtvProvider(TorrentProvider): # pylint: disable=too-many-instance-att def __init__(self): # Provider Init - TorrentProvider.__init__(self, "BITHDTV") + TorrentProvider.__init__(self, 'BITHDTV') # Credentials self.username = None @@ -45,90 +47,73 @@ def __init__(self): # URLs self.url = 'https://www.bit-hdtv.com/' self.urls = { - 'login': self.url + 'takelogin.php', - 'search': self.url + 'torrents.php', + 'login': urljoin(self.url, 'takelogin.php'), + 'search': urljoin(self.url, 'torrents.php'), } + # Proper Strings # Cache self.cache = tvcache.TVCache(self, min_time=10) # Only poll BitHDTV every 10 minutes max - def login(self): - """Login method used for logging in before doing search and torrent downloads""" - if any(dict_from_cookiejar(self.session.cookies).values()): - return True - - login_params = { - 'username': self.username.encode('utf-8'), - 'password': self.password.encode('utf-8'), - } - - response = self.get_url(self.urls['login'], post_data=login_params, returns='text') - if not response: - logger.log(u"Unable to connect to provider", logger.WARNING) - self.session.cookies.clear() - return False - - if '

Login failed!

' in response: - logger.log(u"Invalid username or password. Check your settings", logger.WARNING) - self.session.cookies.clear() - return False - - return True - def search(self, search_strings, age=0, ep_obj=None): # pylint: disable=too-many-locals, too-many-branches - """BIT HDTV login method + """ + BIT HDTV search and parsing - @param search_string: A dict with mode (key) and the search value (value) - @param age: Not used - @param ep_obj: Not used - @return: A list of search results (structure) + :param search_string: A dict with mode (key) and the search value (value) + :param age: Not used + :param ep_obj: Not used + :returns: A list of search results (structure) """ results = [] if not self.login(): return results # Search Params - search_params = {'cat': '12'} if 'Season' in search_strings else {'cat': '10'} + search_params = { + 'cat': 10, + } # Units units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'] for mode in search_strings: items = [] - logger.log(u"Search Mode: {}".format(mode), logger.DEBUG) + logger.log('Search mode: {0}'.format(mode), logger.DEBUG) for search_string in search_strings[mode]: if mode != 'RSS': - logger.log(u"Search string: {}".format(search_string.decode("utf-8")), - logger.DEBUG) - search_params['search'] = search_string - search_params['cat'] = '12' if mode == 'Season' else '10' + if mode == 'Season': + search_params['cat'] = 12 - data = self.get_url(self.urls['search'], params=search_params, returns='text') - if not data: - logger.log(u"No data returned from provider", logger.DEBUG) + response = self.get_url(self.urls['search'], params=search_params, returns='response') + if not response.text: + logger.log('No data returned from provider', logger.DEBUG) continue - with BS4Parser(data, 'html.parser') as html: + with BS4Parser(response.text, 'html5lib') as html: torrent_table = html.find('table', width='750') torrent_rows = torrent_table('tr') if torrent_table else [] # Continue only if at least 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('Data returned from provider does not contain any torrents', logger.DEBUG) continue # Skip column headers for result in torrent_rows[1:]: + freeleech = result.get('bgcolor') + if self.freeleech and not freeleech: + continue try: - cells = result.find_all('td') + cells = result('td') + title = cells[2].find('a')['title'] - download_url = result.find_all('td')[0].find('a')['href'] + download_url = cells[0].find('a')['href'] if not all([title, download_url]): continue @@ -138,22 +123,26 @@ def search(self, search_strings, age=0, ep_obj=None): # pylint: disable=too-man # Filter unseeded torrent if seeders < min(self.minseed, 1): if mode != 'RSS': - logger.log(u"Discarding torrent because it doesn't meet the" - u" minimum seeders: {0}. Seeders: {1})".format + logger.log('Discarding torrent because it doesn\'t meet the' + ' minimum seeders: {0}. Seeders: {1})'.format (title, seeders), logger.DEBUG) continue - freeleech = bool(result.get('bgcolor')) - if self.freeleech and not freeleech: - continue - torrent_size = '{size} {unit}'.format(size=cells[6].contents[0], unit=cells[6].contents[1].get_text()) size = convert_size(torrent_size, units=units) or -1 - item = {'title': title, 'link': download_url, 'size': size, 'seeders': seeders, 'leechers': leechers, 'pubdate': None, 'hash': None} + item = { + 'title': title, + 'link': download_url, + 'size': size, + 'seeders': seeders, + 'leechers': leechers, + 'pubdate': None, + 'hash': None + } if mode != 'RSS': - logger.log(u"Found result: {0} with {1} seeders and {2} leechers".format + logger.log('Found result: {0} with {1} seeders and {2} leechers'.format (title, seeders, leechers), logger.DEBUG) items.append(item) @@ -166,4 +155,29 @@ def search(self, search_strings, age=0, ep_obj=None): # pylint: disable=too-man return results + +def login(self): + """Login method used for logging in before doing search and torrent downloads""" + if any(dict_from_cookiejar(self.session.cookies).values()): + return True + + login_params = { + 'username': self.username.encode('utf-8'), + 'password': self.password.encode('utf-8'), + } + + response = self.get_url(self.urls['login'], post_data=login_params, returns='text') + if not response: + logger.log(u'Unable to connect to provider', logger.WARNING) + self.session.cookies.clear() + return False + + if '

Login failed!

' in response: + logger.log(u'Invalid username or password. Check your settings', logger.WARNING) + self.session.cookies.clear() + return False + + return True + + provider = BithdtvProvider()