diff --git a/CHANGES.md b/CHANGES.md index 486901df..cedbc325 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -60,6 +60,13 @@ * Change restart/shutdown to use updated jQuery +### 0.12.15 (2017-05-04 00:40:00 UTC) + +* Remove provider Nyaa +* Change improve RSS validation (particularly for anime) +* Change improve support for legacy magnet encoding + + ### 0.12.14 (2017-05-02 17:10:00 UTC) * Change provider Transmithe.net is now Nebulance diff --git a/gui/slick/images/providers/nyaatorrents.png b/gui/slick/images/providers/nyaatorrents.png deleted file mode 100644 index afa0b197..00000000 Binary files a/gui/slick/images/providers/nyaatorrents.png and /dev/null differ diff --git a/sickbeard/providers/__init__.py b/sickbeard/providers/__init__.py index a409453c..56dca6ff 100755 --- a/sickbeard/providers/__init__.py +++ b/sickbeard/providers/__init__.py @@ -33,7 +33,7 @@ from . import alpharatio, alphareign, beyondhd, bithdtv, bitmetv, btn, btscene, thepiratebay, torlock, torrentday, torrenting, torrentleech, \ torrentz2, tvchaosuk, zooqle # anime -from . import anizb, nyaatorrents, tokyotoshokan +from . import anizb, tokyotoshokan # custom try: from . import custom01 @@ -86,7 +86,6 @@ __all__ = ['omgwtfnzbs', 'torrentz2', 'tvchaosuk', 'zooqle', - 'nyaatorrents', 'tokyotoshokan', ] diff --git a/sickbeard/providers/generic.py b/sickbeard/providers/generic.py index 7238eb6f..32d7a4b9 100644 --- a/sickbeard/providers/generic.py +++ b/sickbeard/providers/generic.py @@ -177,17 +177,21 @@ class GenericProvider: final_dir = sickbeard.TORRENT_DIR link_type = 'magnet' try: - torrent_hash = re.findall('(?i)urn:btih:([0-9a-f]{32,40})', result.url)[0].upper() + btih = None + try: + btih = re.findall('urn:btih:([\w]{32,40})', result.url)[0] + if 32 == len(btih): + from base64 import b16encode, b32decode + btih = b16encode(b32decode(btih)) + except (StandardError, Exception): + pass - if 32 == len(torrent_hash): - torrent_hash = b16encode(b32decode(torrent_hash)).lower() - - if not torrent_hash: + if not btih or not re.search('(?i)[0-9a-f]{32,40}', btih): logger.log('Unable to extract torrent hash from link: ' + ex(result.url), logger.ERROR) return False - urls = ['http%s://%s/torrent/%s.torrent' % (u + (torrent_hash,)) - for u in (('s', 'itorrents.org'), ('s', 'torra.pro'), ('s', 'torra.click'), + urls = ['http%s://%s/torrent/%s.torrent' % (u + (btih.upper(),)) + for u in (('s', 'itorrents.org'), ('s', 'torra.pro'), ('s', 'torrasave.site'), ('s', 'torrage.info'), ('', 'reflektor.karmorra.info'), ('s', 'torrentproject.se'), ('', 'thetorrent.org'))] except (StandardError, Exception): diff --git a/sickbeard/providers/nyaatorrents.py b/sickbeard/providers/nyaatorrents.py deleted file mode 100644 index 24a6f951..00000000 --- a/sickbeard/providers/nyaatorrents.py +++ /dev/null @@ -1,107 +0,0 @@ -# -# This file is part of SickGear. -# -# SickGear 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 -# (at your option) any later version. -# -# SickGear 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with SickGear. If not, see . - -import re -import urllib - -from . import generic -from sickbeard import logger, show_name_helpers, tvcache -from sickbeard.helpers import tryInt - - -class NyaaProvider(generic.TorrentProvider): - - def __init__(self): - generic.TorrentProvider.__init__(self, 'NyaaTorrents', anime_only=True) - - self.url_base = self.url = 'https://www.nyaa.se/' - - self.minseed, self.minleech = 2 * [None] - - self.cache = NyaaCache(self) - - def _search_provider(self, search_string, search_mode='eponly', **kwargs): - - if self.show and not self.show.is_anime: - return [] - - params = urllib.urlencode({'term': search_string.encode('utf-8'), - 'cats': '1_37', # Limit to English-translated Anime (for now) - # 'sort': '2', # Sort Descending By Seeders - }) - - return self.get_data(getrss_func=self.cache.getRSSFeed, - search_url='%s?page=rss&%s' % (self.url, params), - mode=('Episode', 'Season')['sponly' == search_mode]) - - def get_data(self, getrss_func, search_url, mode='cache'): - - data = getrss_func(search_url) - - results = [] - if data and 'entries' in data: - - rc = dict((k, re.compile('(?i)' + v)) for (k, v) in { - 'stats': '(\d+)\W+seed[^\d]+(\d+)\W+leech[^\d]+\d+\W+down[^\d]+([\d.,]+\s\w+)'}.iteritems()) - - for cur_item in data.get('entries', []): - try: - seeders, leechers, size = 0, 0, 0 - stats = rc['stats'].findall(cur_item.get('summary_detail', {'value': ''}).get('value', '')) - if len(stats): - seeders, leechers, size = (tryInt(n, n) for n in stats[0]) - if self._peers_fail(mode, seeders, leechers): - continue - title, download_url = self._title_and_url(cur_item) - download_url = self._link(download_url) - except (AttributeError, TypeError, ValueError, IndexError): - continue - - if title and download_url: - results.append((title, download_url, seeders, self._bytesizer(size))) - - self._log_search(mode, len(results), search_url) - - return self._sort_seeding(mode, results) - - def _season_strings(self, ep_obj, **kwargs): - - return show_name_helpers.makeSceneShowSearchStrings(self.show) - - def _episode_strings(self, ep_obj, **kwargs): - - return self._season_strings(ep_obj) - - -class NyaaCache(tvcache.TVCache): - - def __init__(self, this_provider): - tvcache.TVCache.__init__(self, this_provider) - - self.update_freq = 15 - - def _cache_data(self): - - params = urllib.urlencode({'page': 'rss', # Use RSS page - 'order': '1', # Sort Descending By Date - 'cats': '1_37' # Limit to English-translated Anime (for now) - }) - - return self.provider.get_data(getrss_func=self.getRSSFeed, - search_url='%s?%s' % (self.provider.url, params)) - - -provider = NyaaProvider() diff --git a/sickbeard/providers/rsstorrent.py b/sickbeard/providers/rsstorrent.py index 50a9d864..6eace767 100644 --- a/sickbeard/providers/rsstorrent.py +++ b/sickbeard/providers/rsstorrent.py @@ -90,7 +90,15 @@ class TorrentRssProvider(generic.TorrentProvider): if not (title and url): continue if url.startswith('magnet:'): - if re.search('urn:btih:([0-9a-f]{32,40})', url): + btih = None + try: + btih = re.findall('urn:btih:([\w]{32,40})', url)[0] + if 32 == len(btih): + from base64 import b16encode, b32decode + btih = b16encode(b32decode(btih)) + except (StandardError, Exception): + pass + if re.search('(?i)[0-9a-f]{32,40}', btih): break else: torrent_file = self.get_url(url)