diff --git a/.build/bower.json b/.build/bower.json index e9a78d46ac93ce8ebb4983e0f39277a43e4ab102..ecbd37d1a176433864df18c5b7a47957d5167861 100644 --- a/.build/bower.json +++ b/.build/bower.json @@ -25,5 +25,8 @@ "jquery-confirm": "~2.5.2", "bootstrap-formhelpers": "~2.3.0", "isotope": "~2.2.2" + }, + "resolutions": { + "bootstrap": "~3.3.5" } } diff --git a/.build/package.json b/.build/package.json index a0a4b41183e254ed37b997591865458798311451..6cd6e05d1d190a93b4f0d75d71fa66b4e56de98c 100644 --- a/.build/package.json +++ b/.build/package.json @@ -2,9 +2,10 @@ "name": "sickrage", "version": "4.0.72", "private": true, - "dependencies": { + "devDependencies": { "grunt": "^0.4.5", "grunt-bower-concat": "^0.5.0", + "grunt-cli": "^0.1.13", "grunt-contrib-cssmin": "^0.14.0", "grunt-contrib-jshint": "^0.11.3", "grunt-contrib-uglify": "^0.9.2" diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py index a58eb83eb77aba944e44fb38f465cd236e5789a7..68a714dfd2ddba7aabe6d83fa45235580c115d4f 100644 --- a/sickbeard/__init__.py +++ b/sickbeard/__init__.py @@ -136,7 +136,7 @@ GIT_AUTOISSUES = False GIT_NEWVER = False DEVELOPER = False -NEWS_URL = 'http://SickRage.github.io/sickrage-news/news.md' +NEWS_URL = 'http://sickrage.github.io/sickrage-news/news.md' NEWS_LAST_READ = None NEWS_LATEST = None NEWS_UNREAD = 0 diff --git a/sickbeard/helpers.py b/sickbeard/helpers.py index 2f35739bb0c5ee689cb06cf3d0ba6290b7f3b04a..6e3cbac62d1307a908ff57aba567752a79e38e71 100644 --- a/sickbeard/helpers.py +++ b/sickbeard/helpers.py @@ -1559,7 +1559,7 @@ def _setUpSession(session, headers): session = CacheControl(sess=session, cache=caches.FileCache(os.path.join(cache_dir, 'sessions'), use_dir_lock=True), cache_etags=False) # request session clear residual referer - if 'Referer' in session.headers and 'Referer' not in headers or {}: + if 'Referer' in session.headers and 'Referer' not in (headers or {}): session.headers.pop('Referer') # request session headers diff --git a/sickbeard/network_timezones.py b/sickbeard/network_timezones.py index 78a9278693abe0abe64a6b0ec82fb37f4e0a1a4d..82f91f3fcfb56ac443cf1a36cc4ab2e77897d9ae 100644 --- a/sickbeard/network_timezones.py +++ b/sickbeard/network_timezones.py @@ -38,7 +38,7 @@ sb_timezone = tz.tzwinlocal() if tz.tzwinlocal else tz.tzlocal() def update_network_dict(): """Update timezone information from SR repositories""" - url = 'http://SickRage.github.io/sb_network_timezones/network_timezones.txt' + url = 'http://sickrage.github.io/sb_network_timezones/network_timezones.txt' url_data = helpers.getURL(url, session=requests.Session()) if not url_data: logger.log(u'Updating network timezones failed, this can happen from time to time. URL: %s' % url, logger.WARNING) diff --git a/sickbeard/postProcessor.py b/sickbeard/postProcessor.py index 598f28590a22e43e1f26ddf00e2eb46909a7d97d..1cd7afa6aa66f8b64fb2128e4c4bed4f6cd76f7d 100644 --- a/sickbeard/postProcessor.py +++ b/sickbeard/postProcessor.py @@ -39,6 +39,7 @@ from sickbeard.name_parser.parser import NameParser, InvalidNameException, Inval from sickrage.helper.encoding import ek from sickrage.helper.exceptions import EpisodeNotFoundException, EpisodePostProcessingFailedException, ex from sickrage.helper.exceptions import ShowDirectoryNotFoundException +from babelfish import language_converters import adba from sickbeard.helpers import verify_freespace @@ -190,10 +191,17 @@ class PostProcessor(object): checklist = glob.glob(ek(os.path.join, ek(os.path.dirname, globbable_file_path), '*')) # get a list of all the files in the folder for filefound in checklist: # loop through all the files in the folder, and check if they are the same name even when the cases don't match file_name = filefound.rpartition('.')[0] + file_extension = filefound.rpartition('.')[2] if not base_name_only: - file_name = file_name + '.' - if file_name.lower() == base_name.lower().replace('[[]', '[').replace('[]]', ']'): # if there's no difference in the filename add it to the filelist + new_file_name = file_name + '.' + if new_file_name.lower() == base_name.lower().replace('[[]', '[').replace('[]]', ']'): # if there's no difference in the filename add it to the filelist filelist.append(filefound) + elif file_extension in common.subtitleExtensions: + language_extensions = tuple('.' + c for c in language_converters['opensubtitles'].codes) + if file_name.lower().endswith(language_extensions) and (len(filefound.rsplit('.', 2)[1]) is 2 or 3): + filelist.append(filefound) + elif file_name.lower().endswith('pt-br') and len(filefound.rsplit('.', 2)[1]) is 5: + filelist.append(filefound) for associated_file_path in filelist: # only add associated to list @@ -299,7 +307,10 @@ class PostProcessor(object): # check if file have subtitles language if os.path.splitext(cur_extension)[1][1:] in common.subtitleExtensions: cur_lang = os.path.splitext(cur_extension)[0] - if cur_lang in sickbeard.subtitles.wantedLanguages(): + if cur_lang: + cur_lang = cur_lang.lower() + if cur_lang == 'pt-br': + cur_lang = 'pt-BR' cur_extension = cur_lang + os.path.splitext(cur_extension)[1] # replace .nfo with .nfo-orig to avoid conflicts @@ -313,7 +324,7 @@ class PostProcessor(object): else: new_file_name = helpers.replaceExtension(cur_file_name, cur_extension) - if sickbeard.SUBTITLES_DIR and cur_extension in common.subtitleExtensions: + if sickbeard.SUBTITLES_DIR and cur_extension[-3:] in common.subtitleExtensions: subs_new_path = ek(os.path.join, new_path, sickbeard.SUBTITLES_DIR) dir_exists = helpers.makeDir(subs_new_path) if not dir_exists: diff --git a/sickbeard/providers/bluetigers.py b/sickbeard/providers/bluetigers.py index 4c431edac135f07eee683b7782df652feda87182..bbe6e3f6e4b6324ba79b42e31d2032c8e96f10f7 100644 --- a/sickbeard/providers/bluetigers.py +++ b/sickbeard/providers/bluetigers.py @@ -83,6 +83,10 @@ class BLUETIGERSProvider(generic.TorrentProvider): results = [] items = {'Season': [], 'Episode': [], 'RSS': []} + + # check for auth + if not self._doLogin(): + return results for mode in search_strings.keys(): logger.log(u"Search Mode: %s" % mode, logger.DEBUG) diff --git a/sickbeard/providers/kat.py b/sickbeard/providers/kat.py index 0168c132268e8ce7744b95655d32792c2f55588a..7b097de4bec31582ae8e048a1c974b236db9fc41 100755 --- a/sickbeard/providers/kat.py +++ b/sickbeard/providers/kat.py @@ -47,8 +47,8 @@ class KATProvider(generic.TorrentProvider): self.cache = KATCache(self) self.urls = { - 'base_url': 'https://kickass.unblocked.la/', - 'search': 'https://kickass.unblocked.la/%s/', + 'base_url': 'https://kickass.unblocked.pe/', + 'search': 'https://kickass.unblocked.pe/%s/', } self.url = self.urls['base_url'] diff --git a/sickbeard/providers/newpct.py b/sickbeard/providers/newpct.py index ad1dd5412b1d4da7079fc73b8e25ad349aef0284..0985f73ce75456c0c0533597e4d23e555574c0c5 100644 --- a/sickbeard/providers/newpct.py +++ b/sickbeard/providers/newpct.py @@ -1,3 +1,4 @@ +# coding=utf-8 # Author: CristianBB # Greetings to Mr. Pine-apple # @@ -13,18 +14,19 @@ # 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 -# GNU General Public License for more details. +# 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/>. import traceback +import re from six.moves import urllib +from sickbeard import helpers from sickbeard import logger from sickbeard import tvcache from sickbeard.providers import generic -from sickbeard.common import USER_AGENT from sickbeard.bs4_parser import BS4Parser @@ -37,13 +39,16 @@ class newpctProvider(generic.TorrentProvider): self.onlyspasearch = None self.cache = newpctCache(self) + # Unsupported + # self.minseed = None + # self.minleech = None + self.urls = { 'base_url': 'http://www.newpct.com', 'search': 'http://www.newpct.com/buscar-descargas/' } self.url = self.urls['base_url'] - self.headers.update({'User-Agent': USER_AGENT}) """ Search query: @@ -71,14 +76,14 @@ class newpctProvider(generic.TorrentProvider): 'q': '' } + def _doSearch(self, search_strings, search_mode='eponly', epcount=0, age=0, epObj=None): results = [] items = {'Season': [], 'Episode': [], 'RSS': []} - lang_info = '' if not epObj or not epObj.show else epObj.show.lang - # Only search if user conditions are true + lang_info = '' if not epObj or not epObj.show else epObj.show.lang if self.onlyspasearch and lang_info != 'es': logger.log(u"Show info is not spanish, skipping provider search", logger.DEBUG) return results @@ -87,6 +92,9 @@ class newpctProvider(generic.TorrentProvider): logger.log(u"Search Mode: %s" % mode, logger.DEBUG) for search_string in search_strings[mode]: + if mode is not 'RSS': + logger.log(u"Search string: %s " % search_string, logger.DEBUG) + self.search_params.update({'q': search_string.strip()}) logger.log(u"Search URL: %s" % self.urls['search'] + '?' + urllib.parse.urlencode(self.search_params), logger.DEBUG) @@ -98,42 +106,90 @@ class newpctProvider(generic.TorrentProvider): with BS4Parser(data, features=["html5lib", "permissive"]) as html: torrent_tbody = html.find('tbody') - if len(torrent_tbody) < 1: + if not len(torrent_tbody): logger.log(u"Data returned from provider does not contain any torrents", logger.DEBUG) continue torrent_table = torrent_tbody.findAll('tr') - num_results = len(torrent_table) - 1 + if not len(torrent_table): + logger.log(u"Torrent table does not have any rows", logger.DEBUG) + continue - iteration = 0 - for row in torrent_table: + for row in torrent_table[:-1]: try: - if iteration < num_results: - torrent_size = row.findAll('td')[2] - torrent_row = row.findAll('a')[1] - - download_url = torrent_row.get('href') - title_raw = torrent_row.get('title') - size = self._convertSize(torrent_size.text) + torrent_size = row.findAll('td')[2] + torrent_row = row.findAll('a')[0] - title = self._processTitle(title_raw) + download_url = torrent_row.get('href', '') + size = self._convertSize(torrent_size.text) + title = self._processTitle(torrent_row.get('title', '')) - item = title, download_url, size - logger.log(u"Found result: %s " % title, logger.DEBUG) - - items[mode].append(item) - iteration += 1 + # FIXME: Provider does not provide seeders/leechers + seeders = 1 + leechers = 0 except (AttributeError, TypeError): continue + if not all([title, download_url]): + continue + + # Filter unseeded torrent (Unsupported) + # if seeders < self.minseed or leechers < self.minleech: + # if mode is not '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) + # continue + + item = title, download_url, size, seeders, leechers + if mode is not 'RSS': + 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) + # For each search mode sort all the items by seeders if available (Unsupported) + # items[mode].sort(key=lambda tup: tup[3], reverse=True) + results += items[mode] return results + def downloadResult(self, result): + """ + Save the result to disk. + """ + + # check for auth + if not self._doLogin(): + return False + + urls, filename = self._makeURL(result) + + for url in urls: + # Search results don't return torrent files directly, it returns show sheets so we must parse showSheet to access torrent. + data = self.getURL(url) + url_torrent = re.search(r'http://tumejorserie.com/descargar/.+\.torrent', data, re.DOTALL).group() + + if url_torrent.startswith('http'): + self.headers.update({'Referer': '/'.join(url_torrent.split('/')[:3]) + '/'}) + + logger.log(u"Downloading a result from " + self.name + " at " + url) + + if helpers.download_file(url_torrent, filename, session=self.session, headers=self.headers): + if self._verify_download(filename): + logger.log(u"Saved result to " + filename, logger.INFO) + return True + else: + logger.log(u"Could not download %s" % url, logger.WARNING) + helpers.remove_file_failed(filename) + + if len(urls): + logger.log(u"Failed to download any results", logger.WARNING) + + return False + @staticmethod def _convertSize(size): size, modifier = size.split(' ') @@ -148,9 +204,12 @@ class newpctProvider(generic.TorrentProvider): size = size * 1024**4 return int(size) - def _processTitle(self, title): - title = title.replace('Descargar ', '') + @staticmethod + def _processTitle(title): + + # Remove "Mas informacion sobre " literal from title + title = title[22:] # Quality title = title.replace('[HDTV]', '[720p HDTV x264]') @@ -169,8 +228,7 @@ class newpctProvider(generic.TorrentProvider): title = title.replace('[BluRay MicroHD]', '[1080p BlueRay x264]') title = title.replace('[MicroHD 1080p]', '[1080p BlueRay x264]') - return title - + return title.strip() class newpctCache(tvcache.TVCache): @@ -178,8 +236,11 @@ class newpctCache(tvcache.TVCache): tvcache.TVCache.__init__(self, provider_obj) - self.minTime = 30 + # set this 0 to suppress log line, since we aren't updating it anyways + self.minTime = 0 + def _getRSSData(self): + return {'entries': []} provider = newpctProvider() diff --git a/sickbeard/providers/thepiratebay.py b/sickbeard/providers/thepiratebay.py index c9dd88e0362489ec066bd16661932574907e5e16..aba4c0b2ed1997f8b8c497597a9a9766d8f2e16a 100644 --- a/sickbeard/providers/thepiratebay.py +++ b/sickbeard/providers/thepiratebay.py @@ -42,9 +42,9 @@ class ThePirateBayProvider(generic.TorrentProvider): self.cache = ThePirateBayCache(self) self.urls = { - 'base_url': 'https://pirateproxy.la/', - 'search': 'https://pirateproxy.la/s/', - 'rss': 'https://pirateproxy.la/tv/latest' + 'base_url': 'https://pirateproxy.pl/', + 'search': 'https://pirateproxy.pl/s/', + 'rss': 'https://pirateproxy.pl/tv/latest' } self.url = self.urls['base_url'] @@ -52,7 +52,7 @@ class ThePirateBayProvider(generic.TorrentProvider): """ 205 = SD, 208 = HD, 200 = All Videos - https://thepiratebay.gd/s/?q=Game of Thrones&type=search&orderby=7&page=0&category=200 + https://pirateproxy.pl/s/?q=Game of Thrones&type=search&orderby=7&page=0&category=200 """ self.search_params = { 'q': '', diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index 1d566da15b826afc308bc63724b71a2e06322df8..c35ab144898ce169d9cfd2fee6840a69b84f7804 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -2161,10 +2161,10 @@ class HomeChangeLog(Home): def index(self): try: - changes = helpers.getURL('http://SickRage.github.io/sickrage-news/CHANGES.md', session=requests.Session()) + changes = helpers.getURL('http://sickrage.github.io/sickrage-news/CHANGES.md', session=requests.Session()) except Exception: logger.log(u'Could not load changes from repo, giving a link!', logger.DEBUG) - changes = 'Could not load changes from the repo. [Click here for CHANGES.md](http://SickRage.github.io/sickrage-news/CHANGES.md)' + changes = 'Could not load changes from the repo. [Click here for CHANGES.md](http://sickrage.github.io/sickrage-news/CHANGES.md)' t = PageTemplate(rh=self, filename="markdown.mako") data = markdown2.markdown(changes if changes else "The was a problem connecting to github, please refresh and try again", extras=['header-ids']) @@ -2512,6 +2512,7 @@ class HomeAddShows(Home): try: popular_shows = imdb_popular.fetch_popular_shows() except Exception as e: + # print traceback.format_exc() popular_shows = None return t.render(title="Popular Shows", header="Popular Shows", popular_shows=popular_shows, imdb_exception=e, topmenu="home")