From 2880069d88a62d90b42ee81518d89c5bc8c8177c Mon Sep 17 00:00:00 2001 From: JackDandy Date: Sat, 9 Feb 2019 15:58:22 +0000 Subject: [PATCH] Fix providers Nyaa and HorribleSubs. --- CHANGES.md | 8 +++- sickbeard/providers/horriblesubs.py | 74 ++++++++++++++++++++++++++----------- sickbeard/providers/nyaa.py | 2 +- 3 files changed, 61 insertions(+), 23 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 65e0a71..3360683 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,10 @@ -### 0.18.12 (2019-02-07 03:55:00 UTC) +### 0.18.13 (2019-02-09 16:00:00 UTC) + +* Fix Nyaa provider +* Fix HorribleSubs provider + + +### 0.18.12 (2019-02-07 03:55:00 UTC) * Change improve DiskStation 6.2 connectivity and error logging * Fix TokyoToshokan diff --git a/sickbeard/providers/horriblesubs.py b/sickbeard/providers/horriblesubs.py index c0eabd5..840c15c 100644 --- a/sickbeard/providers/horriblesubs.py +++ b/sickbeard/providers/horriblesubs.py @@ -15,6 +15,7 @@ # along with SickGear. If not, see . import re +import time import traceback import urllib @@ -28,11 +29,11 @@ class HorribleSubsProvider(generic.TorrentProvider): def __init__(self): generic.TorrentProvider.__init__(self, 'HorribleSubs', anime_only=True) - self.url_base = 'http://horriblesubs.info/' self.urls = {'config_provider_home_uri': self.url_base, - 'browse': self.url_base + 'lib/latest.php', - 'search': self.url_base + 'lib/search.php?value=%s'} + 'browse': self.url_base + 'rss.php?res=all', + 'search': self.url_base + 'api.php?method=search&value=%s&_=%s', + 'get_data': self.url_base + 'api.php?method=getshows&type=show&showid=%s'} self.url = self.urls['config_provider_home_uri'] delattr(self, 'search_mode') @@ -54,33 +55,40 @@ class HorribleSubsProvider(generic.TorrentProvider): search_string = isinstance(search_string, unicode) and unidecode(search_string) or search_string search_url = self.urls['browse'] if 'Cache' == mode else \ - self.urls['search'] % rc['nodots'].sub(' ', search_string) + self.urls['search'] % (rc['nodots'].sub(' ', search_string), str(time.time()).replace('.', '3')) + + data, html = 2 * [None] + if 'Cache' == mode: + data = self.cache.get_rss(search_url) + else: + html = self.get_url(search_url) - html = self.get_url(search_url) if self.should_skip(): return results cnt = len(items[mode]) try: + if None is not data: + for cur_item in data.get('entries', []): + title, download_url = cur_item.get('title'), self._link(cur_item.get('link')) + if title and download_url: + items[mode].append((title, download_url, '', '')) if not html or self._has_no_results(html): raise generic.HaltParseException - with BS4Parser(html, features=['html5lib', 'permissive']) as soup: - torrent_rows = soup.find_all('table', class_='release-table') - - if 1 > len(torrent_rows): - raise generic.HaltParseException - - for tr in torrent_rows: - if 4 < len(tr.find_all('td')): - try: - title = tr.find('td', class_='dl-label').get_text().strip() - title = title.startswith('[') and title or '[HorribleSubs] %s' % title - download_url = self._link(tr.find('a', href=rc['get'])['href']) - if title and download_url: - items[mode].append((title, download_url, '', '')) - except (AttributeError, TypeError, ValueError): - continue + with BS4Parser('%s' % html, features=['html5lib', 'permissive']) as soup: + for link in soup.find_all('a'): + try: + variants = map(lambda t: t.get_text().replace('SD', '480p'), + link.find_all('span', class_='badge')) + map(lambda t: t.decompose(), link.find_all('span') + link.find_all('div')) + title = '[HorribleSubs] ' + re.sub(r'\s*\[HorribleSubs\]\s*', '', link.get_text()) + download_url = self._link(link.get('href')) + if title and download_url: + items[mode] += map(lambda v: ( + '%s [%s]' % (title, v), '%s-%s' % (download_url, v), '', ''), variants) + except (AttributeError, TypeError, ValueError): + continue except generic.HaltParseException: pass @@ -92,5 +100,29 @@ class HorribleSubsProvider(generic.TorrentProvider): return results + def get_data(self, url): + result = None + html = self.get_url(url) + if self.should_skip(): + return result + with BS4Parser(html, features=['html5lib', 'permissive']) as soup: + re_showid = re.compile(r'(?i)hs_showid\s*=\s*(\d+)') + try: + hs_id = re_showid.findall( + filter(lambda s: re_showid.search(s), map(lambda t: t.get_text(), soup.find_all('script')))[0])[0] + except (Exception, BaseException): + return result + html = self.get_url(self.urls['get_data'] % hs_id) + if self.should_skip(): + return result + with BS4Parser(html, features=['html5lib', 'permissive']) as soup: + try: + result = sorted(map(lambda t: t.get('href'), + soup.find(id=re.findall(r'.*#(\d+-\d+\w)$', url)[0]) + .find_all('a', href=re.compile('(?i)(torrent$|^magnet:)'))))[0] + except (Exception, BaseException): + pass + return result + provider = HorribleSubsProvider() diff --git a/sickbeard/providers/nyaa.py b/sickbeard/providers/nyaa.py index 2d64626..c5576a3 100644 --- a/sickbeard/providers/nyaa.py +++ b/sickbeard/providers/nyaa.py @@ -50,7 +50,7 @@ class NyaaProvider(generic.TorrentProvider): for mode in search_params.keys(): for search_string in search_params[mode]: search_string = isinstance(search_string, unicode) and unidecode(search_string) or search_string - search_url = self.urls['search'] % ((0, 2)[self.confirmed], search_string) + search_url = self.urls['search'] % ((0, 2)[self.confirmed], search_string.replace('.', ' ')) html = self.get_url(search_url) if self.should_skip():