diff --git a/bazarr/api/providers/providers_episodes.py b/bazarr/api/providers/providers_episodes.py index 1d4cb868e..b0eca9e65 100644 --- a/bazarr/api/providers/providers_episodes.py +++ b/bazarr/api/providers/providers_episodes.py @@ -5,7 +5,7 @@ from flask_restful import Resource from database import TableEpisodes, TableShows, get_audio_profile_languages, get_profile_id from helper import path_mappings -from get_providers import get_providers, get_providers_auth +from get_providers import get_providers from get_subtitle.manual import manual_search, manual_download_subtitle from utils import history_log from config import settings @@ -35,10 +35,8 @@ class ProviderEpisodes(Resource): profileId = episodeInfo['profileId'] providers_list = get_providers() - providers_auth = get_providers_auth() - data = manual_search(episodePath, profileId, providers_list, providers_auth, sceneName, title, - 'series') + data = manual_search(episodePath, profileId, providers_list, sceneName, title, 'series') if not data: data = [] return jsonify(data=data) @@ -59,12 +57,10 @@ class ProviderEpisodes(Resource): episodePath = path_mappings.path_replace(episodeInfo['path']) sceneName = episodeInfo['scene_name'] or "None" - language = request.form.get('language') hi = request.form.get('hi').capitalize() forced = request.form.get('forced').capitalize() selected_provider = request.form.get('provider') subtitle = request.form.get('subtitle') - providers_auth = get_providers_auth() audio_language_list = get_audio_profile_languages(episode_id=sonarrEpisodeId) if len(audio_language_list) > 0: @@ -73,8 +69,8 @@ class ProviderEpisodes(Resource): audio_language = 'None' try: - result = manual_download_subtitle(episodePath, language, audio_language, hi, forced, subtitle, - selected_provider, providers_auth, sceneName, title, 'series', + result = manual_download_subtitle(episodePath, audio_language, hi, forced, subtitle, selected_provider, + sceneName, title, 'series', profile_id=get_profile_id(episode_id=sonarrEpisodeId)) if result is not None: message = result[0] diff --git a/bazarr/api/providers/providers_movies.py b/bazarr/api/providers/providers_movies.py index 9a57805c2..f412866fe 100644 --- a/bazarr/api/providers/providers_movies.py +++ b/bazarr/api/providers/providers_movies.py @@ -5,7 +5,7 @@ from flask_restful import Resource from database import TableMovies, get_audio_profile_languages, get_profile_id from helper import path_mappings -from get_providers import get_providers, get_providers_auth +from get_providers import get_providers from get_subtitle.manual import manual_search, manual_download_subtitle from utils import history_log_movie from config import settings @@ -34,10 +34,8 @@ class ProviderMovies(Resource): profileId = movieInfo['profileId'] providers_list = get_providers() - providers_auth = get_providers_auth() - data = manual_search(moviePath, profileId, providers_list, providers_auth, sceneName, title, - 'movie') + data = manual_search(moviePath, profileId, providers_list, sceneName, title, 'movie') if not data: data = [] return jsonify(data=data) @@ -58,14 +56,11 @@ class ProviderMovies(Resource): moviePath = path_mappings.path_replace_movie(movieInfo['path']) sceneName = movieInfo['sceneName'] or "None" - language = request.form.get('language') hi = request.form.get('hi').capitalize() forced = request.form.get('forced').capitalize() selected_provider = request.form.get('provider') subtitle = request.form.get('subtitle') - providers_auth = get_providers_auth() - audio_language_list = get_audio_profile_languages(movie_id=radarrId) if len(audio_language_list) > 0: audio_language = audio_language_list[0]['name'] @@ -73,9 +68,8 @@ class ProviderMovies(Resource): audio_language = 'None' try: - result = manual_download_subtitle(moviePath, language, audio_language, hi, forced, subtitle, - selected_provider, providers_auth, sceneName, title, 'movie', - profile_id=get_profile_id(movie_id=radarrId)) + result = manual_download_subtitle(moviePath, audio_language, hi, forced, subtitle, selected_provider, + sceneName, title, 'movie', profile_id=get_profile_id(movie_id=radarrId)) if result is not None: message = result[0] path = result[1] diff --git a/bazarr/get_subtitle/__init__.py b/bazarr/get_subtitle/__init__.py new file mode 100644 index 000000000..4ea027346 --- /dev/null +++ b/bazarr/get_subtitle/__init__.py @@ -0,0 +1,5 @@ +# coding=utf-8 + +from . import mass_download # noqa: W0611 +from . import refiners # noqa: W0611 +from . import wanted # noqa: W0611 diff --git a/bazarr/get_subtitle/download.py b/bazarr/get_subtitle/download.py index cff324d03..a5340415b 100644 --- a/bazarr/get_subtitle/download.py +++ b/bazarr/get_subtitle/download.py @@ -12,18 +12,12 @@ from subliminal_patch.core_persistent import download_best_subtitles from subliminal_patch.score import compute_score from config import settings, get_array_from -from helper import path_mappings, pp_replace, get_target_folder, force_unicode -from get_languages import alpha3_from_alpha2, alpha2_from_alpha3, alpha2_from_language, alpha3_from_language, \ - language_from_alpha3 -from database import TableEpisodes, TableMovies -from analytics import track_event +from helper import get_target_folder, force_unicode +from get_languages import alpha3_from_alpha2 from score import movie_score, series_score -from utils import notify_sonarr, notify_radarr -from event_handler import event_stream from .pool import update_pools, _get_pool -from .utils import get_video, _get_lang_obj, _get_scores, _get_download_code3 -from .sync import sync_subtitles -from .post_processing import postprocessing +from .utils import get_video, _get_lang_obj, _get_scores +from .processing import process_subtitle @update_pools @@ -32,76 +26,37 @@ def generate_subtitles(path, languages, audio_language, sceneName, title, media_ if not languages: return None + logging.debug('BAZARR Searching subtitles for this file: ' + path) + if settings.general.getboolean('utf8_encode'): os.environ["SZ_KEEP_ENCODING"] = "" else: os.environ["SZ_KEEP_ENCODING"] = "True" - language_set = set() - - if not isinstance(languages, (set, list)): - languages = [languages] - pool = _get_pool(media_type, profile_id) providers = pool.providers - for language in languages: - lang, hi_item, forced_item = language - logging.debug('BAZARR Searching subtitles for this file: ' + path) - if hi_item == "True": - hi = "force HI" - else: - hi = "force non-HI" + language_set = _get_language_obj(languages=languages) + hi_required = any([x.hi for x in language_set]) + forced_required = any([x.forced for x in language_set]) + _set_forced_providers(forced_required=forced_required, pool=pool) - # Fixme: This block should be updated elsewhere - if forced_item == "True": - pool.provider_configs['podnapisi']['only_foreign'] = True - pool.provider_configs['subscene']['only_foreign'] = True - pool.provider_configs['opensubtitles']['only_foreign'] = True - else: - pool.provider_configs['podnapisi']['only_foreign'] = False - pool.provider_configs['subscene']['only_foreign'] = False - pool.provider_configs['opensubtitles']['only_foreign'] = False - - # Always use alpha2 in API Request - lang = alpha3_from_alpha2(lang) - - lang_obj = _get_lang_obj(lang) - - if forced_item == "True": - lang_obj = Language.rebuild(lang_obj, forced=True) - if hi == "force HI": - lang_obj = Language.rebuild(lang_obj, hi=True) - - language_set.add(lang_obj) - - 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 - single = settings.general.getboolean('single_language') - - # todo: - """ - AsyncProviderPool: - implement: - blacklist=None, - pre_download_hook=None, - post_download_hook=None, - language_hook=None - """ - video = get_video(force_unicode(path), title, sceneName, providers=providers, - media_type=media_type) + video = get_video(force_unicode(path), title, sceneName, providers=providers, media_type=media_type) if video: handler = series_score if media_type == "series" else movie_score + minimum_score = settings.general.minimum_score + minimum_score_movie = settings.general.minimum_score_movie min_score, max_score, scores = _get_scores(media_type, minimum_score_movie, minimum_score) if providers: if forced_minimum_score: min_score = int(forced_minimum_score) + 1 - downloaded_subtitles = download_best_subtitles({video}, language_set, pool, - int(min_score), hi, + downloaded_subtitles = download_best_subtitles(videos={video}, + languages=language_set, + pool_instance=pool, + min_score=int(min_score), + hearing_impaired=hi_required, compute_score=compute_score, throttle_time=None, # fixme score_obj=handler) @@ -124,7 +79,8 @@ def generate_subtitles(path, languages, audio_language, sceneName, title, media_ fld = get_target_folder(path) chmod = int(settings.general.chmod, 8) if not sys.platform.startswith( 'win') and settings.general.getboolean('chmod_enabled') else None - saved_subtitles = save_subtitles(video.original_path, subtitles, single=single, + saved_subtitles = save_subtitles(video.original_path, subtitles, + single=settings.general.getboolean('single_language'), tags=None, # fixme directory=fld, chmod=chmod, @@ -138,98 +94,10 @@ def generate_subtitles(path, languages, audio_language, sceneName, title, media_ else: saved_any = True for subtitle in saved_subtitles: - downloaded_provider = subtitle.provider_name - downloaded_language_code3 = _get_download_code3(subtitle) - - downloaded_language = language_from_alpha3(downloaded_language_code3) - downloaded_language_code2 = alpha2_from_alpha3(downloaded_language_code3) - audio_language_code2 = alpha2_from_language(audio_language) - audio_language_code3 = alpha3_from_language(audio_language) - downloaded_path = subtitle.storage_path - subtitle_id = subtitle.id - if subtitle.language.hi: - modifier_string = " HI" - elif subtitle.language.forced: - modifier_string = " forced" - else: - modifier_string = "" - logging.debug('BAZARR Subtitles file saved to disk: ' + downloaded_path) - if is_upgrade: - action = "upgraded" - else: - action = "downloaded" - - percent_score = round(subtitle.score * 100 / max_score, 2) - message = downloaded_language + modifier_string + " subtitles " + action + " from " + \ - downloaded_provider + " with a score of " + str(percent_score) + "%." - - if media_type == 'series': - episode_metadata = TableEpisodes.select(TableEpisodes.sonarrSeriesId, - TableEpisodes.sonarrEpisodeId)\ - .where(TableEpisodes.path == path_mappings.path_replace_reverse(path))\ - .dicts()\ - .get() - series_id = episode_metadata['sonarrSeriesId'] - episode_id = episode_metadata['sonarrEpisodeId'] - sync_subtitles(video_path=path, srt_path=downloaded_path, - forced=subtitle.language.forced, - srt_lang=downloaded_language_code2, media_type=media_type, - percent_score=percent_score, - sonarr_series_id=episode_metadata['sonarrSeriesId'], - sonarr_episode_id=episode_metadata['sonarrEpisodeId']) - else: - movie_metadata = TableMovies.select(TableMovies.radarrId)\ - .where(TableMovies.path == path_mappings.path_replace_reverse_movie(path))\ - .dicts()\ - .get() - series_id = "" - episode_id = movie_metadata['radarrId'] - sync_subtitles(video_path=path, srt_path=downloaded_path, - forced=subtitle.language.forced, - srt_lang=downloaded_language_code2, media_type=media_type, - percent_score=percent_score, - radarr_id=movie_metadata['radarrId']) - - if use_postprocessing is True: - command = pp_replace(postprocessing_cmd, path, downloaded_path, downloaded_language, - downloaded_language_code2, downloaded_language_code3, audio_language, - audio_language_code2, audio_language_code3, subtitle.language.forced, - percent_score, subtitle_id, downloaded_provider, series_id, episode_id, - subtitle.language.hi) - - if media_type == 'series': - use_pp_threshold = settings.general.getboolean('use_postprocessing_threshold') - pp_threshold = int(settings.general.postprocessing_threshold) - else: - use_pp_threshold = settings.general.getboolean('use_postprocessing_threshold_movie') - pp_threshold = int(settings.general.postprocessing_threshold_movie) - - if not use_pp_threshold or (use_pp_threshold and percent_score < pp_threshold): - logging.debug("BAZARR Using post-processing command: {}".format(command)) - postprocessing(command, path) - else: - logging.debug("BAZARR post-processing skipped because subtitles score isn't below this " - "threshold value: " + str(pp_threshold) + "%") - - # fixme: support multiple languages at once - if media_type == 'series': - reversed_path = path_mappings.path_replace_reverse(path) - reversed_subtitles_path = path_mappings.path_replace_reverse(downloaded_path) - notify_sonarr(episode_metadata['sonarrSeriesId']) - event_stream(type='series', action='update', payload=episode_metadata['sonarrSeriesId']) - event_stream(type='episode-wanted', action='delete', - payload=episode_metadata['sonarrEpisodeId']) - - else: - reversed_path = path_mappings.path_replace_reverse_movie(path) - reversed_subtitles_path = path_mappings.path_replace_reverse_movie(downloaded_path) - notify_radarr(movie_metadata['radarrId']) - event_stream(type='movie-wanted', action='delete', payload=movie_metadata['radarrId']) - - track_event(category=downloaded_provider, action=action, label=downloaded_language) - - yield message, reversed_path, downloaded_language_code2, downloaded_provider, subtitle.score, \ - subtitle.language.forced, subtitle.id, reversed_subtitles_path, subtitle.language.hi + processed_subtitle = process_subtitle(subtitle=subtitle, media_type=media_type, + audio_language=audio_language, is_upgrade=is_upgrade, + is_manual=False, path=path, max_score=max_score) + yield processed_subtitle if not saved_any: logging.debug('BAZARR No Subtitles were found for this file: ' + path) @@ -238,3 +106,42 @@ def generate_subtitles(path, languages, audio_language, sceneName, title, media_ subliminal.region.backend.sync() logging.debug('BAZARR Ended searching Subtitles for file: ' + path) + + +def _get_language_obj(languages): + language_set = set() + + if not isinstance(languages, (set, list)): + languages = [languages] + + for language in languages: + lang, hi_item, forced_item = language + if hi_item == "True": + hi = "force HI" + else: + hi = "force non-HI" + + # Always use alpha2 in API Request + lang = alpha3_from_alpha2(lang) + + lang_obj = _get_lang_obj(lang) + + if forced_item == "True": + lang_obj = Language.rebuild(lang_obj, forced=True) + if hi == "force HI": + lang_obj = Language.rebuild(lang_obj, hi=True) + + language_set.add(lang_obj) + + return language_set + + +def _set_forced_providers(forced_required, pool): + if forced_required: + pool.provider_configs['podnapisi']['only_foreign'] = True + pool.provider_configs['subscene']['only_foreign'] = True + pool.provider_configs['opensubtitles']['only_foreign'] = True + else: + pool.provider_configs['podnapisi']['only_foreign'] = False + pool.provider_configs['subscene']['only_foreign'] = False + pool.provider_configs['opensubtitles']['only_foreign'] = False diff --git a/bazarr/get_subtitle/manual.py b/bazarr/get_subtitle/manual.py index 104087dbe..1cb073cad 100644 --- a/bazarr/get_subtitle/manual.py +++ b/bazarr/get_subtitle/manual.py @@ -13,75 +13,35 @@ from subliminal_patch.core import save_subtitles from subliminal_patch.core_persistent import list_all_subtitles, download_subtitles from subliminal_patch.score import compute_score -from get_languages import language_from_alpha3, alpha2_from_alpha3, alpha3_from_alpha2, alpha2_from_language, \ - alpha3_from_language +from get_languages import alpha3_from_alpha2 from config import settings, get_array_from -from helper import path_mappings, pp_replace, get_target_folder, force_unicode -from utils import notify_sonarr, notify_radarr -from database import get_profiles_list, TableEpisodes, TableMovies -from analytics import track_event +from helper import get_target_folder, force_unicode +from database import get_profiles_list from score import movie_score, series_score from .pool import update_pools, _get_pool, _init_pool -from .utils import get_video, _get_lang_obj, _get_scores, _get_download_code3 -from .sync import sync_subtitles -from .post_processing import postprocessing +from .utils import get_video, _get_lang_obj, _get_scores +from .processing import process_subtitle @update_pools -def manual_search(path, profile_id, providers, providers_auth, sceneName, title, media_type): +def manual_search(path, profile_id, providers, sceneName, title, media_type): logging.debug('BAZARR Manually searching subtitles for this file: ' + path) final_subtitles = [] - initial_language_set = set() - language_set = set() - - # where [3] is items list of dict(id, lang, forced, hi) - language_items = get_profiles_list(profile_id=int(profile_id))['items'] pool = _get_pool(media_type, profile_id) - for language in language_items: - forced = language['forced'] - hi = language['hi'] - language = language['language'] + language_set, initial_language_set = _get_language_obj(profile_id=profile_id) + also_forced = any([x.forced for x in initial_language_set]) + _set_forced_providers(also_forced=also_forced, pool=pool) - lang = alpha3_from_alpha2(language) - - lang_obj = _get_lang_obj(lang) - - if forced == "True": - lang_obj = Language.rebuild(lang_obj, forced=True) - - pool.provider_configs['podnapisi']['also_foreign'] = True - pool.provider_configs['opensubtitles']['also_foreign'] = True - - if hi == "True": - lang_obj = Language.rebuild(lang_obj, hi=True) - - initial_language_set.add(lang_obj) - - language_set = initial_language_set.copy() - for language in language_set.copy(): - lang_obj_for_hi = language - if not language.forced and not language.hi: - lang_obj_hi = Language.rebuild(lang_obj_for_hi, hi=True) - elif not language.forced and language.hi: - lang_obj_hi = Language.rebuild(lang_obj_for_hi, hi=False) - else: - continue - language_set.add(lang_obj_hi) - - minimum_score = settings.general.minimum_score - minimum_score_movie = settings.general.minimum_score_movie if providers: - video = get_video(force_unicode(path), title, sceneName, providers=providers, - media_type=media_type) + video = get_video(force_unicode(path), title, sceneName, providers=providers, media_type=media_type) else: logging.info("BAZARR All providers are throttled") return None if video: handler = series_score if media_type == "series" else movie_score - min_score, max_score, scores = _get_scores(media_type, minimum_score_movie, minimum_score) try: if providers: @@ -108,6 +68,8 @@ def manual_search(path, profile_id, providers, providers_auth, sceneName, title, logging.exception("BAZARR Error trying to get Subtitle list from provider for this file: " + path) else: subtitles_list = [] + minimum_score = settings.general.minimum_score + minimum_score_movie = settings.general.minimum_score_movie for s in subtitles[video]: try: @@ -122,7 +84,7 @@ def manual_search(path, profile_id, providers, providers_auth, sceneName, title, can_verify_series = False if can_verify_series and not {"series", "season", "episode"}.issubset(matches): - logging.debug(u"BAZARR Skipping %s, because it doesn't match our series/episode", s) + logging.debug(f"BAZARR Skipping {s}, because it doesn't match our series/episode") continue initial_hi = None @@ -137,7 +99,9 @@ def manual_search(path, profile_id, providers, providers_auth, sceneName, title, if not initial_hi_match: initial_hi = None - score, score_without_hash = compute_score(matches, s, video, hearing_impaired=initial_hi, score_obj=handler) + _, max_score, scores = _get_scores(media_type, minimum_score_movie, minimum_score) + score, score_without_hash = compute_score(matches, s, video, hearing_impaired=initial_hi, + score_obj=handler) if 'hash' not in matches: not_matched = scores - matches s.score = score_without_hash @@ -188,8 +152,8 @@ def manual_search(path, profile_id, providers, providers_auth, sceneName, title, @update_pools -def manual_download_subtitle(path, language, audio_language, hi, forced, subtitle, provider, providers_auth, sceneName, - title, media_type, profile_id): +def manual_download_subtitle(path, audio_language, hi, forced, subtitle, provider, sceneName, title, media_type, + profile_id): logging.debug('BAZARR Manually downloading Subtitles for this file: ' + path) if settings.general.getboolean('utf8_encode'): @@ -207,13 +171,8 @@ def manual_download_subtitle(path, language, audio_language, hi, forced, subtitl else: subtitle.language.forced = False subtitle.mods = get_array_from(settings.general.subzero_mods) - use_postprocessing = settings.general.getboolean('use_postprocessing') - postprocessing_cmd = settings.general.postprocessing_cmd - single = settings.general.getboolean('single_language') - video = get_video(force_unicode(path), title, sceneName, providers={provider}, - media_type=media_type) + video = get_video(force_unicode(path), title, sceneName, providers={provider}, media_type=media_type) if video: - min_score, max_score, scores = _get_scores(media_type) try: if provider: download_subtitles([subtitle], _get_pool(media_type, profile_id)) @@ -229,104 +188,25 @@ def manual_download_subtitle(path, language, audio_language, hi, forced, subtitl logging.exception('BAZARR No valid Subtitles file found for this file: ' + path) return try: - score = round(subtitle.score / max_score * 100, 2) - fld = get_target_folder(path) chmod = int(settings.general.chmod, 8) if not sys.platform.startswith( 'win') and settings.general.getboolean('chmod_enabled') else None - saved_subtitles = save_subtitles(video.original_path, [subtitle], single=single, + saved_subtitles = save_subtitles(video.original_path, [subtitle], + single=settings.general.getboolean('single_language'), tags=None, # fixme - directory=fld, + directory=get_target_folder(path), chmod=chmod, # formats=("srt", "vtt") path_decoder=force_unicode) - except Exception: logging.exception('BAZARR Error saving Subtitles file to disk for this file:' + path) return else: if saved_subtitles: + _, max_score, _ = _get_scores(media_type) for saved_subtitle in saved_subtitles: - downloaded_provider = saved_subtitle.provider_name - downloaded_language_code3 = _get_download_code3(subtitle) - - downloaded_language = language_from_alpha3(downloaded_language_code3) - downloaded_language_code2 = alpha2_from_alpha3(downloaded_language_code3) - audio_language_code2 = alpha2_from_language(audio_language) - audio_language_code3 = alpha3_from_language(audio_language) - downloaded_path = saved_subtitle.storage_path - subtitle_id = subtitle.id - logging.debug('BAZARR Subtitles file saved to disk: ' + downloaded_path) - if subtitle.language.hi: - modifier_string = " HI" - elif subtitle.language.forced: - modifier_string = " forced" - else: - modifier_string = "" - message = downloaded_language + modifier_string + " subtitles downloaded from " + \ - downloaded_provider + " with a score of " + str(score) + "% using manual search." - - if media_type == 'series': - episode_metadata = TableEpisodes.select(TableEpisodes.sonarrSeriesId, - TableEpisodes.sonarrEpisodeId)\ - .where(TableEpisodes.path == path_mappings.path_replace_reverse(path))\ - .dicts()\ - .get() - series_id = episode_metadata['sonarrSeriesId'] - episode_id = episode_metadata['sonarrEpisodeId'] - sync_subtitles(video_path=path, srt_path=downloaded_path, - forced=subtitle.language.forced, - srt_lang=downloaded_language_code2, media_type=media_type, - percent_score=score, - sonarr_series_id=episode_metadata['sonarrSeriesId'], - sonarr_episode_id=episode_metadata['sonarrEpisodeId']) - else: - movie_metadata = TableMovies.select(TableMovies.radarrId)\ - .where(TableMovies.path == path_mappings.path_replace_reverse_movie(path))\ - .dicts()\ - .get() - series_id = "" - episode_id = movie_metadata['radarrId'] - sync_subtitles(video_path=path, srt_path=downloaded_path, - forced=subtitle.language.forced, - srt_lang=downloaded_language_code2, media_type=media_type, - percent_score=score, radarr_id=movie_metadata['radarrId']) - - if use_postprocessing: - percent_score = round(subtitle.score * 100 / max_score, 2) - command = pp_replace(postprocessing_cmd, path, downloaded_path, downloaded_language, - downloaded_language_code2, downloaded_language_code3, audio_language, - audio_language_code2, audio_language_code3, subtitle.language.forced, - percent_score, subtitle_id, downloaded_provider, series_id, episode_id, - subtitle.language.hi) - - if media_type == 'series': - use_pp_threshold = settings.general.getboolean('use_postprocessing_threshold') - pp_threshold = settings.general.postprocessing_threshold - else: - use_pp_threshold = settings.general.getboolean('use_postprocessing_threshold_movie') - pp_threshold = settings.general.postprocessing_threshold_movie - - if not use_pp_threshold or (use_pp_threshold and score < float(pp_threshold)): - logging.debug("BAZARR Using post-processing command: {}".format(command)) - postprocessing(command, path) - else: - logging.debug("BAZARR post-processing skipped because subtitles score isn't below this " - "threshold value: " + pp_threshold + "%") - - if media_type == 'series': - reversed_path = path_mappings.path_replace_reverse(path) - reversed_subtitles_path = path_mappings.path_replace_reverse(downloaded_path) - notify_sonarr(episode_metadata['sonarrSeriesId']) - else: - reversed_path = path_mappings.path_replace_reverse_movie(path) - reversed_subtitles_path = path_mappings.path_replace_reverse_movie(downloaded_path) - notify_radarr(movie_metadata['radarrId']) - - track_event(category=downloaded_provider, action="manually_downloaded", - label=downloaded_language) - - return message, reversed_path, downloaded_language_code2, downloaded_provider, subtitle.score, \ - subtitle.language.forced, subtitle.id, reversed_subtitles_path, subtitle.language.hi + return process_subtitle(subtitle=saved_subtitle, media_type=media_type, + audio_language=audio_language, is_upgrade=False, + is_manual=True, path=path, max_score=max_score) else: logging.error( "BAZARR Tried to manually download a Subtitles for file: " + path @@ -337,3 +217,47 @@ def manual_download_subtitle(path, language, audio_language, hi, forced, subtitl subliminal.region.backend.sync() logging.debug('BAZARR Ended manually downloading Subtitles for file: ' + path) + + +def _get_language_obj(profile_id): + initial_language_set = set() + language_set = set() + + # where [3] is items list of dict(id, lang, forced, hi) + language_items = get_profiles_list(profile_id=int(profile_id))['items'] + + for language in language_items: + forced = language['forced'] + hi = language['hi'] + language = language['language'] + + lang = alpha3_from_alpha2(language) + + lang_obj = _get_lang_obj(lang) + + if forced == "True": + lang_obj = Language.rebuild(lang_obj, forced=True) + + if hi == "True": + lang_obj = Language.rebuild(lang_obj, hi=True) + + initial_language_set.add(lang_obj) + + language_set = initial_language_set.copy() + for language in language_set.copy(): + lang_obj_for_hi = language + if not language.forced and not language.hi: + lang_obj_hi = Language.rebuild(lang_obj_for_hi, hi=True) + elif not language.forced and language.hi: + lang_obj_hi = Language.rebuild(lang_obj_for_hi, hi=False) + else: + continue + language_set.add(lang_obj_hi) + + return language_set, initial_language_set + + +def _set_forced_providers(also_forced, pool): + if also_forced: + pool.provider_configs['podnapisi']['also_foreign'] = True + pool.provider_configs['opensubtitles']['also_foreign'] = True diff --git a/bazarr/get_subtitle/mass_download/__init__.py b/bazarr/get_subtitle/mass_download/__init__.py index de492f186..7fe746a2b 100644 --- a/bazarr/get_subtitle/mass_download/__init__.py +++ b/bazarr/get_subtitle/mass_download/__init__.py @@ -1,2 +1,4 @@ +# coding=utf-8 + from .movies import movies_download_subtitles # noqa: W0611 from .series import series_download_subtitles, episode_download_subtitles # noqa: W0611 diff --git a/bazarr/get_subtitle/processing.py b/bazarr/get_subtitle/processing.py new file mode 100644 index 000000000..d8a1b1990 --- /dev/null +++ b/bazarr/get_subtitle/processing.py @@ -0,0 +1,114 @@ +# coding=utf-8 +# fmt: off + +import logging + +from config import settings +from helper import path_mappings, pp_replace +from get_languages import alpha2_from_alpha3, alpha2_from_language, alpha3_from_language, language_from_alpha3 +from database import TableEpisodes, TableMovies +from analytics import track_event +from utils import notify_sonarr, notify_radarr +from event_handler import event_stream +from .utils import _get_download_code3 +from .sync import sync_subtitles +from .post_processing import postprocessing + + +def process_subtitle(subtitle, media_type, audio_language, path, max_score, is_upgrade=False, is_manual=False): + use_postprocessing = settings.general.getboolean('use_postprocessing') + postprocessing_cmd = settings.general.postprocessing_cmd + + downloaded_provider = subtitle.provider_name + downloaded_language_code3 = _get_download_code3(subtitle) + + downloaded_language = language_from_alpha3(downloaded_language_code3) + downloaded_language_code2 = alpha2_from_alpha3(downloaded_language_code3) + audio_language_code2 = alpha2_from_language(audio_language) + audio_language_code3 = alpha3_from_language(audio_language) + downloaded_path = subtitle.storage_path + subtitle_id = subtitle.id + if subtitle.language.hi: + modifier_string = " HI" + elif subtitle.language.forced: + modifier_string = " forced" + else: + modifier_string = "" + logging.debug('BAZARR Subtitles file saved to disk: ' + downloaded_path) + if is_upgrade: + action = "upgraded" + elif is_manual: + action = "manually downloaded" + else: + action = "downloaded" + + percent_score = round(subtitle.score * 100 / max_score, 2) + message = downloaded_language + modifier_string + " subtitles " + action + " from " + \ + downloaded_provider + " with a score of " + str(percent_score) + "%." + + if media_type == 'series': + episode_metadata = TableEpisodes.select(TableEpisodes.sonarrSeriesId, + TableEpisodes.sonarrEpisodeId) \ + .where(TableEpisodes.path == path_mappings.path_replace_reverse(path)) \ + .dicts() \ + .get() + series_id = episode_metadata['sonarrSeriesId'] + episode_id = episode_metadata['sonarrEpisodeId'] + sync_subtitles(video_path=path, srt_path=downloaded_path, + forced=subtitle.language.forced, + srt_lang=downloaded_language_code2, media_type=media_type, + percent_score=percent_score, + sonarr_series_id=episode_metadata['sonarrSeriesId'], + sonarr_episode_id=episode_metadata['sonarrEpisodeId']) + else: + movie_metadata = TableMovies.select(TableMovies.radarrId) \ + .where(TableMovies.path == path_mappings.path_replace_reverse_movie(path)) \ + .dicts() \ + .get() + series_id = "" + episode_id = movie_metadata['radarrId'] + sync_subtitles(video_path=path, srt_path=downloaded_path, + forced=subtitle.language.forced, + srt_lang=downloaded_language_code2, media_type=media_type, + percent_score=percent_score, + radarr_id=movie_metadata['radarrId']) + + if use_postprocessing is True: + command = pp_replace(postprocessing_cmd, path, downloaded_path, downloaded_language, + downloaded_language_code2, downloaded_language_code3, audio_language, + audio_language_code2, audio_language_code3, subtitle.language.forced, + percent_score, subtitle_id, downloaded_provider, series_id, episode_id, + subtitle.language.hi) + + if media_type == 'series': + use_pp_threshold = settings.general.getboolean('use_postprocessing_threshold') + pp_threshold = int(settings.general.postprocessing_threshold) + else: + use_pp_threshold = settings.general.getboolean('use_postprocessing_threshold_movie') + pp_threshold = int(settings.general.postprocessing_threshold_movie) + + if not use_pp_threshold or (use_pp_threshold and percent_score < pp_threshold): + logging.debug("BAZARR Using post-processing command: {}".format(command)) + postprocessing(command, path) + else: + logging.debug("BAZARR post-processing skipped because subtitles score isn't below this " + "threshold value: " + str(pp_threshold) + "%") + + if media_type == 'series': + reversed_path = path_mappings.path_replace_reverse(path) + reversed_subtitles_path = path_mappings.path_replace_reverse(downloaded_path) + notify_sonarr(episode_metadata['sonarrSeriesId']) + event_stream(type='series', action='update', payload=episode_metadata['sonarrSeriesId']) + event_stream(type='episode-wanted', action='delete', + payload=episode_metadata['sonarrEpisodeId']) + + else: + reversed_path = path_mappings.path_replace_reverse_movie(path) + reversed_subtitles_path = path_mappings.path_replace_reverse_movie(downloaded_path) + notify_radarr(movie_metadata['radarrId']) + event_stream(type='movie-wanted', action='delete', payload=movie_metadata['radarrId']) + + track_event(category=downloaded_provider, action=action, label=downloaded_language) + + return message, reversed_path, downloaded_language_code2, downloaded_provider, subtitle.score, \ + subtitle.language.forced, subtitle.id, reversed_subtitles_path, subtitle.language.hi diff --git a/bazarr/get_subtitle/refiners/__init__.py b/bazarr/get_subtitle/refiners/__init__.py index e4bbba618..d0840f111 100644 --- a/bazarr/get_subtitle/refiners/__init__.py +++ b/bazarr/get_subtitle/refiners/__init__.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- + from .ffprobe import refine_from_ffprobe from .database import refine_from_db diff --git a/bazarr/get_subtitle/refiners/utils.py b/bazarr/get_subtitle/refiners/utils.py index 3df803e19..bdbb78891 100644 --- a/bazarr/get_subtitle/refiners/utils.py +++ b/bazarr/get_subtitle/refiners/utils.py @@ -2,6 +2,7 @@ from guessit import guessit + def convert_to_guessit(guessit_key, attr_from_db): try: return guessit(attr_from_db)[guessit_key] diff --git a/bazarr/get_subtitle/wanted/__init__.py b/bazarr/get_subtitle/wanted/__init__.py index 97676641a..73ea6380a 100644 --- a/bazarr/get_subtitle/wanted/__init__.py +++ b/bazarr/get_subtitle/wanted/__init__.py @@ -1,2 +1,4 @@ +# coding=utf-8 + from .movies import wanted_download_subtitles_movie, wanted_search_missing_subtitles_movies # noqa: W0611 from .series import wanted_download_subtitles, wanted_search_missing_subtitles_series # noqa: W0611