def _list_subtitles(): # list subtitles with AsyncProviderPool( providers=self.config.providers, provider_configs=self.config.provider_configs) as pool: subtitles = pool.list_subtitles(video, self.config.languages) # fill the subtitle liststore subtitle_liststore = builder.get_object('subtitle_liststore') for s in subtitles: scaled_score = compute_score(s, video) scores = get_scores(video) if s.hearing_impaired == self.config.hearing_impaired: scaled_score -= scores['hearing_impaired'] scaled_score *= 100 / scores['hash'] subtitle_liststore.append([ s.id, nice_language(s.language), scaled_score, s.provider_name.capitalize(), s.hearing_impaired, s.page_link, False ]) subtitle_liststore.set_sort_column_id(2, Gtk.SortType.DESCENDING) # stop the spinner spinner.stop() # connect signals builder.connect_signals( ChooseHandler(self.config, video, subtitles, spinner))
def search(self, path, languages): languages = {language_converter.from_english(l): l for l in languages} xbmc.log('Languages: %s' % languages, level=xbmc.LOGDEBUG) video = self.get_video(path) providers = self.get_providers() provider_configs = self.get_provider_configs() max_workers = self.get_max_workers() xbmc.log('Providers: %s' % providers, level=xbmc.LOGDEBUG) xbmc.log('Provider Configs: %s' % provider_configs, level=xbmc.LOGDEBUG) with AsyncProviderPool(max_workers=max_workers, providers=providers, provider_configs=provider_configs) as p: subtitles = p.list_subtitles(video, languages=set(languages.keys())) max_score = episode_scores['hash'] if isinstance(video, Episode) else movie_scores['hash'] scored_subtitles = sorted([(s, compute_score(s, video)) for s in subtitles], key=operator.itemgetter(1), reverse=True) for subtitle, score in scored_subtitles: option = SubtitleOption(subtitle) option.get_subtitle(subtitle.id) l = languages[subtitle.language] release_name = '[%s] %s' % (subtitle.provider_name, self.get_release_name(subtitle)) rating = int(round(float(5 * (score+2)/max_score))) sync = score + 2 >= max_score option.add_directory_item(self.base_url, self.handle, release_name, l, rating, sync) xbmc.log('%s' % subtitles, level=xbmc.LOGDEBUG) return True
def _download_subtitle(): # download the subtitle with AsyncProviderPool( providers=self.config.providers, provider_configs=self.config.provider_configs) as pool: pool.download_subtitle(subtitle) # save the subtitle save_subtitles(self.video, [subtitle], single=self.config.single) # mark the subtitle as downloaded model.set_value(iter, 6, True) # stop the spinner self.spinner.stop()
def run(self, scan_path, scan_age, languages, encoding, min_score, providers, provider_configs, max_workers, plex_url=None, plex_token=None, *args, **kwargs): if not os.path.isdir(scan_path): raise IOError('Path \'%s\' doesn\'t exist!' % scan_path) if not scan_age >= 1: raise ValueError('\'scan_age\' must by at least 1!') if not len(languages) >= 1: raise ValueError('\'languages\' list can\'t be empty!') if not providers: raise ValueError('\'providers\' argument can\'t be empty!') if not max_workers >= 1: raise ValueError('\'max_workers\' must be at least 1!') if not provider_configs: provider_configs = {} __tree_dict = lambda: defaultdict(__tree_dict) result = __tree_dict() encoding = codecs.lookup(encoding).name age = timedelta(weeks=scan_age) languages = set([Language(l) for l in languages]) plex = None if plex_url and plex_token: plex = PlexServer(plex_url, plex_token) scan_start = datetime.now() videos = [] ignored_videos = [] if not region.is_configured: region.configure('dogpile.cache.dbm', expiration_time=timedelta(days=30), arguments={ 'filename': 'subliminal.dbm', 'lock_factory': MutexLock }) # scan videos scanned_videos = scan_videos(scan_path, age=age) for video in scanned_videos: video.subtitle_languages |= set( search_external_subtitles(video.name).values()) if check_video(video, languages=languages, age=age, undefined=False): refine(video) if languages - video.subtitle_languages: videos.append(video) else: ignored_videos.append(video) else: ignored_videos.append(video) if videos: result['videos']['collected'] = [ os.path.split(v.name)[1] for v in videos ] if ignored_videos: result['videos']['ignored'] = len(ignored_videos) if videos: # download best subtitles downloaded_subtitles = defaultdict(list) with AsyncProviderPool(max_workers=max_workers, providers=providers, provider_configs=provider_configs) as p: for video in videos: scores = get_scores(video) subtitles_to_download = p.list_subtitles( video, languages - video.subtitle_languages) downloaded_subtitles[video] = p.download_best_subtitles( subtitles_to_download, video, languages, min_score=scores['hash'] * min_score / 100) if p.discarded_providers: result['providers']['discarded'] = list( p.discarded_providers) # filter subtitles with TinyDB('subtitle_db.json') as db: table = db.table('downloaded') query = Query() for video, subtitles in downloaded_subtitles.items(): discarded_subtitles = list() discarded_subtitles_info = list() for s in subtitles: subtitle_hash = hashlib.sha256(s.content).hexdigest() subtitle_file = get_subtitle_path( os.path.split(video.name)[1], s.language) dbo = {'hash': subtitle_hash, 'file': subtitle_file} if table.search((query.hash == subtitle_hash) & (query.file == subtitle_file)): discarded_subtitles.append(s) discarded_subtitles_info.append(dbo) else: table.insert(dbo) downloaded_subtitles[video] = [ x for x in subtitles if x not in discarded_subtitles ] if discarded_subtitles_info: result['subtitles'][ 'discarded'] = result['subtitles'].get( 'discarded', []) + discarded_subtitles_info downloaded_subtitles = { k: v for k, v in downloaded_subtitles.items() if v } # save subtitles saved_subtitles = {} for video, subtitles in downloaded_subtitles.items(): saved_subtitles[video] = save_subtitles(video, subtitles, directory=None, encoding=encoding) for key, group in groupby(saved_subtitles[video], lambda x: x.provider_name): subtitle_filenames = [ get_subtitle_path( os.path.split(video.name)[1], s.language) for s in list(group) ] result['subtitles'][key] = result['subtitles'].get( key, []) + subtitle_filenames result['subtitles']['total'] = sum( len(v) for v in saved_subtitles.values()) # refresh plex for video, subtitles in saved_subtitles.items(): if plex and subtitles: item_found = False for section in plex.library.sections(): try: if isinstance(section, MovieSection) and isinstance( video, Movie): results = section.search(title=video.title, year=video.year, libtype='movie', sort='addedAt:desc', maxresults=1) if not results: raise NotFound plex_item = results[0] elif isinstance(section, ShowSection) and isinstance( video, Episode): results = section.search(title=video.series, year=video.year, libtype='show', sort='addedAt:desc', maxresults=1) if not results: raise NotFound plex_item = results[0].episode( season=video.season, episode=video.episode) else: continue except NotFound: continue except BadRequest: continue if plex_item: plex_item.refresh() result['plex']['refreshed'] = result['plex'].get( 'refreshed', []) + [ '%s%s' % (repr(plex_item.section()), repr(video)) ] item_found = True if not item_found: result['plex']['failed'] = result['plex'].get( 'failed', []) + [repr(video)] # convert subtitles for video, subtitles in saved_subtitles.items(): target_format = aeidon.formats.SUBRIP for s in subtitles: subtitle_path = get_subtitle_path(video.name, s.language) source_format = aeidon.util.detect_format( subtitle_path, encoding) source_file = aeidon.files.new( source_format, subtitle_path, aeidon.encodings.detect_bom(subtitle_path) or encoding) if source_format != target_format: format_info = { 'file': get_subtitle_path( os.path.split(video.name)[1], s.language), 'from': source_format.label, 'to': target_format.label } result['subtitles'][ 'converted'] = result['subtitles'].get( 'converted', []) + [format_info] aeidon_subtitles = source_file.read() for f in [ aeidon.formats.SUBRIP, aeidon.formats.MICRODVD, aeidon.formats.MPL2 ]: markup = aeidon.markups.new(f) for s in aeidon_subtitles: s.main_text = markup.decode(s.main_text) markup = aeidon.markups.new(target_format) for s in aeidon_subtitles: s.main_text = markup.encode(s.main_text) target_file = aeidon.files.new(target_format, subtitle_path, encoding) target_file.write(aeidon_subtitles, aeidon.documents.MAIN) scan_end = datetime.now() result['meta']['start'] = scan_start.isoformat() result['meta']['end'] = scan_end.isoformat() result['meta']['duration'] = str(scan_end - scan_start) return result
def download(obj, provider, refiner, language, age, directory, encoding, single, force, hearing_impaired, min_score, max_workers, archives, verbose, path): """Download best subtitles. PATH can be an directory containing videos, a video file path or a video file name. It can be used multiple times. If an existing subtitle is detected (external or embedded) in the correct language, the download is skipped for the associated video. """ # process parameters language = set(language) # scan videos videos = [] ignored_videos = [] errored_paths = [] with click.progressbar(path, label='Collecting videos', item_show_func=lambda p: p or '') as bar: for p in bar: logger.debug('Collecting path %s', p) # non-existing if not os.path.exists(p): try: video = Video.fromname(p) except: logger.exception( 'Unexpected error while collecting non-existing path %s', p) errored_paths.append(p) continue if not force: video.subtitle_languages |= set( search_external_subtitles( video.name, directory=directory).values()) refine(video, episode_refiners=refiner, movie_refiners=refiner, embedded_subtitles=not force) videos.append(video) continue # directories if os.path.isdir(p): try: scanned_videos = scan_videos(p, age=age, archives=archives) except: logger.exception( 'Unexpected error while collecting directory path %s', p) errored_paths.append(p) continue for video in scanned_videos: if check_video(video, languages=language, age=age, undefined=single): if not force: video.subtitle_languages |= set( search_external_subtitles( video.name, directory=directory).values()) refine(video, episode_refiners=refiner, movie_refiners=refiner, embedded_subtitles=not force) videos.append(video) else: ignored_videos.append(video) continue # other inputs try: video = scan_video(p) except: logger.exception('Unexpected error while collecting path %s', p) errored_paths.append(p) continue if check_video(video, languages=language, age=age, undefined=single): if not force: video.subtitle_languages |= set( search_external_subtitles( video.name, directory=directory).values()) refine(video, episode_refiners=refiner, movie_refiners=refiner, embedded_subtitles=not force) videos.append(video) else: ignored_videos.append(video) # output errored paths if verbose > 0: for p in errored_paths: click.secho('%s errored' % p, fg='red') # output ignored videos if verbose > 1: for video in ignored_videos: click.secho( '%s ignored - subtitles: %s / age: %d day%s' % (os.path.split(video.name)[1], ', '.join(str(s) for s in video.subtitle_languages) or 'none', video.age.days, 's' if video.age.days > 1 else ''), fg='yellow') # report collected videos click.echo('%s video%s collected / %s video%s ignored / %s error%s' % ( click.style( str(len(videos)), bold=True, fg='green' if videos else None), 's' if len(videos) > 1 else '', click.style(str(len(ignored_videos)), bold=True, fg='yellow' if ignored_videos else None), 's' if len(ignored_videos) > 1 else '', click.style(str(len(errored_paths)), bold=True, fg='red' if errored_paths else None), 's' if len(errored_paths) > 1 else '', )) # exit if no video collected if not videos: return # download best subtitles downloaded_subtitles = defaultdict(list) with AsyncProviderPool(max_workers=max_workers, providers=provider, provider_configs=obj['provider_configs']) as p: with click.progressbar( videos, label='Downloading subtitles', item_show_func=lambda v: os.path.split(v.name)[1] if v is not None else '') as bar: for v in bar: scores = get_scores(v) subtitles = p.download_best_subtitles( p.list_subtitles(v, language - v.subtitle_languages), v, language, min_score=scores['hash'] * min_score / 100, hearing_impaired=hearing_impaired, only_one=single) downloaded_subtitles[v] = subtitles if p.discarded_providers: click.secho( 'Some providers have been discarded due to unexpected errors: %s' % ', '.join(p.discarded_providers), fg='yellow') # save subtitles total_subtitles = 0 for v, subtitles in downloaded_subtitles.items(): saved_subtitles = save_subtitles(v, subtitles, single=single, directory=directory, encoding=encoding) total_subtitles += len(saved_subtitles) if verbose > 0: click.echo( '%s subtitle%s downloaded for %s' % (click.style(str(len(saved_subtitles)), bold=True), 's' if len(saved_subtitles) > 1 else '', os.path.split(v.name)[1])) if verbose > 1: for s in saved_subtitles: matches = s.get_matches(v) score = compute_score(s, v) # score color score_color = None scores = get_scores(v) if isinstance(v, Movie): if score < scores['title']: score_color = 'red' elif score < scores['title'] + scores['year'] + scores[ 'release_group']: score_color = 'yellow' else: score_color = 'green' elif isinstance(v, Episode): if score < scores['series'] + scores['season'] + scores[ 'episode']: score_color = 'red' elif score < scores['series'] + scores['season'] + scores[ 'episode'] + scores['release_group']: score_color = 'yellow' else: score_color = 'green' # scale score from 0 to 100 taking out preferences scaled_score = score if s.hearing_impaired == hearing_impaired: scaled_score -= scores['hearing_impaired'] scaled_score *= 100 / scores['hash'] # echo some nice colored output click.echo( ' - [{score}] {language} subtitle from {provider_name} (match on {matches})' .format(score=click.style('{:5.1f}'.format(scaled_score), fg=score_color, bold=score >= scores['hash']), language=s.language.name if s.language.country is None else '%s (%s)' % (s.language.name, s.language.country.name), provider_name=s.provider_name, matches=', '.join( sorted(matches, key=scores.get, reverse=True)))) if verbose == 0: click.echo('Downloaded %s subtitle%s' % (click.style(str(total_subtitles), bold=True), 's' if total_subtitles > 1 else ''))
def download_callback(self, menuitem, files): # scan videos videos = [] for f in files: # ignore non-writable locations if not f.can_write(): continue # directories if f.is_directory(): try: scanned_videos = scan_videos(f.get_location().get_path()) except: continue for video in scanned_videos: if check_video(video, languages=self.config.languages, age=self.config.age, undefined=self.config.single): video.subtitle_languages |= set( search_external_subtitles(video.name).values()) refine( video, episode_refiners=self.config.refiners, movie_refiners=self.config.refiners, embedded_subtitles=self.config.embedded_subtitles) videos.append(video) continue # other inputs try: video = scan_video(f.get_location().get_path()) except: continue if check_video(video, languages=self.config.languages, undefined=self.config.single): video.subtitle_languages |= set( search_external_subtitles(video.name).values()) refine(video, episode_refiners=self.config.refiners, movie_refiners=self.config.refiners, embedded_subtitles=self.config.embedded_subtitles) videos.append(video) # download best subtitles downloaded_subtitles = defaultdict(list) with AsyncProviderPool( providers=self.config.providers, provider_configs=self.config.provider_configs) as pool: for v in videos: scores = get_scores(v) subtitles = pool.download_best_subtitles( pool.list_subtitles( v, self.config.languages - v.subtitle_languages), v, self.config.languages, min_score=scores['hash'] * self.config.min_score / 100, hearing_impaired=self.config.hearing_impaired, only_one=self.config.single) downloaded_subtitles[v] = subtitles # save subtitles for v, subtitles in downloaded_subtitles.items(): save_subtitles(v, subtitles, single=self.config.single)
def download_subtitle(path, language, hi, providers, providers_auth, sceneName, media_type): if hi == "True": hi = True else: hi = False language_set = set() if language == 'pob': language_set.add(Language('por', 'BR')) else: language_set.add(Language(language)) use_scenename = get_general_settings()[9] minimum_score = get_general_settings()[8] minimum_score_movie = get_general_settings()[22] use_postprocessing = get_general_settings()[10] postprocessing_cmd = get_general_settings()[11] try: if sceneName == "None" or use_scenename is False: used_sceneName = False video = scan_video(path) else: used_sceneName = True video = Video.fromname(sceneName) except Exception as e: logging.exception("Error trying to get video information for this file: " + path) else: if media_type == "movie": max_score = 120.0 elif media_type == "series": max_score = 360.0 try: with AsyncProviderPool(max_workers=None, providers=providers, provider_configs=providers_auth) as p: subtitles = p.list_subtitles(video, language_set) except Exception as e: logging.exception("Error trying to get subtitle list from provider") else: subtitles_list = [] sorted_subtitles = sorted([(s, compute_score(s, video, hearing_impaired=hi)) for s in subtitles], key=operator.itemgetter(1), reverse=True) for s, preliminary_score in sorted_subtitles: if media_type == "movie": if (preliminary_score / max_score * 100) < int(minimum_score_movie): continue matched = set(s.get_matches(video)) if hi == s.hearing_impaired: matched.add('hearing_impaired') not_matched = set(score.movie_scores.keys()) - matched required = set(['title']) if any(elem in required for elem in not_matched): continue elif media_type == "series": if (preliminary_score / max_score * 100) < int(minimum_score): continue matched = set(s.get_matches(video)) if hi == s.hearing_impaired: matched.add('hearing_impaired') not_matched = set(score.episode_scores.keys()) - matched required = set(['series', 'season', 'episode']) if any(elem in required for elem in not_matched): continue subtitles_list.append(s) if len(subtitles_list) > 0: best_subtitle = subtitles_list[0] download_subtitles([best_subtitle], providers=providers, provider_configs=providers_auth) try: calculated_score = round(float(compute_score(best_subtitle, video, hearing_impaired=hi)) / max_score * 100, 2) if used_sceneName == True: video = scan_video(path) single = get_general_settings()[7] if single is True: result = save_subtitles(video, [best_subtitle], single=True, encoding='utf-8') else: result = save_subtitles(video, [best_subtitle], encoding='utf-8') except Exception as e: logging.exception('Error saving subtitles file to disk.') return None else: if len(result) > 0: downloaded_provider = result[0].provider_name downloaded_language = language_from_alpha3(result[0].language.alpha3) downloaded_language_code2 = alpha2_from_alpha3(result[0].language.alpha3) downloaded_language_code3 = result[0].language.alpha3 downloaded_path = get_subtitle_path(path, language=language_set) if used_sceneName == True: message = downloaded_language + " subtitles downloaded from " + downloaded_provider + " with a score of " + unicode(calculated_score) + "% using this scene name: " + sceneName else: message = downloaded_language + " subtitles downloaded from " + downloaded_provider + " with a score of " + unicode(calculated_score) + "% using filename guessing." if use_postprocessing is True: command = pp_replace(postprocessing_cmd, path, downloaded_path, downloaded_language, downloaded_language_code2, downloaded_language_code3) try: if os.name == 'nt': codepage = subprocess.Popen("chcp", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # wait for the process to terminate out_codepage, err_codepage = codepage.communicate() encoding = out_codepage.split(':')[-1].strip() process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # wait for the process to terminate out, err = process.communicate() if os.name == 'nt': out = out.decode(encoding) except: if out == "": logging.error('Post-processing result for file ' + path + ' : Nothing returned from command execution') else: logging.error('Post-processing result for file ' + path + ' : ' + out) else: if out == "": logging.info('Post-processing result for file ' + path + ' : Nothing returned from command execution') else: logging.info('Post-processing result for file ' + path + ' : ' + out) return message else: return None else: return None
def manual_search(path, language, hi, providers, providers_auth, sceneName, media_type): if hi == "True": hi = True else: hi = False language_set = set() for lang in ast.literal_eval(language): lang = alpha3_from_alpha2(lang) if lang == 'pob': language_set.add(Language('por', 'BR')) else: language_set.add(Language(lang)) use_scenename = get_general_settings()[9] use_postprocessing = get_general_settings()[10] postprocessing_cmd = get_general_settings()[11] try: if sceneName == "None" or use_scenename is False: used_sceneName = False video = scan_video(path) else: used_sceneName = True video = Video.fromname(sceneName) except: logging.error("Error trying to get video information.") else: if media_type == "movie": max_score = 120.0 elif media_type == "series": max_score = 360.0 try: with AsyncProviderPool(max_workers=None, providers=providers, provider_configs=providers_auth) as p: subtitles = p.list_subtitles(video, language_set) except Exception as e: logging.exception("Error trying to get subtitle list from provider") else: subtitles_list = [] for s in subtitles: {s: compute_score(s, video, hearing_impaired=hi)} if media_type == "movie": matched = set(s.get_matches(video)) if hi == s.hearing_impaired: matched.add('hearing_impaired') not_matched = set(score.movie_scores.keys()) - matched required = set(['title']) if any(elem in required for elem in not_matched): continue if used_sceneName: not_matched.remove('hash') elif media_type == "series": matched = set(s.get_matches(video)) if hi == s.hearing_impaired: matched.add('hearing_impaired') not_matched = set(score.episode_scores.keys()) - matched required = set(['series', 'season', 'episode']) if any(elem in required for elem in not_matched): continue if used_sceneName: not_matched.remove('hash') subtitles_list.append(dict(score=round((compute_score(s, video, hearing_impaired=hi) / max_score * 100), 2), language=alpha2_from_alpha3(s.language.alpha3), hearing_impaired=str(s.hearing_impaired), provider=s.provider_name, subtitle=codecs.encode(pickle.dumps(s), "base64").decode(), url=s.page_link, matches=list(matched), dont_matches=list(not_matched))) subtitles_dict = {} subtitles_dict = sorted(subtitles_list, key=lambda x: x['score'], reverse=True) return(subtitles_dict)
def download_subtitle(path, language, hi, providers, providers_auth, sceneName, media_type): logging.debug('BAZARR Searching subtitles for this file: ' + path) if hi == "True": hi = True else: hi = False language_set = set() if language == 'pob': language_set.add(Language('por', 'BR')) else: language_set.add(Language(language)) use_scenename = settings.general.getboolean('use_scenename') minimum_score = settings.general.minimum_score minimum_score_movie = settings.general.minimum_score_movie use_postprocessing = settings.general.getboolean('use_postprocessing') postprocessing_cmd = settings.general.postprocessing_cmd try: if sceneName == "None" or use_scenename is False: used_sceneName = False video = scan_video(path) else: used_sceneName = True video = Video.fromname(sceneName) except Exception as e: logging.exception("BAZARR Error trying to get video information for this file: " + path) pass else: if media_type == "movie": max_score = 120.0 elif media_type == "series": max_score = 360.0 try: with AsyncProviderPool(max_workers=None, providers=providers, provider_configs=providers_auth) as p: subtitles = p.list_subtitles(video, language_set) except Exception as e: logging.exception("BAZARR Error trying to get subtitle list from provider for this file: " + path) else: subtitles_list = [] try: sorted_subtitles = sorted([(s, compute_score(s, video, hearing_impaired=hi)) for s in subtitles], key=operator.itemgetter(1), reverse=True) except Exception as e: logging.exception('BAZARR Exception raised while trying to compute score for this file: ' + path) return None else: for s, preliminary_score in sorted_subtitles: if media_type == "movie": if (preliminary_score / max_score * 100) < int(minimum_score_movie): continue matched = set(s.get_matches(video)) if hi == s.hearing_impaired: matched.add('hearing_impaired') not_matched = set(score.movie_scores.keys()) - matched required = set(['title']) if any(elem in required for elem in not_matched): continue elif media_type == "series": if (preliminary_score / max_score * 100) < int(minimum_score): continue matched = set(s.get_matches(video)) if hi == s.hearing_impaired: matched.add('hearing_impaired') not_matched = set(score.episode_scores.keys()) - matched required = set(['series', 'season', 'episode']) if any(elem in required for elem in not_matched): continue subtitles_list.append(s) logging.debug('BAZARR ' + str(len(subtitles_list)) + " subtitles have been found for this file: " + path) if len(subtitles_list) > 0: try: download_result = False for subtitle in subtitles_list: download_result = p.download_subtitle(subtitle) if download_result: logging.debug('BAZARR Subtitles file downloaded from ' + str(subtitle.provider_name) + ' for this file: ' + path) break else: logging.warning('BAZARR Subtitles file skipped from ' + str(subtitle.provider_name) + ' for this file: ' + path + ' because no content was returned by the provider (probably throttled).') continue if not download_result: logging.error('BAZARR Tried to download a subtitles for file: ' + path + " but we weren't able to do it this time (probably being throttled). Going to retry on next search.") return None except Exception as e: logging.exception('BAZARR Error downloading subtitles for this file ' + path) return None else: try: calculated_score = round(float(compute_score(subtitle, video, hearing_impaired=hi)) / max_score * 100, 2) if used_sceneName: video = scan_video(path) single = settings.general.getboolean('single_language') if single is True: result = save_subtitles(video, [subtitle], single=True, encoding='utf-8') else: result = save_subtitles(video, [subtitle], encoding='utf-8') except Exception as e: logging.exception('BAZARR Error saving subtitles file to disk for this file:' + path) pass else: downloaded_provider = result[0].provider_name downloaded_language = language_from_alpha3(result[0].language.alpha3) downloaded_language_code2 = alpha2_from_alpha3(result[0].language.alpha3) downloaded_language_code3 = result[0].language.alpha3 downloaded_path = get_subtitle_path(path, downloaded_language_code2) logging.debug('BAZARR Subtitles file saved to disk: ' + downloaded_path) if used_sceneName: message = downloaded_language + " subtitles downloaded from " + downloaded_provider + " with a score of " + unicode(calculated_score) + "% using this scene name: " + sceneName else: message = downloaded_language + " subtitles downloaded from " + downloaded_provider + " with a score of " + unicode(calculated_score) + "% using filename guessing." if use_postprocessing is True: command = pp_replace(postprocessing_cmd, path, downloaded_path, downloaded_language, downloaded_language_code2, downloaded_language_code3) try: if os.name == 'nt': codepage = subprocess.Popen("chcp", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # wait for the process to terminate out_codepage, err_codepage = codepage.communicate() encoding = out_codepage.split(':')[-1].strip() process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # wait for the process to terminate out, err = process.communicate() if os.name == 'nt': out = out.decode(encoding) except: if out == "": logging.error('BAZARR Post-processing result for file ' + path + ' : Nothing returned from command execution') else: logging.error('BAZARR Post-processing result for file ' + path + ' : ' + out) else: if out == "": logging.info('BAZARR Post-processing result for file ' + path + ' : Nothing returned from command execution') else: logging.info('BAZARR Post-processing result for file ' + path + ' : ' + out) return message else: logging.debug('BAZARR No subtitles were found for this file: ' + path) return None logging.debug('BAZARR Ended searching subtitles for file: ' + path)
def manual_search(path, language, hi, providers, providers_auth, sceneName, media_type): logging.debug('BAZARR Manually searching subtitles for this file: ' + path) subtitles_dict = {} if hi == "True": hi = True else: hi = False language_set = set() for lang in ast.literal_eval(language): lang = alpha3_from_alpha2(lang) if lang == 'pob': language_set.add(Language('por', 'BR')) else: language_set.add(Language(lang)) use_scenename = settings.general.getboolean('use_scenename') use_postprocessing = settings.general.getboolean('use_postprocessing') postprocessing_cmd = settings.general.postprocessing_cmd try: if sceneName == "None" or use_scenename is False: used_sceneName = False video = scan_video(path) else: used_sceneName = True video = Video.fromname(sceneName) except: logging.exception("BAZARR Error trying to get video information for this file: " + path) else: if media_type == "movie": max_score = 120.0 elif media_type == "series": max_score = 360.0 try: with AsyncProviderPool(max_workers=None, providers=providers, provider_configs=providers_auth) as p: subtitles = p.list_subtitles(video, language_set) except Exception as e: logging.exception("BAZARR Error trying to get subtitle list from provider for this file: " + path) else: subtitles_list = [] for s in subtitles: {s: compute_score(s, video, hearing_impaired=hi)} if media_type == "movie": matched = set(s.get_matches(video)) if hi == s.hearing_impaired: matched.add('hearing_impaired') not_matched = set(score.movie_scores.keys()) - matched required = set(['title']) if any(elem in required for elem in not_matched): continue if used_sceneName: not_matched.remove('hash') if type(s) is LegendasTVSubtitle: # The pickle doesn't work very well with RAR (rarfile.RarFile) or ZIP (zipfile.ZipFile) s.archive.content = None elif media_type == "series": matched = set(s.get_matches(video)) if hi == s.hearing_impaired: matched.add('hearing_impaired') not_matched = set(score.episode_scores.keys()) - matched required = set(['series', 'season', 'episode']) if any(elem in required for elem in not_matched): continue if used_sceneName: not_matched.remove('hash') if type(s) is LegendasTVSubtitle: # The pickle doesn't work very well with RAR (rarfile.RarFile) or ZIP (zipfile.ZipFile) s.archive.content = None subtitles_list.append(dict(score=round((compute_score(s, video, hearing_impaired=hi) / max_score * 100), 2), language=alpha2_from_alpha3(s.language.alpha3), hearing_impaired=str(s.hearing_impaired), provider=s.provider_name, subtitle=codecs.encode(pickle.dumps(s), "base64").decode(), url=s.page_link, matches=list(matched), dont_matches=list(not_matched))) subtitles_dict = sorted(subtitles_list, key=lambda x: x['score'], reverse=True) logging.debug('BAZARR ' + str(len(subtitles_dict)) + " subtitles have been found for this file: " + path) logging.debug('BAZARR Ended searching subtitles for this file: ' + path) return(subtitles_dict)