def sync(self, video_path, srt_path, srt_lang, media_type, sonarr_series_id=None, sonarr_episode_id=None, radarr_id=None): self.reference = video_path self.srtin = srt_path self.srtout = '{}.synced.srt'.format(os.path.splitext(self.srtin)[0]) self.args = None ffprobe_exe = get_binary('ffprobe') if not ffprobe_exe: logging.debug('BAZARR FFprobe not found!') return else: logging.debug('BAZARR FFprobe used is %s', ffprobe_exe) ffmpeg_exe = get_binary('ffmpeg') if not ffmpeg_exe: logging.debug('BAZARR FFmpeg not found!') return else: logging.debug('BAZARR FFmpeg used is %s', ffmpeg_exe) self.ffmpeg_path = os.path.dirname(ffmpeg_exe) try: unparsed_args = [self.reference, '-i', self.srtin, '-o', self.srtout, '--ffmpegpath', self.ffmpeg_path, '--vad', self.vad, '--log-dir-path', self.log_dir_path] if settings.subsync.getboolean('debug'): unparsed_args.append('--make-test-case') parser = make_parser() self.args = parser.parse_args(args=unparsed_args) result = run(self.args) except Exception as e: logging.exception('BAZARR an exception occurs during the synchronization process for this subtitles: ' '{0}'.format(self.srtin)) else: if os.path.isfile(self.srtout): if not settings.subsync.getboolean('debug'): os.remove(self.srtin) os.rename(self.srtout, self.srtin) offset_seconds = result['offset_seconds'] or 0 framerate_scale_factor = result['framerate_scale_factor'] or 0 message = "{0} subtitles synchronization ended with an offset of {1} seconds and a framerate " \ "scale factor of {2}.".format(language_from_alpha3(srt_lang), offset_seconds, "{:.2f}".format(framerate_scale_factor)) if media_type == 'series': history_log(action=5, sonarr_series_id=sonarr_series_id, sonarr_episode_id=sonarr_episode_id, description=message, video_path=path_mappings.path_replace_reverse(self.reference), language=alpha2_from_alpha3(srt_lang), subtitles_path=srt_path) else: history_log_movie(action=5, radarr_id=radarr_id, description=message, video_path=path_mappings.path_replace_reverse_movie(self.reference), language=alpha2_from_alpha3(srt_lang), subtitles_path=srt_path) else: logging.error('BAZARR unable to sync subtitles: {0}'.format(self.srtin)) return result
def delete_subtitles(media_type, language, forced, hi, media_path, subtitles_path, sonarr_series_id=None, sonarr_episode_id=None, radarr_id=None): if not subtitles_path.endswith('.srt'): logging.error('BAZARR can only delete .srt files.') return False if hi in [True, 'true', 'True']: language_log = alpha2_from_alpha3(language) + ':hi' language_string = language_from_alpha3(language) + ' HI' elif forced in [True, 'true', 'True']: language_log = alpha2_from_alpha3(language) + ':forced' language_string = language_from_alpha3(language) + ' forced' else: language_log = alpha2_from_alpha3(language) language_string = language_from_alpha3(language) result = language_string + " subtitles deleted from disk." if media_type == 'series': try: os.remove(path_mappings.path_replace(subtitles_path)) except OSError: logging.exception('BAZARR cannot delete subtitles file: ' + subtitles_path) store_subtitles(path_mappings.path_replace_reverse(media_path), media_path) return False else: history_log(0, sonarr_series_id, sonarr_episode_id, result, language=language_log, video_path=path_mappings.path_replace_reverse(media_path), subtitles_path=path_mappings.path_replace_reverse(subtitles_path)) store_subtitles(path_mappings.path_replace_reverse(media_path), media_path) notify_sonarr(sonarr_series_id) else: try: os.remove(path_mappings.path_replace_movie(subtitles_path)) except OSError: logging.exception('BAZARR cannot delete subtitles file: ' + subtitles_path) store_subtitles_movie(path_mappings.path_replace_reverse_movie(media_path), media_path) return False else: history_log_movie(0, radarr_id, result, language=language_log, video_path=path_mappings.path_replace_reverse_movie(media_path), subtitles_path=path_mappings.path_replace_reverse_movie(subtitles_path)) store_subtitles_movie(path_mappings.path_replace_reverse_movie(media_path), media_path) notify_radarr(radarr_id) return True
def get(self): history = request.args.get('history') if history and history not in False_Keys: languages = list( TableHistory.select(TableHistory.language).where( TableHistory.language != None).dicts()) languages += list( TableHistoryMovie.select(TableHistoryMovie.language).where( TableHistoryMovie.language != None).dicts()) languages_list = list( set([l['language'].split(':')[0] for l in languages])) languages_dicts = [] for language in languages_list: code2 = None if len(language) == 2: code2 = language elif len(language) == 3: code2 = alpha2_from_alpha3(language) else: continue if not any(x['code2'] == code2 for x in languages_dicts): try: languages_dicts.append({ 'code2': code2, 'name': language_from_alpha2(code2), # Compatibility: Use false temporarily 'enabled': False }) except: continue return jsonify(sorted(languages_dicts, key=itemgetter('name'))) result = TableSettingsLanguages.select(TableSettingsLanguages.name, TableSettingsLanguages.code2, TableSettingsLanguages.enabled)\ .order_by(TableSettingsLanguages.name).dicts() result = list(result) for item in result: item['enabled'] = item['enabled'] == 1 return jsonify(result)
def manual_search(path, language, hi, providers, providers_auth, sceneName, title, media_type): logging.debug('BAZARR Manually searching subtitles for this file: ' + path) final_subtitles = [] 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') 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 video = get_video(path, title, sceneName, use_scenename, providers=providers, media_type=media_type) if video: min_score, max_score, scores = get_scores( video, media_type, min_score_movie_perc=int(minimum_score_movie), min_score_series_perc=int(minimum_score)) try: if providers: subtitles = list_subtitles([video], language_set, providers=providers, provider_configs=providers_auth, pool_class=provider_pool(), throttle_callback=provider_throttle, language_hook=None) # fixme else: subtitles = [] logging.info("BAZARR All providers are throttled") 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[video]: try: matches = s.get_matches(video) except AttributeError: continue # skip wrong season/episodes if media_type == "series": can_verify_series = True if not s.hash_verifiable and "hash" in matches: 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) continue score = compute_score(matches, s, video, hearing_impaired=hi) not_matched = scores - matches s.score = score # if score < min_score: # continue subtitles_list.append( dict(score=round((score / 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.make_picklable()), "base64").decode(), url=s.page_link, matches=list(matches), dont_matches=list(not_matched))) final_subtitles = sorted(subtitles_list, key=lambda x: x['score'], reverse=True) logging.debug('BAZARR ' + str(len(final_subtitles)) + " subtitles have been found for this file: " + path) logging.debug('BAZARR Ended searching subtitles for this file: ' + path) return final_subtitles
def manual_download_subtitle(path, language, hi, subtitle, provider, providers_auth, sceneName, title, media_type): logging.debug('BAZARR Manually downloading subtitles for this file: ' + path) subtitle = pickle.loads(codecs.decode(subtitle.encode(), "base64")) use_scenename = settings.general.getboolean('use_scenename') use_postprocessing = settings.general.getboolean('use_postprocessing') postprocessing_cmd = settings.general.postprocessing_cmd single = settings.general.getboolean('single_language') video = get_video(path, title, sceneName, use_scenename, providers={provider}, media_type=media_type) if video: min_score, max_score, scores = get_scores(video, media_type) try: if provider: download_subtitles([subtitle], providers={provider}, provider_configs=providers_auth, pool_class=provider_pool(), throttle_callback=provider_throttle) logging.debug( 'BAZARR Subtitles file downloaded for this file:' + path) else: logging.info("BAZARR All providers are throttled") return None except Exception as e: logging.exception( 'BAZARR Error downloading subtitles for this file ' + path) return None else: if not subtitle.is_valid(): notifications.write( msg='No valid subtitles file found for this file: ' + path, queue='get_subtitle') logging.exception( 'BAZARR No valid subtitles file found for this file: ' + path) return logging.debug('BAZARR Subtitles file downloaded for this file:' + path) 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, tags=None, # fixme directory=fld, chmod=chmod, # formats=("srt", "vtt") path_decoder=force_unicode) except Exception as e: logging.exception( 'BAZARR Error saving subtitles file to disk for this file:' + path) return else: if saved_subtitles: for saved_subtitle in saved_subtitles: downloaded_provider = saved_subtitle.provider_name if saved_subtitle.language == 'pt-BR': downloaded_language_code3 = 'pob' else: downloaded_language_code3 = subtitle.language.alpha3 downloaded_language = language_from_alpha3( downloaded_language_code3) downloaded_language_code2 = alpha2_from_alpha3( downloaded_language_code3) downloaded_path = saved_subtitle.storage_path logging.debug('BAZARR Subtitles file saved to disk: ' + downloaded_path) message = downloaded_language + " subtitles downloaded from " + downloaded_provider + " with a score of " + unicode( score) + "% using manual search." 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) if media_type == 'series': reversed_path = path_replace_reverse(path) else: reversed_path = path_replace_reverse_movie(path) return message, reversed_path, downloaded_language_code2, downloaded_provider, subtitle.score else: logging.error( "BAZARR Tried to manually download a subtitles for file: " + path + " but we weren't able to do (probably throttled by " + str(subtitle.provider_name) + ". Please retry later or select a subtitles from another provider." ) return None logging.debug('BAZARR Ended manually downloading subtitles for file: ' + path)
def store_subtitles(file): logging.debug('BAZARR started subtitles indexing for this file: ' + file) actual_subtitles = [] if os.path.exists(file): # notifications.write(msg='Analyzing this file for subtitles: ' + file, queue='list_subtitles') if settings.general.getboolean('use_embedded_subs'): logging.debug("BAZARR is trying to index embedded subtitles.") try: subtitle_languages = embedded_subs_reader.list_languages(file) for subtitle_language in subtitle_languages: try: if alpha2_from_alpha3(subtitle_language) is not None: lang = str(alpha2_from_alpha3(subtitle_language)) logging.debug( "BAZARR embedded subtitles detected: " + lang) actual_subtitles.append([lang, None]) except: logging.debug( "BAZARR unable to index this unrecognized language: " + subtitle_language) pass except Exception as e: logging.exception( "BAZARR error when trying to analyze this %s file: %s" % (os.path.splitext(file)[1], file)) pass brazilian_portuguese = [".pt-br", ".pob", "pb"] try: dest_folder = get_subtitle_destination_folder() subliminal_patch.core.CUSTOM_PATHS = [dest_folder ] if dest_folder else [] subtitles = search_external_subtitles( file, languages=get_language_set(), only_one=settings.general.getboolean('single_language')) except Exception as e: logging.exception("BAZARR unable to index external subtitles.") pass else: for subtitle, language in subtitles.iteritems(): subtitle_path = get_external_subtitles_path(file, subtitle) if str(os.path.splitext(subtitle)[0]).lower().endswith( tuple(brazilian_portuguese)): logging.debug("BAZARR external subtitles detected: " + "pb") actual_subtitles.append( [str("pb"), path_replace_reverse(subtitle_path)]) elif str(language) != 'und': logging.debug("BAZARR external subtitles detected: " + str(language)) actual_subtitles.append( [str(language), path_replace_reverse(subtitle_path)]) else: if os.path.splitext(subtitle)[1] != ".sub": logging.debug( "BAZARR falling back to file content analysis to detect language." ) with open( path_replace( os.path.join(os.path.dirname(file), subtitle)), 'r') as f: text = list(islice(f, 100)) text = ' '.join(text) encoding = UnicodeDammit(text) try: text = text.decode(encoding.original_encoding) detected_language = langdetect.detect(text) except Exception as e: logging.exception( 'BAZARR Error trying to detect language for this subtitles file: ' + path_replace( os.path.join(os.path.dirname(file), subtitle)) + ' You should try to delete this subtitles file manually and ask Bazarr to download it again.' ) else: if len(detected_language) > 0: logging.debug( "BAZARR external subtitles detected and analysis guessed this language: " + str(detected_language)) actual_subtitles.append([ str(detected_language), path_replace_reverse( os.path.join( os.path.dirname(file), subtitle)) ]) conn_db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) c_db = conn_db.cursor() logging.debug("BAZARR storing those languages to DB: " + str(actual_subtitles)) c_db.execute("UPDATE table_episodes SET subtitles = ? WHERE path = ?", (str(actual_subtitles), path_replace_reverse(file))) conn_db.commit() c_db.close() else: logging.debug( "BAZARR this file doesn't seems to exist or isn't accessible.") logging.debug('BAZARR ended subtitles indexing for this file: ' + file) return actual_subtitles
def download_subtitle(path, language, hi, providers, providers_auth, sceneName, title, media_type, forced_minimum_score=None, is_upgrade=False): # fixme: supply all missing languages, not only one, to hit providers only once who support multiple languages in # one query logging.debug('BAZARR Searching subtitles for this file: ' + path) if hi == "True": hi = True else: hi = False language_set = set() if not isinstance(language, types.ListType): language = [language] for l in language: if l == 'pob': language_set.add(Language('por', 'BR')) else: language_set.add(Language(l)) 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 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(path, title, sceneName, use_scenename, providers=providers, media_type=media_type) if video: min_score, max_score, scores = get_scores( video, media_type, min_score_movie_perc=int(minimum_score_movie), min_score_series_perc=int(minimum_score)) if providers: if forced_minimum_score: min_score = int(forced_minimum_score) + 1 downloaded_subtitles = download_best_subtitles( {video}, language_set, int(min_score), hi, providers=providers, provider_configs=providers_auth, pool_class=provider_pool(), compute_score=compute_score, throttle_time=None, # fixme blacklist=None, # fixme throttle_callback=provider_throttle, pre_download_hook=None, # fixme post_download_hook=None, # fixme language_hook=None) # fixme else: downloaded_subtitles = None logging.info("BAZARR All providers are throttled") saved_any = False if downloaded_subtitles: for video, subtitles in downloaded_subtitles.iteritems(): if not subtitles: continue try: 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, tags=None, # fixme directory=fld, chmod=chmod, # formats=("srt", "vtt") path_decoder=force_unicode) except Exception as e: logging.exception( 'BAZARR Error saving subtitles file to disk for this file:' + path) pass else: saved_any = True for subtitle in saved_subtitles: downloaded_provider = subtitle.provider_name if subtitle.language == 'pt-BR': downloaded_language_code3 = 'pob' else: downloaded_language_code3 = subtitle.language.alpha3 downloaded_language = language_from_alpha3( downloaded_language_code3) downloaded_language_code2 = alpha2_from_alpha3( downloaded_language_code3) downloaded_path = subtitle.storage_path logging.debug('BAZARR Subtitles file saved to disk: ' + downloaded_path) if is_upgrade: action = "upgraded" else: action = "downloaded" if video.used_scene_name: message = downloaded_language + " subtitles " + action + " from " + downloaded_provider + " with a score of " + unicode( round(subtitle.score * 100 / max_score, 2) ) + "% using this scene name: " + sceneName else: message = downloaded_language + " subtitles " + action + " from " + downloaded_provider + " with a score of " + unicode( round(subtitle.score * 100 / max_score, 2)) + "% 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) # fixme: support multiple languages at once if media_type == 'series': reversed_path = path_replace_reverse(path) else: reversed_path = path_replace_reverse_movie(path) return message, reversed_path, downloaded_language_code2, downloaded_provider, subtitle.score if not saved_any: logging.debug('BAZARR No subtitles were found for this file: ' + path) return None logging.debug('BAZARR Ended searching subtitles for file: ' + path)
def store_subtitles(file): # languages = [] actual_subtitles = [] if os.path.exists(file): if os.path.splitext(file)[1] == '.mkv': try: with open(file, 'rb') as f: mkv = enzyme.MKV(f) for subtitle_track in mkv.subtitle_tracks: try: if alpha2_from_alpha3(subtitle_track.language) != None: actual_subtitles.append([ str(alpha2_from_alpha3( subtitle_track.language)), None ]) except: pass except: pass brazilian_portuguese = [".pt-br", ".pob", "pb"] try: subtitles = core.search_external_subtitles(file) except: pass else: for subtitle, language in subtitles.iteritems(): if str(os.path.splitext(subtitle)[0]).lower().endswith( tuple(brazilian_portuguese)) is True: actual_subtitles.append([ str("pb"), path_replace_reverse( os.path.join(os.path.dirname(file), subtitle)) ]) elif str(language) != 'und': actual_subtitles.append([ str(language), path_replace_reverse( os.path.join(os.path.dirname(file), subtitle)) ]) else: with open( path_replace( os.path.join(os.path.dirname(file), subtitle)), 'r') as f: text = list(islice(f, 100)) text = ' '.join(text) encoding = UnicodeDammit(text) try: text = text.decode(encoding.original_encoding) except Exception as e: logging.exception( 'Error trying to detect character encoding for this subtitles file: ' + path_replace( os.path.join(os.path.dirname(file), subtitle)) + ' You should try to delete this subtitles file manually and ask Bazarr to download it again.' ) else: detected_language = langdetect.detect(text) if len(detected_language) > 0: actual_subtitles.append([ str(detected_language), path_replace_reverse( os.path.join(os.path.dirname(file), subtitle)) ]) conn_db = sqlite3.connect(os.path.join(config_dir, 'db/bazarr.db'), timeout=30) c_db = conn_db.cursor() c_db.execute( "UPDATE table_episodes SET subtitles = ? WHERE path = ?", (str(actual_subtitles), path_replace_reverse(file))) conn_db.commit() c_db.close() return actual_subtitles
def store_subtitles(file): logging.debug('BAZARR started subtitles indexing for this file: ' + file) actual_subtitles = [] if os.path.exists(file): if os.path.splitext(file)[1] == '.mkv': logging.debug("BAZARR is trying to index embedded subtitles.") try: with open(file, 'rb') as f: mkv = enzyme.MKV(f) for subtitle_track in mkv.subtitle_tracks: try: if alpha2_from_alpha3(subtitle_track.language) != None: lang = str( alpha2_from_alpha3(subtitle_track.language)) logging.debug( "BAZARR embedded subtitles detected: " + lang) actual_subtitles.append([lang, None]) except: logging.debug( "BAZARR unable to index this unrecognized language: " + subtitle_track.language) pass except Exception as e: logging.exception( "BAZARR error when trying to analyze this mkv file: " + file) pass else: logging.debug("BAZARR This file isn't an .mkv file.") brazilian_portuguese = [".pt-br", ".pob", "pb"] try: subtitles = core.search_external_subtitles(file) except Exception as e: logging.exception("BAZARR unable to index external subtitles.") pass else: for subtitle, language in subtitles.iteritems(): if str(os.path.splitext(subtitle)[0]).lower().endswith( tuple(brazilian_portuguese)) is True: logging.debug("BAZARR external subtitles detected: " + "pb") actual_subtitles.append([ str("pb"), path_replace_reverse( os.path.join(os.path.dirname(file), subtitle)) ]) elif str(language) != 'und': logging.debug("BAZARR external subtitles detected: " + str(language)) actual_subtitles.append([ str(language), path_replace_reverse( os.path.join(os.path.dirname(file), subtitle)) ]) else: if os.path.splitext(subtitle)[1] != ".sub": logging.debug( "BAZARR falling back to file content analysis to detect language." ) with open( path_replace( os.path.join(os.path.dirname(file), subtitle)), 'r') as f: text = list(islice(f, 100)) text = ' '.join(text) encoding = UnicodeDammit(text) try: text = text.decode(encoding.original_encoding) detected_language = langdetect.detect(text) except Exception as e: logging.exception( 'BAZARR Error trying to detect language for this subtitles file: ' + path_replace( os.path.join(os.path.dirname(file), subtitle)) + ' You should try to delete this subtitles file manually and ask Bazarr to download it again.' ) else: if len(detected_language) > 0: logging.debug( "BAZARR external subtitles detected and analysis guessed this language: " + str(detected_language)) actual_subtitles.append([ str(detected_language), path_replace_reverse( os.path.join( os.path.dirname(file), subtitle)) ]) conn_db = sqlite3.connect(os.path.join(config_dir, 'db/bazarr.db'), timeout=30) c_db = conn_db.cursor() logging.debug("BAZARR storing those languages to DB: " + str(actual_subtitles)) c_db.execute("UPDATE table_episodes SET subtitles = ? WHERE path = ?", (str(actual_subtitles), path_replace_reverse(file))) conn_db.commit() c_db.close() else: logging.debug( "BAZARR this file doesn't seems to exist or isn't accessible.") logging.debug('BAZARR ended subtitles indexing for this file: ' + file) return actual_subtitles
def store_subtitles(original_path, reversed_path): logging.debug('BAZARR started subtitles indexing for this file: ' + reversed_path) actual_subtitles = [] if os.path.exists(reversed_path): if settings.general.getboolean('use_embedded_subs'): logging.debug("BAZARR is trying to index embedded subtitles.") try: subtitle_languages = embedded_subs_reader.list_languages( reversed_path) for subtitle_language, subtitle_forced, subtitle_hi, subtitle_codec in subtitle_languages: try: if (settings.general.getboolean("ignore_pgs_subs") and subtitle_codec.lower() == "pgs") or \ (settings.general.getboolean("ignore_vobsub_subs") and subtitle_codec.lower() == "vobsub"): logging.debug( "BAZARR skipping %s sub for language: %s" % (subtitle_codec, alpha2_from_alpha3(subtitle_language))) continue if alpha2_from_alpha3(subtitle_language) is not None: lang = str(alpha2_from_alpha3(subtitle_language)) if subtitle_forced: lang = lang + ":forced" if subtitle_hi: lang = lang + ":hi" logging.debug( "BAZARR embedded subtitles detected: " + lang) actual_subtitles.append([lang, None]) except: logging.debug( "BAZARR unable to index this unrecognized language: " + subtitle_language) pass except Exception as e: logging.exception( "BAZARR error when trying to analyze this %s file: %s" % (os.path.splitext(reversed_path)[1], reversed_path)) pass brazilian_portuguese = [".pt-br", ".pob", "pb"] brazilian_portuguese_forced = [ ".pt-br.forced", ".pob.forced", "pb.forced" ] try: dest_folder = get_subtitle_destination_folder() core.CUSTOM_PATHS = [dest_folder] if dest_folder else [] subtitles = search_external_subtitles( reversed_path, languages=get_language_set(), only_one=settings.general.getboolean('single_language')) full_dest_folder_path = os.path.dirname(reversed_path) if dest_folder: if settings.general.subfolder == "absolute": full_dest_folder_path = dest_folder elif settings.general.subfolder == "relative": full_dest_folder_path = os.path.join( os.path.dirname(reversed_path), dest_folder) subtitles = guess_external_subtitles(full_dest_folder_path, subtitles) except Exception as e: logging.exception("BAZARR unable to index external subtitles.") pass else: for subtitle, language in subtitles.items(): subtitle_path = get_external_subtitles_path( reversed_path, subtitle) if str(os.path.splitext(subtitle)[0]).lower().endswith( tuple(brazilian_portuguese)): logging.debug("BAZARR external subtitles detected: " + "pb") actual_subtitles.append([ str("pb"), path_mappings.path_replace_reverse(subtitle_path) ]) elif str(os.path.splitext(subtitle)[0]).lower().endswith( tuple(brazilian_portuguese_forced)): logging.debug("BAZARR external subtitles detected: " + "pb:forced") actual_subtitles.append([ str("pb:forced"), path_mappings.path_replace_reverse(subtitle_path) ]) elif not language: continue elif str(language.basename) != 'und': logging.debug("BAZARR external subtitles detected: " + str(language.basename)) actual_subtitles.append([ str(language.basename + (':hi' if language.hi else '')), path_mappings.path_replace_reverse(subtitle_path) ]) database.execute("UPDATE table_episodes SET subtitles=? WHERE path=?", (str(actual_subtitles), original_path)) matching_episodes = database.execute( "SELECT sonarrEpisodeId, sonarrSeriesId FROM table_episodes WHERE path=?", (original_path, )) for episode in matching_episodes: if episode: logging.debug("BAZARR storing those languages to DB: " + str(actual_subtitles)) list_missing_subtitles(epno=episode['sonarrEpisodeId']) else: logging.debug( "BAZARR haven't been able to update existing subtitles to DB : " + str(actual_subtitles)) else: logging.debug( "BAZARR this file doesn't seems to exist or isn't accessible.") logging.debug('BAZARR ended subtitles indexing for this file: ' + reversed_path) return actual_subtitles
def manual_download_subtitle(path, language, hi, subtitle, provider, providers_auth, sceneName, media_type): logging.debug('BAZARR Manually downloading subtitles for this file: ' + path) if hi == "True": hi = True else: hi = False subtitle = pickle.loads(codecs.decode(subtitle.encode(), "base64")) if media_type == 'series': type_of_score = 360 elif media_type == 'movie': type_of_score = 120 use_scenename = settings.general.getboolean('use_scenename') use_postprocessing = settings.general.getboolean('use_postprocessing') postprocessing_cmd = settings.general.postprocessing_cmd language = alpha3_from_alpha2(language) if language == 'pob': lang_obj = Language('por', 'BR') else: lang_obj = Language(language) try: if sceneName is 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: try: download_subtitles([subtitle], providers=provider, provider_configs=providers_auth) logging.debug('BAZARR Subtitles file downloaded for this file:' + path) except Exception as e: logging.exception('BAZARR Error downloading subtitles for this file ' + path) return None else: single = settings.general.getboolean('single_language') try: score = round(float(compute_score(subtitle, video, hearing_impaired=hi)) / type_of_score * 100, 2) if used_sceneName == True: video = scan_video(path) 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) 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, downloaded_language_code2) logging.debug('BAZARR Subtitles file saved to disk: ' + downloaded_path) message = downloaded_language + " subtitles downloaded from " + downloaded_provider + " with a score of " + unicode(score) + "% using manual search." 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.error("BAZARR Tried to manually download a subtitles for file: " + path + " but we weren't able to do (probably throttled by " + str(subtitle.provider_name) + ". Please retry later or select a subtitles from another provider.") return None logging.debug('BAZARR Ended manually downloading subtitles for file: ' + path)
def manual_download_subtitle(path, language, hi, subtitle, provider, providers_auth, sceneName, media_type): if hi == "True": hi = True else: hi = False subtitle = pickle.loads(codecs.decode(subtitle.encode(), "base64")) if media_type == 'series': type_of_score = 360 elif media_type == 'movie': type_of_score = 120 use_scenename = get_general_settings()[9] use_postprocessing = get_general_settings()[10] postprocessing_cmd = get_general_settings()[11] language = alpha3_from_alpha2(language) if language == 'pob': lang_obj = Language('por', 'BR') else: lang_obj = Language(language) try: if sceneName is 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 extract information from this filename: ' + path) return None else: try: best_subtitle = subtitle download_subtitles([best_subtitle], providers=provider, provider_configs=providers_auth) except Exception as e: logging.exception('Error downloading subtitles for ' + path) return None else: single = get_general_settings()[7] try: score = round(float(compute_score(best_subtitle, video, hearing_impaired=hi)) / type_of_score * 100, 2) if used_sceneName == True: video = scan_video(path) 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=lang_obj) message = downloaded_language + " subtitles downloaded from " + downloaded_provider + " with a score of " + unicode(score) + "% using manual search." 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
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 sync(self, video_path, srt_path, srt_lang, media_type, sonarr_series_id=None, sonarr_episode_id=None, radarr_id=None): self.reference = video_path self.srtin = srt_path self.srtout = None self.args = None ffprobe_exe = get_binary('ffprobe') if not ffprobe_exe: logging.debug('BAZARR FFprobe not found!') return else: logging.debug('BAZARR FFprobe used is %s', ffprobe_exe) ffmpeg_exe = get_binary('ffmpeg') if not ffmpeg_exe: logging.debug('BAZARR FFmpeg not found!') return else: logging.debug('BAZARR FFmpeg used is %s', ffmpeg_exe) self.ffmpeg_path = os.path.dirname(ffmpeg_exe) try: unparsed_args = [ self.reference, '-i', self.srtin, '--overwrite-input', '--ffmpegpath', self.ffmpeg_path, '--vad', self.vad ] parser = make_parser() self.args = parser.parse_args(args=unparsed_args) result = run(self.args) except Exception as e: logging.exception( 'BAZARR an exception occurs during the synchronization process for this subtitles: ' '{0}'.format(self.srtin)) else: if result['sync_was_successful']: message = "{0} subtitles synchronization ended with an offset of {1} seconds and a framerate scale " \ "factor of {2}.".format(language_from_alpha3(srt_lang), result['offset_seconds'], "{:.2f}".format(result['framerate_scale_factor'])) if media_type == 'series': history_log(action=5, sonarr_series_id=sonarr_series_id, sonarr_episode_id=sonarr_episode_id, description=message, video_path=path_mappings.path_replace_reverse( self.reference), language=alpha2_from_alpha3(srt_lang), subtitles_path=srt_path) else: history_log_movie( action=5, radarr_id=radarr_id, description=message, video_path=path_mappings.path_replace_reverse_movie( self.reference), language=alpha2_from_alpha3(srt_lang), subtitles_path=srt_path) else: logging.error('BAZARR unable to sync subtitles: {0}'.format( self.srtin)) return result
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 store_subtitles_movie(original_path, reversed_path): logging.debug('BAZARR started subtitles indexing for this file: ' + reversed_path) actual_subtitles = [] if os.path.exists(reversed_path): if settings.general.getboolean('use_embedded_subs'): logging.debug("BAZARR is trying to index embedded subtitles.") try: subtitle_languages = embedded_subs_reader.list_languages( reversed_path) for subtitle_language, subtitle_forced, subtitle_hi, subtitle_codec in subtitle_languages: try: if (settings.general.getboolean("ignore_pgs_subs") and subtitle_codec.lower() == "pgs") or \ (settings.general.getboolean("ignore_vobsub_subs") and subtitle_codec.lower() == "vobsub"): logging.debug( "BAZARR skipping %s sub for language: %s" % (subtitle_codec, alpha2_from_alpha3(subtitle_language))) continue if alpha2_from_alpha3(subtitle_language) is not None: lang = str(alpha2_from_alpha3(subtitle_language)) if subtitle_forced: lang = lang + ':forced' if subtitle_hi: lang = lang + ':hi' logging.debug( "BAZARR embedded subtitles detected: " + lang) actual_subtitles.append([lang, None]) except: logging.debug( "BAZARR unable to index this unrecognized language: " + subtitle_language) pass except Exception as e: logging.exception( "BAZARR error when trying to analyze this %s file: %s" % (os.path.splitext(reversed_path)[1], reversed_path)) pass brazilian_portuguese = [".pt-br", ".pob", "pb"] brazilian_portuguese_forced = [ ".pt-br.forced", ".pob.forced", "pb.forced" ] simplified_chinese_fuzzy = [u"简", u"双语"] simplified_chinese = [ ".chs", ".sc", ".zhs", ".zh-hans", ".hans", ".zh_hans", ".zhhans", ".gb", ".simplified" ] simplified_chinese_forced = [ ".chs.forced", ".sc.forced", ".zhs.forced", "hans.forced", ".gb.forced", u"简体中文.forced", u"双语.forced" ] traditional_chinese_fuzzy = [u"繁", u"雙語"] traditional_chinese = [ ".cht", ".tc", ".zh-tw", ".zht", ".zh-hant", ".zhhant", ".zh_hant", ".hant", ".big5", ".traditional" ] traditional_chinese_forced = [ ".cht.forced", ".tc.forced", ".zht.forced", "hant.forced", ".big5.forced", u"繁體中文.forced", u"雙語.forced", "zh-tw.forced" ] try: dest_folder = get_subtitle_destination_folder() or '' core.CUSTOM_PATHS = [dest_folder] if dest_folder else [] subtitles = search_external_subtitles(reversed_path, languages=get_language_set()) full_dest_folder_path = os.path.dirname(reversed_path) if dest_folder: if settings.general.subfolder == "absolute": full_dest_folder_path = dest_folder elif settings.general.subfolder == "relative": full_dest_folder_path = os.path.join( os.path.dirname(reversed_path), dest_folder) subtitles = guess_external_subtitles(full_dest_folder_path, subtitles) except Exception as e: logging.exception("BAZARR unable to index external subtitles.") pass else: for subtitle, language in subtitles.items(): subtitle_path = get_external_subtitles_path( reversed_path, subtitle) if str(os.path.splitext(subtitle)[0]).lower().endswith( tuple(brazilian_portuguese)): logging.debug("BAZARR external subtitles detected: " + "pb") actual_subtitles.append([ str("pb"), path_mappings.path_replace_reverse_movie(subtitle_path) ]) elif str(os.path.splitext(subtitle)[0]).lower().endswith( tuple(brazilian_portuguese_forced)): logging.debug("BAZARR external subtitles detected: " + "pb:forced") actual_subtitles.append([ str("pb:forced"), path_mappings.path_replace_reverse_movie(subtitle_path) ]) elif str(os.path.splitext(subtitle)[0]).lower().endswith( tuple(simplified_chinese)) or ( str(subtitle_path).lower() )[:-5] in simplified_chinese_fuzzy: logging.debug("BAZARR external subtitles detected: " + "zh") actual_subtitles.append([ str("zh"), path_mappings.path_replace_reverse_movie(subtitle_path) ]) elif any(ext in ( str(os.path.splitext(subtitle)[0]).lower())[-12:] for ext in simplified_chinese_forced): logging.debug("BAZARR external subtitles detected: " + "zh:forced") actual_subtitles.append([ str("zh:forced"), path_mappings.path_replace_reverse_movie(subtitle_path) ]) elif str(os.path.splitext(subtitle)[0]).lower().endswith( tuple(traditional_chinese)) or ( str(subtitle_path).lower() )[:-5] in traditional_chinese_fuzzy: logging.debug("BAZARR external subtitles detected: " + "zt") actual_subtitles.append([ str("zt"), path_mappings.path_replace_reverse_movie(subtitle_path) ]) elif any(ext in ( str(os.path.splitext(subtitle)[0]).lower())[-12:] for ext in traditional_chinese_forced): logging.debug("BAZARR external subtitles detected: " + "zt:forced") actual_subtitles.append([ str("zt:forced"), path_mappings.path_replace_reverse_movie(subtitle_path) ]) elif not language: continue elif str(language.basename) != 'und': if language.forced: language_str = str(language) elif language.hi: language_str = str(language) + ':hi' else: language_str = str(language) logging.debug("BAZARR external subtitles detected: " + language_str) actual_subtitles.append([ language_str, path_mappings.path_replace_reverse_movie(subtitle_path) ]) database.execute("UPDATE table_movies SET subtitles=? WHERE path=?", (str(actual_subtitles), original_path)) matching_movies = database.execute( "SELECT radarrId FROM table_movies WHERE path=?", (original_path, )) for movie in matching_movies: if movie: logging.debug("BAZARR storing those languages to DB: " + str(actual_subtitles)) list_missing_subtitles_movies(no=movie['radarrId']) else: logging.debug( "BAZARR haven't been able to update existing subtitles to DB : " + str(actual_subtitles)) else: logging.debug( "BAZARR this file doesn't seems to exist or isn't accessible.") logging.debug('BAZARR ended subtitles indexing for this file: ' + reversed_path) return actual_subtitles
def manual_upload_subtitle(path, language, forced, hi, title, scene_name, media_type, subtitle, audio_language): logging.debug('BAZARR Manually uploading subtitles for this file: ' + path) single = settings.general.getboolean('single_language') use_postprocessing = settings.general.getboolean('use_postprocessing') postprocessing_cmd = settings.general.postprocessing_cmd chmod = int(settings.general.chmod, 8) if not sys.platform.startswith( 'win') and settings.general.getboolean('chmod_enabled') else None language = alpha3_from_alpha2(language) custom = CustomLanguage.from_value(language, "alpha3") if custom is None: lang_obj = Language(language) else: lang_obj = custom.subzero_language() if forced: lang_obj = Language.rebuild(lang_obj, forced=True) sub = Subtitle( lang_obj, mods=get_array_from(settings.general.subzero_mods) ) sub.content = subtitle.read() if not sub.is_valid(): logging.exception('BAZARR Invalid subtitle file: ' + subtitle.filename) sub.mods = None if settings.general.getboolean('utf8_encode'): sub.set_encoding("utf-8") saved_subtitles = [] try: saved_subtitles = save_subtitles(path, [sub], single=single, tags=None, # fixme 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 if len(saved_subtitles) < 1: logging.exception('BAZARR Error saving Subtitles file to disk for this file:' + path) return subtitle_path = saved_subtitles[0].storage_path if hi: modifier_string = " HI" elif forced: modifier_string = " forced" else: modifier_string = "" message = language_from_alpha3(language) + modifier_string + " Subtitles manually uploaded." if hi: modifier_code = ":hi" elif forced: modifier_code = ":forced" else: modifier_code = "" uploaded_language_code3 = language + modifier_code uploaded_language = language_from_alpha3(language) + modifier_string uploaded_language_code2 = alpha2_from_alpha3(language) + modifier_code audio_language_code2 = alpha2_from_language(audio_language) audio_language_code3 = alpha3_from_language(audio_language) if media_type == 'series': episode_metadata = TableEpisodes.select(TableEpisodes.sonarrSeriesId, TableEpisodes.sonarrEpisodeId) \ .where(TableEpisodes.path == path_mappings.path_replace_reverse(path)) \ .dicts() \ .get_or_none() if not episode_metadata: return series_id = episode_metadata['sonarrSeriesId'] episode_id = episode_metadata['sonarrEpisodeId'] sync_subtitles(video_path=path, srt_path=subtitle_path, srt_lang=uploaded_language_code2, media_type=media_type, percent_score=100, sonarr_series_id=episode_metadata['sonarrSeriesId'], forced=forced, 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_or_none() if not movie_metadata: return series_id = "" episode_id = movie_metadata['radarrId'] sync_subtitles(video_path=path, srt_path=subtitle_path, srt_lang=uploaded_language_code2, media_type=media_type, percent_score=100, radarr_id=movie_metadata['radarrId'], forced=forced) if use_postprocessing: command = pp_replace(postprocessing_cmd, path, subtitle_path, uploaded_language, uploaded_language_code2, uploaded_language_code3, audio_language, audio_language_code2, audio_language_code3, forced, 100, "1", "manual", series_id, episode_id, hi=hi) postprocessing(command, path) if media_type == 'series': reversed_path = path_mappings.path_replace_reverse(path) reversed_subtitles_path = path_mappings.path_replace_reverse(subtitle_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(subtitle_path) notify_radarr(movie_metadata['radarrId']) event_stream(type='movie', action='update', payload=movie_metadata['radarrId']) event_stream(type='movie-wanted', action='delete', payload=movie_metadata['radarrId']) return message, reversed_path, reversed_subtitles_path
def store_subtitles_movie(original_path, reversed_path): logging.debug('BAZARR started subtitles indexing for this file: ' + reversed_path) actual_subtitles = [] if os.path.exists(reversed_path): if settings.general.getboolean('use_embedded_subs'): logging.debug("BAZARR is trying to index embedded subtitles.") try: subtitle_languages = embedded_subs_reader.list_languages( reversed_path) for subtitle_language, subtitle_forced, subtitle_codec in subtitle_languages: try: if settings.general.getboolean( "ignore_pgs_subs" ) and subtitle_codec == "hdmv_pgs_subtitle": logging.debug( "BAZARR skipping pgs sub for language: " + str(alpha2_from_alpha3(subtitle_language))) continue if alpha2_from_alpha3(subtitle_language) is not None: lang = str(alpha2_from_alpha3(subtitle_language)) if subtitle_forced: lang = lang + ':forced' logging.debug( "BAZARR embedded subtitles detected: " + lang) actual_subtitles.append([lang, None]) except: logging.debug( "BAZARR unable to index this unrecognized language: " + subtitle_language) pass except Exception as e: logging.exception( "BAZARR error when trying to analyze this %s file: %s" % (os.path.splitext(reversed_path)[1], reversed_path)) pass brazilian_portuguese = [".pt-br", ".pob", "pb"] brazilian_portuguese_forced = [ ".pt-br.forced", ".pob.forced", "pb.forced" ] try: dest_folder = get_subtitle_destination_folder() or '' subliminal_patch.core.CUSTOM_PATHS = [dest_folder ] if dest_folder else [] subtitles = search_external_subtitles(reversed_path, languages=get_language_set()) subtitles = guess_external_subtitles( get_subtitle_destination_folder() or os.path.dirname(reversed_path), subtitles) except Exception as e: logging.exception("BAZARR unable to index external subtitles.") pass else: for subtitle, language in six.iteritems(subtitles): subtitle_path = get_external_subtitles_path( reversed_path, subtitle) if str(os.path.splitext(subtitle)[0]).lower().endswith( tuple(brazilian_portuguese)): logging.debug("BAZARR external subtitles detected: " + "pb") actual_subtitles.append( [str("pb"), path_replace_reverse_movie(subtitle_path)]) elif str(os.path.splitext(subtitle)[0]).lower().endswith( tuple(brazilian_portuguese_forced)): logging.debug("BAZARR external subtitles detected: " + "pb:forced") actual_subtitles.append([ str("pb:forced"), path_replace_reverse_movie(subtitle_path) ]) elif not language: continue elif str(language) != 'und': logging.debug("BAZARR external subtitles detected: " + str(language)) actual_subtitles.append([ str(language), path_replace_reverse_movie(subtitle_path) ]) database.execute("UPDATE table_movies SET subtitles=? WHERE path=?", (str(actual_subtitles), original_path)) matching_movies = database.execute( "SELECT radarrId FROM table_movies WHERE path=?", (original_path, )) for movie in matching_movies: if movie: logging.debug("BAZARR storing those languages to DB: " + str(actual_subtitles)) list_missing_subtitles_movies(no=movie['radarrId']) else: logging.debug( "BAZARR haven't been able to update existing subtitles to DB : " + str(actual_subtitles)) else: logging.debug( "BAZARR this file doesn't seems to exist or isn't accessible.") logging.debug('BAZARR ended subtitles indexing for this file: ' + reversed_path) return actual_subtitles
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)
def sync(self, video_path, srt_path, srt_lang, media_type, sonarr_series_id=None, sonarr_episode_id=None, radarr_id=None): self.reference = video_path self.srtin = srt_path self.srtout = None ffprobe_exe = get_binary('ffprobe') if not ffprobe_exe: logging.debug('BAZARR FFprobe not found!') return else: logging.debug('BAZARR FFprobe used is %s', ffprobe_exe) api.initialize({'provider': 'ffmpeg', 'ffmpeg': ffprobe_exe}) data = api.know(self.reference) using_what = None if 'subtitle' in data: for i, embedded_subs in enumerate(data['subtitle']): if 'language' in embedded_subs: language = embedded_subs['language'].alpha3 if language == "eng": using_what = "English embedded subtitle track" self.reference_stream = "s:{}".format(i) break if not self.reference_stream: using_what = "{0} embedded subtitle track".format( language_from_alpha3(embedded_subs['language'].alpha3) or 'unknown language embedded subtitles ' 'track') self.reference_stream = "s:0" elif 'audio' in data: audio_tracks = data['audio'] for i, audio_track in enumerate(audio_tracks): if 'language' in audio_track: language = audio_track['language'].alpha3 if language == srt_lang: using_what = "{0} audio track".format(language_from_alpha3(audio_track['language'].alpha3) or 'unknown language audio track') self.reference_stream = "a:{}".format(i) break if not self.reference_stream: audio_tracks = data['audio'] for i, audio_track in enumerate(audio_tracks): if 'language' in audio_track: language = audio_track['language'].alpha3 if language == "eng": using_what = "English audio track" self.reference_stream = "a:{}".format(i) break if not self.reference_stream: using_what = "first audio track" self.reference_stream = "a:0" else: raise NoAudioTrack ffmpeg_exe = get_binary('ffmpeg') if not ffmpeg_exe: logging.debug('BAZARR FFmpeg not found!') return else: logging.debug('BAZARR FFmpeg used is %s', ffmpeg_exe) self.ffmpeg_path = os.path.dirname(ffmpeg_exe) try: result = run(self) except Exception as e: logging.error('BAZARR an exception occurs during the synchronization process for this subtitles: ' + self.srtin) else: if result['sync_was_successful']: message = "{0} subtitles synchronization ended with an offset of {1} seconds and a framerate scale " \ "factor of {2} using {3} (0:{4}).".format(language_from_alpha3(srt_lang), result['offset_seconds'], result['framerate_scale_factor'], using_what, self.reference_stream) if media_type == 'series': history_log(action=5, sonarr_series_id=sonarr_series_id, sonarr_episode_id=sonarr_episode_id, description=message, video_path=path_mappings.path_replace_reverse(self.reference), language=alpha2_from_alpha3(srt_lang), subtitles_path=srt_path) else: history_log_movie(action=5, radarr_id=radarr_id, description=message, video_path=path_mappings.path_replace_reverse_movie(self.reference), language=alpha2_from_alpha3(srt_lang), subtitles_path=srt_path) else: logging.error('BAZARR unable to sync subtitles using {0}({1}): {2}'.format(using_what, self.reference_stream, self.srtin)) return result
def store_subtitles(file): logging.debug('BAZARR started subtitles indexing for this file: ' + file) actual_subtitles = [] if os.path.exists(file): if settings.general.getboolean('use_embedded_subs'): logging.debug("BAZARR is trying to index embedded subtitles.") try: subtitle_languages = embedded_subs_reader.list_languages(file) for subtitle_language, subtitle_forced, subtitle_codec in subtitle_languages: try: if settings.general.getboolean( "ignore_pgs_subs" ) and subtitle_codec == "hdmv_pgs_subtitle": logging.debug( "BAZARR skipping pgs sub for language: " + str(alpha2_from_alpha3(subtitle_language))) continue if alpha2_from_alpha3(subtitle_language) is not None: lang = str(alpha2_from_alpha3(subtitle_language)) if subtitle_forced: lang = lang + ":forced" logging.debug( "BAZARR embedded subtitles detected: " + lang) actual_subtitles.append([lang, None]) except: logging.debug( "BAZARR unable to index this unrecognized language: " + subtitle_language) pass except Exception as e: logging.exception( "BAZARR error when trying to analyze this %s file: %s" % (os.path.splitext(file)[1], file)) pass brazilian_portuguese = [".pt-br", ".pob", "pb"] brazilian_portuguese_forced = [ ".pt-br.forced", ".pob.forced", "pb.forced" ] try: dest_folder = get_subtitle_destination_folder() subliminal_patch.core.CUSTOM_PATHS = [dest_folder ] if dest_folder else [] subtitles = search_external_subtitles( file, languages=get_language_set(), only_one=settings.general.getboolean('single_language')) except Exception as e: logging.exception("BAZARR unable to index external subtitles.") pass else: for subtitle, language in subtitles.iteritems(): subtitle_path = get_external_subtitles_path(file, subtitle) if str(os.path.splitext(subtitle)[0]).lower().endswith( tuple(brazilian_portuguese)): logging.debug("BAZARR external subtitles detected: " + "pb") actual_subtitles.append( [str("pb"), path_replace_reverse(subtitle_path)]) elif str(os.path.splitext(subtitle)[0]).lower().endswith( tuple(brazilian_portuguese_forced)): logging.debug("BAZARR external subtitles detected: " + "pb:forced") actual_subtitles.append([ str("pb:forced"), path_replace_reverse(subtitle_path) ]) elif str(language) != 'und': logging.debug("BAZARR external subtitles detected: " + str(language)) actual_subtitles.append( [str(language), path_replace_reverse(subtitle_path)]) else: if os.path.splitext(subtitle)[1] != ".sub": logging.debug( "BAZARR falling back to file content analysis to detect language." ) with open( os.path.join(os.path.dirname(file), subtitle), 'r') as f: text = list(islice(f, 100)) text = ' '.join(text) encoding = UnicodeDammit(text) try: text = text.decode(encoding.original_encoding) detected_language = langdetect.detect(text) except Exception as e: logging.exception( 'BAZARR Error trying to detect language for this subtitles file: ' + os.path.join(os.path.dirname(file), subtitle) + ' You should try to delete this subtitles file manually and ask Bazarr to download it again.' ) else: if len(detected_language) > 0: logging.debug( "BAZARR external subtitles detected and analysis guessed this language: " + str(detected_language)) actual_subtitles.append([ str(detected_language), path_replace_reverse( os.path.join( os.path.dirname(file), subtitle)) ]) update_count = TableEpisodes.update({ TableEpisodes.subtitles: str(actual_subtitles) }).where(TableEpisodes.path == path_replace_reverse(file)).execute() if update_count > 0: logging.debug("BAZARR storing those languages to DB: " + str(actual_subtitles)) else: logging.debug( "BAZARR haven't been able to update existing subtitles to DB : " + str(actual_subtitles)) else: logging.debug( "BAZARR this file doesn't seems to exist or isn't accessible.") logging.debug('BAZARR ended subtitles indexing for this file: ' + file) return actual_subtitles
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_or_none() if not episode_metadata: return 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_or_none() if not movie_metadata: return 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
def store_subtitles(original_path, reversed_path, use_cache=True): logging.debug('BAZARR started subtitles indexing for this file: ' + reversed_path) actual_subtitles = [] if os.path.exists(reversed_path): if settings.general.getboolean('use_embedded_subs'): logging.debug("BAZARR is trying to index embedded subtitles.") item = TableEpisodes.select(TableEpisodes.episode_file_id, TableEpisodes.file_size)\ .where(TableEpisodes.path == original_path)\ .dicts()\ .get_or_none() if not item: logging.exception(f"BAZARR error when trying to select this episode from database: {reversed_path}") else: try: subtitle_languages = embedded_subs_reader(reversed_path, file_size=item['file_size'], episode_file_id=item['episode_file_id'], use_cache=use_cache) for subtitle_language, subtitle_forced, subtitle_hi, subtitle_codec in subtitle_languages: try: if (settings.general.getboolean("ignore_pgs_subs") and subtitle_codec.lower() == "pgs") or \ (settings.general.getboolean("ignore_vobsub_subs") and subtitle_codec.lower() == "vobsub") or \ (settings.general.getboolean("ignore_ass_subs") and subtitle_codec.lower() == "ass"): logging.debug("BAZARR skipping %s sub for language: %s" % (subtitle_codec, alpha2_from_alpha3(subtitle_language))) continue if alpha2_from_alpha3(subtitle_language) is not None: lang = str(alpha2_from_alpha3(subtitle_language)) if subtitle_forced: lang = lang + ":forced" if subtitle_hi: lang = lang + ":hi" logging.debug("BAZARR embedded subtitles detected: " + lang) actual_subtitles.append([lang, None]) except Exception as error: logging.debug("BAZARR unable to index this unrecognized language: %s (%s)", subtitle_language, error) except Exception: logging.exception( "BAZARR error when trying to analyze this %s file: %s" % (os.path.splitext(reversed_path)[1], reversed_path)) pass try: dest_folder = get_subtitle_destination_folder() core.CUSTOM_PATHS = [dest_folder] if dest_folder else [] subtitles = search_external_subtitles(reversed_path, languages=get_language_set(), only_one=settings.general.getboolean('single_language')) full_dest_folder_path = os.path.dirname(reversed_path) if dest_folder: if settings.general.subfolder == "absolute": full_dest_folder_path = dest_folder elif settings.general.subfolder == "relative": full_dest_folder_path = os.path.join(os.path.dirname(reversed_path), dest_folder) subtitles = guess_external_subtitles(full_dest_folder_path, subtitles) except Exception: logging.exception("BAZARR unable to index external subtitles.") else: for subtitle, language in subtitles.items(): valid_language = False if language: if hasattr(language, 'alpha3'): valid_language = alpha2_from_alpha3(language.alpha3) else: logging.debug(f"Skipping subtitles because we are unable to define language: {subtitle}") continue if not valid_language: logging.debug(f'{language.alpha3} is an unsupported language code.') continue subtitle_path = get_external_subtitles_path(reversed_path, subtitle) custom = CustomLanguage.found_external(subtitle, subtitle_path) if custom is not None: actual_subtitles.append([custom, path_mappings.path_replace_reverse(subtitle_path)]) elif str(language) != 'und': if language.forced: language_str = str(language) elif language.hi: language_str = str(language) + ':hi' else: language_str = str(language) logging.debug("BAZARR external subtitles detected: " + language_str) actual_subtitles.append([language_str, path_mappings.path_replace_reverse(subtitle_path)]) TableEpisodes.update({TableEpisodes.subtitles: str(actual_subtitles)})\ .where(TableEpisodes.path == original_path)\ .execute() matching_episodes = TableEpisodes.select(TableEpisodes.sonarrEpisodeId, TableEpisodes.sonarrSeriesId)\ .where(TableEpisodes.path == original_path)\ .dicts() for episode in matching_episodes: if episode: logging.debug("BAZARR storing those languages to DB: " + str(actual_subtitles)) list_missing_subtitles(epno=episode['sonarrEpisodeId']) else: logging.debug("BAZARR haven't been able to update existing subtitles to DB : " + str(actual_subtitles)) else: logging.debug("BAZARR this file doesn't seems to exist or isn't accessible.") logging.debug('BAZARR ended subtitles indexing for this file: ' + reversed_path) return actual_subtitles