From 584f4a7c049a95564e45344e6a5bcf9c40af2fde Mon Sep 17 00:00:00 2001 From: panni Date: Sun, 16 Feb 2020 05:53:32 +0100 Subject: [PATCH] update subliminal_patch; improve scoring; improve bsplayer; possibly fix bazarr#821 --- libs/subliminal_patch/core.py | 9 ++-- libs/subliminal_patch/providers/bsplayer.py | 48 ++++++--------------- libs/subliminal_patch/score.py | 24 +++++++---- 3 files changed, 34 insertions(+), 47 deletions(-) diff --git a/libs/subliminal_patch/core.py b/libs/subliminal_patch/core.py index 81da38aae..2746522ff 100644 --- a/libs/subliminal_patch/core.py +++ b/libs/subliminal_patch/core.py @@ -360,15 +360,16 @@ class SZProviderPool(ProviderPool): orig_matches = matches.copy() logger.debug('%r: Found matches %r', s, matches) + score, score_without_hash = compute_score(matches, s, video, hearing_impaired=use_hearing_impaired) unsorted_subtitles.append( - (s, compute_score(matches, s, video, hearing_impaired=use_hearing_impaired), matches, orig_matches)) + (s, score, score_without_hash, matches, orig_matches)) # sort subtitles by score - scored_subtitles = sorted(unsorted_subtitles, key=operator.itemgetter(1), reverse=True) + scored_subtitles = sorted(unsorted_subtitles, key=operator.itemgetter(1, 2), reverse=True) # download best subtitles, falling back on the next on error downloaded_subtitles = [] - for subtitle, score, matches, orig_matches in scored_subtitles: + for subtitle, score, score_without_hash, matches, orig_matches in scored_subtitles: # check score if score < min_score: logger.info('%r: Score %d is below min_score (%d)', subtitle, score, min_score) @@ -552,7 +553,7 @@ def scan_video(path, dont_use_actual_file=False, hints=None, providers=None, ski video.hashes['bsplayer'] = osub_hash = hash_opensubtitles(hash_path) if "opensubtitles" in providers: - video.hashes['opensubtitles'] = osub_hash = hash_opensubtitles(hash_path) + video.hashes['opensubtitles'] = osub_hash = osub_hash or hash_opensubtitles(hash_path) if "shooter" in providers: video.hashes['shooter'] = hash_shooter(hash_path) diff --git a/libs/subliminal_patch/providers/bsplayer.py b/libs/subliminal_patch/providers/bsplayer.py index 9839a0331..f6eb20db4 100644 --- a/libs/subliminal_patch/providers/bsplayer.py +++ b/libs/subliminal_patch/providers/bsplayer.py @@ -19,9 +19,11 @@ from xml.etree import ElementTree logger = logging.getLogger(__name__) + class BSPlayerSubtitle(Subtitle): """BSPlayer Subtitle.""" provider_name = 'bsplayer' + hash_verifiable = True def __init__(self, language, filename, subtype, video, link): super(BSPlayerSubtitle, self).__init__(language) @@ -41,27 +43,12 @@ class BSPlayerSubtitle(Subtitle): def get_matches(self, video): matches = set() - - video_filename = video.name - video_filename = os.path.basename(video_filename) - video_filename, _ = os.path.splitext(video_filename) - video_filename = sanitize_release_group(video_filename) - - subtitle_filename = self.filename - subtitle_filename = os.path.basename(subtitle_filename) - subtitle_filename, _ = os.path.splitext(subtitle_filename) - subtitle_filename = sanitize_release_group(subtitle_filename) - - matches |= guess_matches(video, guessit(self.filename)) - - matches.add(id(self)) matches.add('hash') return matches - class BSPlayerProvider(Provider): """BSPlayer Provider.""" languages = {Language('por', 'BR')} | {Language(l) for l in [ @@ -69,6 +56,7 @@ class BSPlayerProvider(Provider): 'ron', 'rus', 'spa', 'swe', 'tur', 'ukr', 'zho' ]} SEARCH_THROTTLE = 8 + hash_verifiable = True # batantly based on kodi's bsplayer plugin # also took from BSPlayer-Subtitles-Downloader @@ -108,18 +96,11 @@ class BSPlayerProvider(Provider): res = self.session.post(self.search_url, data) return ElementTree.fromstring(res.text) - ### with requests - # res = requests.post( - # url=self.search_url, - # data=data, - # headers=headers - # ) - # return ElementTree.fromstring(res.text) - except Exception as ex: logger.info("ERROR: %s." % ex) if func_name == 'logIn': self.search_url = self.get_sub_domain() + sleep(1) logger.info('ERROR: Too many tries (%d)...' % tries) raise Exception('Too many tries...') @@ -167,7 +148,6 @@ class BSPlayerProvider(Provider): # language_ids = 'spa' language_ids = ','.join(sorted(l.opensubtitles for l in language)) - if video.imdb_id is None: imdbId = '*' else: @@ -193,13 +173,13 @@ class BSPlayerProvider(Provider): if items: logger.info("Subtitles Found.") for item in items: - subID=item.find('subID').text - subDownloadLink=item.find('subDownloadLink').text - subLang= Language.fromopensubtitles(item.find('subLang').text) - subName=item.find('subName').text - subFormat=item.find('subFormat').text + subID = item.find('subID').text + subDownloadLink = item.find('subDownloadLink').text + subLang = Language.fromopensubtitles(item.find('subLang').text) + subName = item.find('subName').text + subFormat = item.find('subFormat').text subtitles.append( - BSPlayerSubtitle(subLang,subName, subFormat, video, subDownloadLink) + BSPlayerSubtitle(subLang, subName, subFormat, video, subDownloadLink) ) return subtitles @@ -207,9 +187,9 @@ class BSPlayerProvider(Provider): return self.query(video, video.hashes['bsplayer'], languages) def get_sub_domain(self): - # s1-9, s101-109 + # s1-9, s101-109 SUB_DOMAINS = ['s1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', - 's101', 's102', 's103', 's104', 's105', 's106', 's107', 's108', 's109'] + 's101', 's102', 's103', 's104', 's105', 's106', 's107', 's108', 's109'] API_URL_TEMPLATE = "http://{sub_domain}.api.bsplayer-subtitles.com/v1.php" sub_domains_end = len(SUB_DOMAINS) - 1 return API_URL_TEMPLATE.format(sub_domain=SUB_DOMAINS[random.randint(0, sub_domains_end)]) @@ -226,10 +206,8 @@ class BSPlayerProvider(Provider): raise ValueError('Error 500 on server') with gzip.GzipFile(fileobj=io.BytesIO(res.content)) as gf: - subtitle.content = gf.read() + subtitle.content = gf.read() subtitle.normalize() return subtitle raise ValueError('Problems conecting to the server') - - diff --git a/libs/subliminal_patch/score.py b/libs/subliminal_patch/score.py index c7b687e8c..286a2ac58 100644 --- a/libs/subliminal_patch/score.py +++ b/libs/subliminal_patch/score.py @@ -61,6 +61,8 @@ def compute_score(matches, subtitle, video, hearing_impaired=None): episode_hash_valid_if = {"series", "season", "episode", "format"} movie_hash_valid_if = {"video_codec", "format"} + orig_matches = matches.copy() + # on hash match, discard everything else if subtitle.hash_verifiable: if 'hash' in matches: @@ -84,41 +86,47 @@ def compute_score(matches, subtitle, video, hearing_impaired=None): matches &= {'hash'} # handle equivalent matches + eq_matches = set() if is_episode: if 'title' in matches: logger.debug('Adding title match equivalent') - matches.add('episode') + eq_matches.add('episode') if 'series_imdb_id' in matches: logger.debug('Adding series_imdb_id match equivalent') - matches |= {'series', 'year'} + eq_matches |= {'series', 'year'} if 'imdb_id' in matches: logger.debug('Adding imdb_id match equivalents') - matches |= {'series', 'year', 'season', 'episode'} + eq_matches |= {'series', 'year', 'season', 'episode'} if 'tvdb_id' in matches: logger.debug('Adding tvdb_id match equivalents') - matches |= {'series', 'year', 'season', 'episode', 'title'} + eq_matches |= {'series', 'year', 'season', 'episode', 'title'} if 'series_tvdb_id' in matches: logger.debug('Adding series_tvdb_id match equivalents') - matches |= {'series', 'year'} + eq_matches |= {'series', 'year'} # specials if video.is_special and 'title' in matches and 'series' in matches \ and 'year' in matches: logger.debug('Adding special title match equivalent') - matches |= {'season', 'episode'} + eq_matches |= {'season', 'episode'} elif is_movie: if 'imdb_id' in matches: logger.debug('Adding imdb_id match equivalents') - matches |= {'title', 'year'} + eq_matches |= {'title', 'year'} + + matches |= eq_matches # handle hearing impaired if hearing_impaired is not None and subtitle.hearing_impaired == hearing_impaired: logger.debug('Matched hearing_impaired') matches.add('hearing_impaired') + orig_matches.add('hearing_impaired') # compute the score score = sum((scores.get(match, 0) for match in matches)) logger.info('%r: Computed score %r with final matches %r', subtitle, score, matches) - return score + score_without_hash = sum((scores.get(match, 0) for match in orig_matches | eq_matches if match != "hash")) + + return score, score_without_hash