From 14f3848872e460132d707ee0f443534c086bb067 Mon Sep 17 00:00:00 2001 From: Ofir Brukner Date: Sun, 12 Oct 2014 16:19:34 +0300 Subject: [PATCH 1/2] Added all logic related to subscenter, including logo --- gui/slick/images/subtitles/subscenter.png | Bin 0 -> 3841 bytes lib/subliminal/core.py | 3 +- lib/subliminal/services/subscenter.py | 116 ++++++++++++++++++++++ 3 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 gui/slick/images/subtitles/subscenter.png create mode 100644 lib/subliminal/services/subscenter.py diff --git a/gui/slick/images/subtitles/subscenter.png b/gui/slick/images/subtitles/subscenter.png new file mode 100644 index 0000000000000000000000000000000000000000..84389c5763885d840c67b07cae71f25aa3967faa GIT binary patch literal 3841 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 Dm9a2B literal 0 HcmV?d00001 diff --git a/lib/subliminal/core.py b/lib/subliminal/core.py index 9c3fa3dc..0ecbf3f6 100644 --- a/lib/subliminal/core.py +++ b/lib/subliminal/core.py @@ -32,7 +32,8 @@ __all__ = ['SERVICES', 'LANGUAGE_INDEX', 'SERVICE_INDEX', 'SERVICE_CONFIDENCE', 'create_list_tasks', 'create_download_tasks', 'consume_task', 'matching_confidence', 'key_subtitles', 'group_by_video'] logger = logging.getLogger("subliminal") -SERVICES = ['opensubtitles', 'subswiki', 'subtitulos', 'thesubdb', 'addic7ed', 'tvsubtitles', 'itasa', 'usub'] +SERVICES = ['opensubtitles', 'subswiki', 'subtitulos', 'thesubdb', 'addic7ed', 'tvsubtitles', 'itasa', + 'usub', 'subscenter'] LANGUAGE_INDEX, SERVICE_INDEX, SERVICE_CONFIDENCE, MATCHING_CONFIDENCE = range(4) diff --git a/lib/subliminal/services/subscenter.py b/lib/subliminal/services/subscenter.py new file mode 100644 index 00000000..23eaad5e --- /dev/null +++ b/lib/subliminal/services/subscenter.py @@ -0,0 +1,116 @@ +# -*- coding: utf-8 -*- +# Copyright 2012 Ofir Brukner +# +# This file is part of subliminal. +# +# subliminal is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# subliminal 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with subliminal. If not, see . +import logging +import re +import json +import os +from . import ServiceBase +from ..exceptions import DownloadFailedError, ServiceError +from ..language import language_set +from ..subtitles import get_subtitle_path, ResultSubtitle +from ..videos import Episode, Movie +from ..utils import to_unicode, get_keywords + + +logger = logging.getLogger("subliminal") + + +class Subscenter(ServiceBase): + server_url = 'http://subscenter.cinemast.com/he/' + site_url = 'http://subscenter.cinemast.com/' + api_based = False + languages = language_set(['he', 'en']) + videos = [Episode, Movie] + require_video = False + required_features = ['permissive'] + + @staticmethod + def slugify(string): + new_string = string.replace(' ', '-').replace("'", '').replace(':', '').lower() + # We remove multiple spaces by using this regular expression. + return re.sub('-+', '-', new_string) + + def list_checked(self, video, languages): + series = None + season = None + episode = None + title = video.title + if isinstance(video, Episode): + series = video.series + season = video.season + episode = video.episode + return self.query(video.path or video.release, languages, get_keywords(video.guess), series, season, + episode, title) + + def query(self, filepath, languages=None, keywords=None, series=None, season=None, episode=None, title=None): + logger.debug(u'Getting subtitles for %s season %d episode %d with languages %r' % (series, season, episode, languages)) + # Converts the title to Subscenter format by replacing whitespaces and removing specific chars. + if series and season and episode: + # Search for a TV show. + kind = 'episode' + slugified_series = self.slugify(series) + url = self.server_url + 'cinemast/data/series/sb/' + slugified_series + '/' + str(season) + '/' + \ + str(episode) + '/' + elif title: + # Search for a movie. + kind = 'movie' + slugified_title = self.slugify(title) + url = self.server_url + 'cinemast/data/movie/sb/' + slugified_title + '/' + else: + raise ServiceError('One or more parameters are missing') + logger.debug('Searching subtitles %r', {'title': title, 'season': season, 'episode': episode}) + response = self.session.get(url) + if response.status_code != 200: + raise ServiceError('Request failed with status code %d' % response.status_code) + + subtitles = [] + response_json = json.loads(response.content) + for lang, lang_json in response_json.items(): + lang_obj = self.get_language(lang) + if lang_obj in self.languages and lang in languages: + for group_data in lang_json.values(): + for quality in group_data.values(): + for sub in quality.values(): + release = sub.get('subtitle_version') + sub_path = get_subtitle_path(filepath, lang_obj, self.config.multi) + link = self.server_url + 'subtitle/download/' + lang + '/' + str(sub.get('id')) + \ + '/?v=' + release + '&key=' + str(sub.get('key')) + subtitles.append(ResultSubtitle(sub_path, lang_obj, self.__class__.__name__.lower(), + link, release=to_unicode(release))) + return subtitles + + def download(self, subtitle): + logger.info(u'Downloading %s in %s' % (subtitle.link, subtitle.path)) + try: + r = self.session.get(subtitle.link, headers={'Referer': subtitle.link, 'User-Agent': self.user_agent}) + if r.status_code != 200: + raise DownloadFailedError('Request failed with status code %d' % r.status_code) + if r.headers['Content-Type'] == 'text/html': + raise DownloadFailedError('Download limit exceeded') + with open(subtitle.path, 'wb') as f: + f.write(r.content) + except Exception as e: + logger.error(u'Download failed: %s' % e) + if os.path.exists(subtitle.path): + os.remove(subtitle.path) + raise DownloadFailedError(str(e)) + logger.debug(u'Download finished') + return subtitle + + +Service = Subscenter \ No newline at end of file From b0426ca12d82091f158abfa89802294ae50ee5d2 Mon Sep 17 00:00:00 2001 From: Ofir Brukner Date: Mon, 13 Oct 2014 00:25:06 +0300 Subject: [PATCH 2/2] Fixed a few bugs. Also fixed buggy search function in webserve. --- lib/subliminal/services/subscenter.py | 23 ++++------------------- sickbeard/webserve.py | 14 ++++++-------- 2 files changed, 10 insertions(+), 27 deletions(-) diff --git a/lib/subliminal/services/subscenter.py b/lib/subliminal/services/subscenter.py index 23eaad5e..3646c50b 100644 --- a/lib/subliminal/services/subscenter.py +++ b/lib/subliminal/services/subscenter.py @@ -18,9 +18,8 @@ import logging import re import json -import os from . import ServiceBase -from ..exceptions import DownloadFailedError, ServiceError +from ..exceptions import ServiceError from ..language import language_set from ..subtitles import get_subtitle_path, ResultSubtitle from ..videos import Episode, Movie @@ -82,34 +81,20 @@ class Subscenter(ServiceBase): response_json = json.loads(response.content) for lang, lang_json in response_json.items(): lang_obj = self.get_language(lang) - if lang_obj in self.languages and lang in languages: + if lang_obj in self.languages and lang_obj in languages: for group_data in lang_json.values(): for quality in group_data.values(): for sub in quality.values(): release = sub.get('subtitle_version') sub_path = get_subtitle_path(filepath, lang_obj, self.config.multi) link = self.server_url + 'subtitle/download/' + lang + '/' + str(sub.get('id')) + \ - '/?v=' + release + '&key=' + str(sub.get('key')) + '/?v=' + release + '&key=' + str(sub.get('key')) subtitles.append(ResultSubtitle(sub_path, lang_obj, self.__class__.__name__.lower(), link, release=to_unicode(release))) return subtitles def download(self, subtitle): - logger.info(u'Downloading %s in %s' % (subtitle.link, subtitle.path)) - try: - r = self.session.get(subtitle.link, headers={'Referer': subtitle.link, 'User-Agent': self.user_agent}) - if r.status_code != 200: - raise DownloadFailedError('Request failed with status code %d' % r.status_code) - if r.headers['Content-Type'] == 'text/html': - raise DownloadFailedError('Download limit exceeded') - with open(subtitle.path, 'wb') as f: - f.write(r.content) - except Exception as e: - logger.error(u'Download failed: %s' % e) - if os.path.exists(subtitle.path): - os.remove(subtitle.path) - raise DownloadFailedError(str(e)) - logger.debug(u'Download finished') + self.download_zip_file(subtitle.link, subtitle.path) return subtitle diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index c8f2f951..46e88f5e 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -4451,30 +4451,28 @@ class Home(MainHandler): return quality_class def searchEpisodeSubtitles(self, show=None, season=None, episode=None): - # retrieve the episode object and fail if we can't get one ep_obj = _getEpisode(show, season, episode) if isinstance(ep_obj, str): return json.dumps({'result': 'failure'}) # try do download subtitles for that episode - previous_subtitles = ep_obj.subtitles + previous_subtitles = set(subliminal.language.Language(x) for x in ep_obj.subtitles) try: - ep_obj.subtitles = ep_obj.downloadSubtitles() + ep_obj.subtitles = set(x.language for x in ep_obj.downloadSubtitles().values()[0]) except: return json.dumps({'result': 'failure'}) # return the correct json value if previous_subtitles != ep_obj.subtitles: status = 'New subtitles downloaded: %s' % ' '.join([ - "" + subliminal.language.Language(x).name + "" for x in - sorted(list(set(ep_obj.subtitles).difference(previous_subtitles)))]) + "" + x.name + "" for x in + sorted(list(ep_obj.subtitles.difference(previous_subtitles)))]) else: status = 'No subtitles downloaded' ui.notifications.message('Subtitles Search', status) - return json.dumps({'result': status, 'subtitles': ','.join([x for x in ep_obj.subtitles])}) - + return json.dumps({'result': status, 'subtitles': ','.join([x.alpha2 for x in ep_obj.subtitles])}) def setSceneNumbering(self, show, indexer, forSeason=None, forEpisode=None, forAbsolute=None, sceneSeason=None, sceneEpisode=None, sceneAbsolute=None):