def postprocessEpisode(item): postprocess(item) if 'audio_language' in item and item['audio_language'] is not None: item['audio_language'] = get_audio_profile_languages(episode_id=item['sonarrEpisodeId']) if 'subtitles' in item: if item['subtitles'] is None: raw_subtitles = [] else: raw_subtitles = ast.literal_eval(item['subtitles']) subtitles = [] for subs in raw_subtitles: subtitle = subs[0].split(':') sub = {"name": language_from_alpha2(subtitle[0]), "code2": subtitle[0], "code3": alpha3_from_alpha2(subtitle[0]), "path": path_mappings.path_replace(subs[1]), "forced": False, "hi": False} if len(subtitle) > 1: sub["forced"] = True if subtitle[1] == 'forced' else False sub["hi"] = True if subtitle[1] == 'hi' else False subtitles.append(sub) item.update({"subtitles": subtitles}) # Parse missing subtitles if 'missing_subtitles' in item: if item['missing_subtitles'] is None: item['missing_subtitles'] = [] else: item['missing_subtitles'] = ast.literal_eval(item['missing_subtitles']) for i, subs in enumerate(item['missing_subtitles']): subtitle = subs.split(':') item['missing_subtitles'][i] = {"name": language_from_alpha2(subtitle[0]), "code2": subtitle[0], "code3": alpha3_from_alpha2(subtitle[0]), "forced": False, "hi": False} if len(subtitle) > 1: item['missing_subtitles'][i].update({ "forced": True if subtitle[1] == 'forced' else False, "hi": True if subtitle[1] == 'hi' else False }) if 'scene_name' in item: item["sceneName"] = item["scene_name"] del item["scene_name"] if 'path' in item and item['path']: # Provide mapped path item['path'] = path_mappings.path_replace(item['path'])
def historystats(): data_providers = database.execute( "SELECT DISTINCT provider FROM table_history WHERE provider IS NOT null " "UNION SELECT DISTINCT provider FROM table_history_movie WHERE provider " "IS NOT null") data_providers_list = [] for item in data_providers: data_providers_list.append(item['provider']) data_languages = database.execute( "SELECT DISTINCT language FROM table_history WHERE language IS NOT null " "AND language != '' UNION SELECT DISTINCT language FROM table_history_movie " "WHERE language IS NOT null AND language != ''") data_languages_list = [] for item in data_languages: splitted_lang = item['language'].split(':') item = { "name": language_from_alpha2(splitted_lang[0]), "code2": splitted_lang[0], "code3": alpha3_from_alpha2(splitted_lang[0]), "forced": True if len(splitted_lang) > 1 else False } data_languages_list.append(item) return render_template('historystats.html', data_providers=data_providers_list, data_languages=sorted(data_languages_list, key=lambda i: i['name']))
def postprocess(item): # Remove ffprobe_cache if 'ffprobe_cache' in item: del (item['ffprobe_cache']) # Parse tags if 'tags' in item: if item['tags'] is None: item['tags'] = [] else: item['tags'] = ast.literal_eval(item['tags']) if 'monitored' in item: if item['monitored'] is None: item['monitored'] = False else: item['monitored'] = item['monitored'] == 'True' if 'hearing_impaired' in item and item['hearing_impaired'] is not None: if item['hearing_impaired'] is None: item['hearing_impaired'] = False else: item['hearing_impaired'] = item['hearing_impaired'] == 'True' if 'language' in item: if item['language'] == 'None': item['language'] = None elif item['language'] is not None: splitted_language = item['language'].split(':') item['language'] = {"name": language_from_alpha2(splitted_language[0]), "code2": splitted_language[0], "code3": alpha3_from_alpha2(splitted_language[0]), "forced": True if item['language'].endswith(':forced') else False, "hi": True if item['language'].endswith(':hi') else False}
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 settings.subsync.getboolean('debug'): return result 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_alpha2(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=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=srt_lang, subtitles_path=srt_path) else: logging.error('BAZARR unable to sync subtitles: {0}'.format(self.srtin)) return result
def series_download_subtitles(no): if settings.sonarr.getboolean('only_monitored'): monitored_only_query_string = ' AND monitored = "True"' else: monitored_only_query_string = "" conn_db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) c_db = conn_db.cursor() episodes_details = c_db.execute( 'SELECT path, missing_subtitles, sonarrEpisodeId, scene_name FROM table_episodes WHERE sonarrSeriesId = ? AND missing_subtitles != "[]"' + monitored_only_query_string, (no, )).fetchall() series_details = c_db.execute( "SELECT hearing_impaired, title FROM table_shows WHERE sonarrSeriesId = ?", (no, )).fetchone() c_db.close() providers_list = get_providers() providers_auth = get_providers_auth() for episode in episodes_details: for language in ast.literal_eval(episode[1]): if language is not None: notifications.write(msg='Searching for ' + str(language_from_alpha2(language)) + ' subtitles for this episode: ' + path_replace(episode[0]), queue='get_subtitle') result = download_subtitle(path_replace(episode[0]), str(alpha3_from_alpha2(language)), series_details[0], providers_list, providers_auth, str(episode[3]), series_details[1], 'series') if result is not None: message = result[0] path = result[1] language_code = result[2] provider = result[3] score = result[4] store_subtitles(path_replace(episode[0])) history_log(1, no, episode[2], message, path, language_code, provider, score) send_notifications(no, episode[2], message) list_missing_subtitles(no) notifications.write(msg='Searching completed. Please reload the page.', type='success', duration='permanent', button='refresh', queue='get_subtitle')
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 language_log = language language_string = language_from_alpha2(language) if hi in [True, 'true', 'True']: language_log += ':hi' language_string += ' HI' elif forced in [True, 'true', 'True']: language_log += ':forced' language_string += ' forced' 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 episode_download_subtitles(no): if settings.sonarr.getboolean('only_monitored'): monitored_only_query_string = ' AND monitored = "True"' else: monitored_only_query_string = "" conn_db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) c_db = conn_db.cursor() episodes_details = c_db.execute( 'SELECT table_episodes.path, table_episodes.missing_subtitles, table_episodes.sonarrEpisodeId, table_episodes.scene_name, table_shows.hearing_impaired, table_shows.title, table_shows.sonarrSeriesId FROM table_episodes INNER JOIN table_shows on table_shows.sonarrSeriesId = table_episodes.sonarrSeriesId WHERE table_episodes.sonarrEpisodeId = ?' + monitored_only_query_string, (no, )).fetchall() c_db.close() providers_list = get_providers() providers_auth = get_providers_auth() for episode in episodes_details: for language in ast.literal_eval(episode[1]): if language is not None: notifications.write(msg='Searching for ' + str(language_from_alpha2(language)) + ' subtitles for this episode: ' + path_replace(episode[0]), queue='get_subtitle') result = download_subtitle(path_replace(episode[0]), str(alpha3_from_alpha2(language)), episode[4], providers_list, providers_auth, str(episode[3]), episode[5], 'series') if result is not None: message = result[0] path = result[1] language_code = result[2] provider = result[3] score = result[4] store_subtitles(path_replace(episode[0])) history_log(1, episode[6], episode[2], message, path, language_code, provider, score) send_notifications(episode[6], episode[2], message) list_missing_subtitles(episode[6])
def movies_download_subtitles(no): conn_db = sqlite3.connect(os.path.join(args.config_dir, 'db', 'bazarr.db'), timeout=30) c_db = conn_db.cursor() movie = c_db.execute( "SELECT path, missing_subtitles, radarrId, sceneName, hearing_impaired, title FROM table_movies WHERE radarrId = ?", (no, )).fetchone() c_db.close() providers_list = get_providers() providers_auth = get_providers_auth() for language in ast.literal_eval(movie[1]): if language is not None: notifications.write( msg='Searching for ' + str(language_from_alpha2(language)) + ' subtitles for this movie: ' + path_replace_movie(movie[0]), queue='get_subtitle') result = download_subtitle(path_replace_movie(movie[0]), str(alpha3_from_alpha2(language)), movie[4], providers_list, providers_auth, str(movie[3]), movie[5], 'movie') if result is not None: message = result[0] path = result[1] language_code = result[2] provider = result[3] score = result[4] store_subtitles_movie(path_replace_movie(movie[0])) history_log_movie(1, no, message, path, language_code, provider, score) send_notifications_movie(no, message) list_missing_subtitles_movies(no) notifications.write(msg='Searching completed. Please reload the page.', type='success', duration='permanent', button='refresh', queue='get_subtitle')
def wanted_download_subtitles_movie(path): conn_db = sqlite3.connect(os.path.join(config_dir, 'db', 'bazarr.db'), timeout=30) c_db = conn_db.cursor() movies_details = c_db.execute("SELECT path, missing_subtitles, radarrId, radarrId, hearing_impaired, sceneName, failedAttempts FROM table_movies WHERE path = ? AND missing_subtitles != '[]'", (path_replace_reverse_movie(path),)).fetchall() c_db.close() providers_list = get_providers() providers_auth = get_providers_auth() for movie in movies_details: attempt = movie[6] if type(attempt) == unicode: attempt = ast.literal_eval(attempt) for language in ast.literal_eval(movie[1]): if attempt is None: attempt = [] attempt.append([language, time.time()]) else: att = zip(*attempt)[0] if language not in att: attempt.append([language, time.time()]) conn_db = sqlite3.connect(os.path.join(config_dir, 'db', 'bazarr.db'), timeout=30) c_db = conn_db.cursor() c_db.execute('UPDATE table_movies SET failedAttempts = ? WHERE radarrId = ?', (unicode(attempt), movie[2])) conn_db.commit() c_db.close() for i in range(len(attempt)): if attempt[i][0] == language: if search_active(attempt[i][1]) is True: q4ws.append('Searching ' + str(language_from_alpha2(language)) + ' subtitles for this file: ' + path) message = download_subtitle(path_replace_movie(movie[0]), str(alpha3_from_alpha2(language)), movie[4], providers_list, providers_auth, str(movie[5]), 'movie') if message is not None: store_subtitles_movie(path_replace_movie(movie[0])) list_missing_subtitles_movies(movie[3]) history_log_movie(1, movie[3], message) send_notifications_movie(movie[3], message) else: logging.info('BAZARR Search is not active for movie ' + movie[0] + ' Language: ' + attempt[i][0])
def wanted_download_subtitles(path): conn_db = sqlite3.connect(os.path.join(config_dir, 'db', 'bazarr.db'), timeout=30) c_db = conn_db.cursor() episodes_details = c_db.execute("SELECT table_episodes.path, table_episodes.missing_subtitles, table_episodes.sonarrEpisodeId, table_episodes.sonarrSeriesId, table_shows.hearing_impaired, table_episodes.scene_name, table_episodes.failedAttempts FROM table_episodes INNER JOIN table_shows on table_shows.sonarrSeriesId = table_episodes.sonarrSeriesId WHERE table_episodes.path = ? AND missing_subtitles != '[]'", (path_replace_reverse(path),)).fetchall() c_db.close() providers_list = get_providers() providers_auth = get_providers_auth() for episode in episodes_details: attempt = episode[6] if type(attempt) == unicode: attempt = ast.literal_eval(attempt) for language in ast.literal_eval(episode[1]): if attempt is None: attempt = [] attempt.append([language, time.time()]) else: att = zip(*attempt)[0] if language not in att: attempt.append([language, time.time()]) 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 failedAttempts = ? WHERE sonarrEpisodeId = ?', (unicode(attempt), episode[2])) conn_db.commit() c_db.close() for i in range(len(attempt)): if attempt[i][0] == language: if search_active(attempt[i][1]) is True: q4ws.append('Searching ' + str(language_from_alpha2(language)) + ' subtitles for this file: ' + path) message = download_subtitle(path_replace(episode[0]), str(alpha3_from_alpha2(language)), episode[4], providers_list, providers_auth, str(episode[5]), 'series') if message is not None: store_subtitles(path_replace(episode[0])) list_missing_subtitles(episode[3]) history_log(1, episode[3], episode[2], message) send_notifications(episode[3], episode[2], message) else: logging.debug('BAZARR Search is not active for episode ' + episode[0] + ' Language: ' + attempt[i][0])
def list_missing_subtitles_movies(no=None, epno=None, send_event=True): if no is not None: movies_subtitles_clause = " WHERE radarrId=" + str(no) else: movies_subtitles_clause = "" movies_subtitles = database.execute( "SELECT radarrId, subtitles, profileId, audio_language FROM table_movies" + movies_subtitles_clause) if isinstance(movies_subtitles, str): logging.error( "BAZARR list missing subtitles query to DB returned this instead of rows: " + movies_subtitles) return use_embedded_subs = settings.general.getboolean('use_embedded_subs') for movie_subtitles in movies_subtitles: missing_subtitles_text = '[]' if movie_subtitles['profileId']: # get desired subtitles desired_subtitles_temp = get_profiles_list( profile_id=movie_subtitles['profileId']) desired_subtitles_list = [] if desired_subtitles_temp: for language in ast.literal_eval( desired_subtitles_temp['items']): if language['audio_exclude'] == "True": cutoff_lang_temp = get_profile_cutoff( profile_id=movie_subtitles['profileId']) if cutoff_lang_temp: if language_from_alpha2( cutoff_lang_temp[0] ['language']) in ast.literal_eval( movie_subtitles['audio_language']): desired_subtitles_list = [] break if language_from_alpha2( language['language']) in ast.literal_eval( movie_subtitles['audio_language']): continue desired_subtitles_list.append([ language['language'], language['forced'], language['hi'] ]) # get existing subtitles actual_subtitles_list = [] if movie_subtitles['subtitles'] is not None: if use_embedded_subs: actual_subtitles_temp = ast.literal_eval( movie_subtitles['subtitles']) else: actual_subtitles_temp = [ x for x in ast.literal_eval(movie_subtitles['subtitles']) if x[1] ] for subtitles in actual_subtitles_temp: subtitles = subtitles[0].split(':') lang = subtitles[0] forced = False hi = False if len(subtitles) > 1: if subtitles[1] == 'forced': forced = True hi = False elif subtitles[1] == 'hi': forced = False hi = True actual_subtitles_list.append([lang, str(forced), str(hi)]) # check if cutoff is reached and skip any further check cutoff_met = False cutoff_temp_list = get_profile_cutoff( profile_id=movie_subtitles['profileId']) if cutoff_temp_list: for cutoff_temp in cutoff_temp_list: cutoff_language = [ cutoff_temp['language'], cutoff_temp['forced'], cutoff_temp['hi'] ] if cutoff_language in actual_subtitles_list: cutoff_met = True missing_subtitles_text = str([]) elif cutoff_language and [ cutoff_language[0], 'True', 'False' ] in actual_subtitles_list: cutoff_met = True missing_subtitles_text = str([]) elif cutoff_language and [ cutoff_language[0], 'False', 'True' ] in actual_subtitles_list: cutoff_met = True missing_subtitles_text = str([]) if not cutoff_met: # get difference between desired and existing subtitles missing_subtitles_list = [] for item in desired_subtitles_list: if item not in actual_subtitles_list: missing_subtitles_list.append(item) # remove missing that have forced or hi subtitles for this language in existing for item in actual_subtitles_list: if item[1] == 'True' or item[2] == 'True': try: missing_subtitles_list.remove( [item[0], 'False', 'False']) except ValueError: pass # make the missing languages list looks like expected missing_subtitles_output_list = [] for item in missing_subtitles_list: lang = item[0] if item[1] == 'True': lang += ':forced' elif item[2] == 'True': lang += ':hi' missing_subtitles_output_list.append(lang) missing_subtitles_text = str(missing_subtitles_output_list) database.execute( "UPDATE table_movies SET missing_subtitles=? WHERE radarrId=?", (missing_subtitles_text, movie_subtitles['radarrId'])) if send_event: event_stream(type='movie', action='update', movie=movie_subtitles['radarrId']) event_stream(type='badges_movies')
def movieParser(movie, action, tags_dict, movie_default_profile, audio_profiles): if 'movieFile' in movie: # Detect file separator if movie['path'][0] == "/": separator = "/" else: separator = "\\" try: overview = str(movie['overview']) except Exception: overview = "" try: poster_big = movie['images'][0]['url'] poster = os.path.splitext( poster_big)[0] + '-500' + os.path.splitext(poster_big)[1] except Exception: poster = "" try: fanart = movie['images'][1]['url'] except Exception: fanart = "" if 'sceneName' in movie['movieFile']: sceneName = movie['movieFile']['sceneName'] else: sceneName = None alternativeTitles = None if get_radarr_info.is_legacy(): if 'alternativeTitles' in movie: alternativeTitles = str( [item['title'] for item in movie['alternativeTitles']]) else: if 'alternateTitles' in movie: alternativeTitles = str( [item['title'] for item in movie['alternateTitles']]) if 'imdbId' in movie: imdbId = movie['imdbId'] else: imdbId = None try: format, resolution = movie['movieFile']['quality']['quality'][ 'name'].split('-') except Exception: format = movie['movieFile']['quality']['quality']['name'] try: resolution = str(movie['movieFile']['quality']['quality'] ['resolution']) + 'p' except Exception: resolution = None if 'mediaInfo' in movie['movieFile']: videoFormat = videoCodecID = videoCodecLibrary = None if get_radarr_info.is_legacy(): if 'videoFormat' in movie['movieFile']['mediaInfo']: videoFormat = movie['movieFile']['mediaInfo'][ 'videoFormat'] else: if 'videoCodec' in movie['movieFile']['mediaInfo']: videoFormat = movie['movieFile']['mediaInfo']['videoCodec'] if 'videoCodecID' in movie['movieFile']['mediaInfo']: videoCodecID = movie['movieFile']['mediaInfo']['videoCodecID'] if 'videoCodecLibrary' in movie['movieFile']['mediaInfo']: videoCodecLibrary = movie['movieFile']['mediaInfo'][ 'videoCodecLibrary'] videoCodec = RadarrFormatVideoCodec(videoFormat, videoCodecID, videoCodecLibrary) audioFormat = audioCodecID = audioProfile = audioAdditionalFeatures = None if get_radarr_info.is_legacy(): if 'audioFormat' in movie['movieFile']['mediaInfo']: audioFormat = movie['movieFile']['mediaInfo'][ 'audioFormat'] else: if 'audioCodec' in movie['movieFile']['mediaInfo']: audioFormat = movie['movieFile']['mediaInfo']['audioCodec'] if 'audioCodecID' in movie['movieFile']['mediaInfo']: audioCodecID = movie['movieFile']['mediaInfo']['audioCodecID'] if 'audioProfile' in movie['movieFile']['mediaInfo']: audioProfile = movie['movieFile']['mediaInfo']['audioProfile'] if 'audioAdditionalFeatures' in movie['movieFile']['mediaInfo']: audioAdditionalFeatures = movie['movieFile']['mediaInfo'][ 'audioAdditionalFeatures'] audioCodec = RadarrFormatAudioCodec(audioFormat, audioCodecID, audioProfile, audioAdditionalFeatures) else: videoCodec = None audioCodec = None audio_language = [] if get_radarr_info.is_legacy(): if 'mediaInfo' in movie['movieFile']: if 'audioLanguages' in movie['movieFile']['mediaInfo']: audio_languages_list = movie['movieFile']['mediaInfo'][ 'audioLanguages'].split('/') if len(audio_languages_list): for audio_language_list in audio_languages_list: audio_language.append(audio_language_list.strip()) if not audio_language: audio_language = profile_id_to_language( movie['qualityProfileId'], audio_profiles) else: if 'languages' in movie['movieFile'] and len( movie['movieFile']['languages']): for item in movie['movieFile']['languages']: if isinstance(item, dict): if 'name' in item: language = item['name'] if item['name'] == 'Portuguese (Brazil)': language = language_from_alpha2('pb') audio_language.append(language) tags = [d['label'] for d in tags_dict if d['id'] in movie['tags']] if action == 'update': return { 'radarrId': int(movie["id"]), 'title': movie["title"], 'path': movie["path"] + separator + movie['movieFile']['relativePath'], 'tmdbId': str(movie["tmdbId"]), 'poster': poster, 'fanart': fanart, 'audio_language': str(audio_language), 'sceneName': sceneName, 'monitored': str(bool(movie['monitored'])), 'year': str(movie['year']), 'sortTitle': movie['sortTitle'], 'alternativeTitles': alternativeTitles, 'format': format, 'resolution': resolution, 'video_codec': videoCodec, 'audio_codec': audioCodec, 'overview': overview, 'imdbId': imdbId, 'movie_file_id': int(movie['movieFile']['id']), 'tags': str(tags), 'file_size': movie['movieFile']['size'] } else: return { 'radarrId': int(movie["id"]), 'title': movie["title"], 'path': movie["path"] + separator + movie['movieFile']['relativePath'], 'tmdbId': str(movie["tmdbId"]), 'subtitles': '[]', 'overview': overview, 'poster': poster, 'fanart': fanart, 'audio_language': str(audio_language), 'sceneName': sceneName, 'monitored': str(bool(movie['monitored'])), 'sortTitle': movie['sortTitle'], 'year': str(movie['year']), 'alternativeTitles': alternativeTitles, 'format': format, 'resolution': resolution, 'video_codec': videoCodec, 'audio_codec': audioCodec, 'imdbId': imdbId, 'movie_file_id': int(movie['movieFile']['id']), 'tags': str(tags), 'profileId': movie_default_profile, 'file_size': movie['movieFile']['size'] }
def postprocessMovie(item): postprocess(item) # Parse audio language if 'audio_language' in item and item['audio_language'] is not None: item['audio_language'] = get_audio_profile_languages(movie_id=item['radarrId']) # Parse alternate titles if 'alternativeTitles' in item: if item['alternativeTitles'] is None: item['alternativeTitles'] = [] else: item['alternativeTitles'] = ast.literal_eval(item['alternativeTitles']) # Parse failed attempts if 'failedAttempts' in item: if item['failedAttempts']: item['failedAttempts'] = ast.literal_eval(item['failedAttempts']) # Parse subtitles if 'subtitles' in item: if item['subtitles'] is None: item['subtitles'] = [] else: item['subtitles'] = ast.literal_eval(item['subtitles']) for i, subs in enumerate(item['subtitles']): language = subs[0].split(':') item['subtitles'][i] = {"path": path_mappings.path_replace_movie(subs[1]), "name": language_from_alpha2(language[0]), "code2": language[0], "code3": alpha3_from_alpha2(language[0]), "forced": False, "hi": False} if len(language) > 1: item['subtitles'][i].update({ "forced": True if language[1] == 'forced' else False, "hi": True if language[1] == 'hi' else False }) if settings.general.getboolean('embedded_subs_show_desired'): desired_lang_list = get_desired_languages(item['profileId']) item['subtitles'] = [x for x in item['subtitles'] if x['code2'] in desired_lang_list or x['path']] item['subtitles'] = sorted(item['subtitles'], key=itemgetter('name', 'forced')) # Parse missing subtitles if 'missing_subtitles' in item: if item['missing_subtitles'] is None: item['missing_subtitles'] = [] else: item['missing_subtitles'] = ast.literal_eval(item['missing_subtitles']) for i, subs in enumerate(item['missing_subtitles']): language = subs.split(':') item['missing_subtitles'][i] = {"name": language_from_alpha2(language[0]), "code2": language[0], "code3": alpha3_from_alpha2(language[0]), "forced": False, "hi": False} if len(language) > 1: item['missing_subtitles'][i].update({ "forced": True if language[1] == 'forced' else False, "hi": True if language[1] == 'hi' else False }) # Provide mapped path if 'path' in item: if item['path']: item['path'] = path_mappings.path_replace_movie(item['path']) if 'subtitles_path' in item: # Provide mapped subtitles path item['subtitles_path'] = path_mappings.path_replace_movie(item['subtitles_path']) # map poster and fanart to server proxy if 'poster' in item: poster = item['poster'] item['poster'] = f"{base_url}/images/movies{poster}" if poster else None if 'fanart' in item: fanart = item['fanart'] item['fanart'] = f"{base_url}/images/movies{fanart}" if fanart else None
def list_missing_subtitles_movies(no=None, send_event=True): movies_subtitles = TableMovies.select(TableMovies.radarrId, TableMovies.subtitles, TableMovies.profileId, TableMovies.audio_language)\ .where((TableMovies.radarrId == no) if no else None)\ .dicts() if isinstance(movies_subtitles, str): logging.error("BAZARR list missing subtitles query to DB returned this instead of rows: " + movies_subtitles) return use_embedded_subs = settings.general.getboolean('use_embedded_subs') for movie_subtitles in movies_subtitles: missing_subtitles_text = '[]' if movie_subtitles['profileId']: # get desired subtitles desired_subtitles_temp = get_profiles_list(profile_id=movie_subtitles['profileId']) desired_subtitles_list = [] if desired_subtitles_temp: for language in desired_subtitles_temp['items']: if language['audio_exclude'] == "True": if language_from_alpha2(language['language']) in ast.literal_eval( movie_subtitles['audio_language']): continue desired_subtitles_list.append([language['language'], language['forced'], language['hi']]) # get existing subtitles actual_subtitles_list = [] if movie_subtitles['subtitles'] is not None: if use_embedded_subs: actual_subtitles_temp = ast.literal_eval(movie_subtitles['subtitles']) else: actual_subtitles_temp = [x for x in ast.literal_eval(movie_subtitles['subtitles']) if x[1]] for subtitles in actual_subtitles_temp: subtitles = subtitles[0].split(':') lang = subtitles[0] forced = False hi = False if len(subtitles) > 1: if subtitles[1] == 'forced': forced = True hi = False elif subtitles[1] == 'hi': forced = False hi = True actual_subtitles_list.append([lang, str(forced), str(hi)]) # check if cutoff is reached and skip any further check cutoff_met = False cutoff_temp_list = get_profile_cutoff(profile_id=movie_subtitles['profileId']) if cutoff_temp_list: for cutoff_temp in cutoff_temp_list: cutoff_language = [cutoff_temp['language'], cutoff_temp['forced'], cutoff_temp['hi']] if cutoff_temp['audio_exclude'] == 'True' and language_from_alpha2(cutoff_temp['language']) in \ ast.literal_eval(movie_subtitles['audio_language']): cutoff_met = True elif cutoff_language in actual_subtitles_list: cutoff_met = True elif cutoff_language and [cutoff_language[0], 'True', 'False'] in actual_subtitles_list: cutoff_met = True elif cutoff_language and [cutoff_language[0], 'False', 'True'] in actual_subtitles_list: cutoff_met = True if cutoff_met: missing_subtitles_text = str([]) else: # get difference between desired and existing subtitles missing_subtitles_list = [] for item in desired_subtitles_list: if item not in actual_subtitles_list: missing_subtitles_list.append(item) # remove missing that have forced or hi subtitles for this language in existing for item in actual_subtitles_list: if item[2] == 'True': try: missing_subtitles_list.remove([item[0], 'False', 'False']) except ValueError: pass # make the missing languages list looks like expected missing_subtitles_output_list = [] for item in missing_subtitles_list: lang = item[0] if item[1] == 'True': lang += ':forced' elif item[2] == 'True': lang += ':hi' missing_subtitles_output_list.append(lang) missing_subtitles_text = str(missing_subtitles_output_list) TableMovies.update({TableMovies.missing_subtitles: missing_subtitles_text})\ .where(TableMovies.radarrId == movie_subtitles['radarrId'])\ .execute() if send_event: event_stream(type='movie', payload=movie_subtitles['radarrId']) event_stream(type='badges')