Cache ffprobe results

This commit is contained in:
Abdulmohsen 2021-05-01 00:52:56 +03:00 committed by GitHub
parent 72c9899f58
commit dcbd7f004c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 248 additions and 162 deletions

View File

@ -721,7 +721,7 @@ class EpisodesSubtitles(Resource):
history_log(1, sonarrSeriesId, sonarrEpisodeId, message, path, language_code, provider, score, subs_id,
subs_path)
send_notifications(sonarrSeriesId, sonarrEpisodeId, message)
store_subtitles(path, episodePath)
store_subtitles(path, episodePath, 'episode', sonarrEpisodeId)
else:
event_stream(type='episode', action='update', series=int(sonarrSeriesId), episode=int(sonarrEpisodeId))
@ -777,7 +777,7 @@ class EpisodesSubtitles(Resource):
subtitles_path=subs_path)
if not settings.general.getboolean('dont_notify_manual_actions'):
send_notifications(sonarrSeriesId, sonarrEpisodeId, message)
store_subtitles(path, episodePath)
store_subtitles(path, episodePath, 'episode', sonarrEpisodeId)
except OSError:
pass
@ -927,7 +927,7 @@ class MoviesSubtitles(Resource):
subs_path = result[7]
history_log_movie(1, radarrId, message, path, language_code, provider, score, subs_id, subs_path)
send_notifications_movie(radarrId, message)
store_subtitles_movie(path, moviePath)
store_subtitles_movie(path, moviePath, 'movie', radarrId)
else:
event_stream(type='movie', action='update', movie=int(radarrId))
except OSError:
@ -982,7 +982,7 @@ class MoviesSubtitles(Resource):
history_log_movie(4, radarrId, message, path, language_code, provider, score, subtitles_path=subs_path)
if not settings.general.getboolean('dont_notify_manual_actions'):
send_notifications_movie(radarrId, message)
store_subtitles_movie(path, moviePath)
store_subtitles_movie(path, moviePath, 'movie', radarrId)
except OSError:
pass
@ -1109,7 +1109,7 @@ class ProviderMovies(Resource):
history_log_movie(2, radarrId, message, path, language_code, provider, score, subs_id, subs_path)
if not settings.general.getboolean('dont_notify_manual_actions'):
send_notifications_movie(radarrId, message)
store_subtitles_movie(path, moviePath)
store_subtitles_movie(path, moviePath, 'movie', radarrId)
except OSError:
pass
@ -1192,7 +1192,7 @@ class ProviderEpisodes(Resource):
subs_path)
if not settings.general.getboolean('dont_notify_manual_actions'):
send_notifications(sonarrSeriesId, sonarrEpisodeId, message)
store_subtitles(path, episodePath)
store_subtitles(path, episodePath, 'episode', sonarrEpisodeId)
return result, 201
except OSError:
pass
@ -1654,9 +1654,9 @@ class Subtitles(Resource):
forced=forced, hi=hi)
if result:
if media_type == 'episode':
store_subtitles(path_mappings.path_replace_reverse(video_path), video_path)
store_subtitles(path_mappings.path_replace_reverse(video_path), video_path, 'episode', id)
else:
store_subtitles_movie(path_mappings.path_replace_reverse_movie(video_path), video_path)
store_subtitles_movie(path_mappings.path_replace_reverse_movie(video_path), video_path, 'movie', id)
return '', 200
else:
return '', 404

View File

@ -108,6 +108,8 @@ def db_upgrade():
['table_episodes', 'audio_codec', 'text'],
['table_episodes', 'episode_file_id', 'integer'],
['table_episodes', 'audio_language', 'text'],
['table_episodes', 'file_size', 'integer', '0'],
['table_episodes', 'file_ffprobe', 'text'],
['table_movies', 'sortTitle', 'text'],
['table_movies', 'year', 'text'],
['table_movies', 'alternativeTitles', 'text'],
@ -120,6 +122,8 @@ def db_upgrade():
['table_movies', 'movie_file_id', 'integer'],
['table_movies', 'tags', 'text', '[]'],
['table_movies', 'profileId', 'integer'],
['table_movies', 'file_ffprobe', 'text'],
['table_movies', 'file_size', 'integer', '0'],
['table_history', 'video_path', 'text'],
['table_history', 'language', 'text'],
['table_history', 'provider', 'text'],

View File

@ -10,21 +10,28 @@ from knowit import api
class EmbeddedSubsReader:
def __init__(self):
self.ffprobe = None
def list_languages(self, file):
from utils import get_binary
self.cache = None
self.data = None
def list_languages(self, file, original_path, record_type=None, record_id=None):
from utils import get_binary, cache_get_ffprobe, cache_save_ffprobe
self.cache = cache_get_ffprobe(original_path, record_type, record_id)
if self.cache['ffprobe'] is not None:
return self.cache['ffprobe']
self.ffprobe = get_binary("ffprobe")
subtitles_list = []
if self.ffprobe:
api.initialize({'provider': 'ffmpeg', 'ffmpeg': self.ffprobe})
data = api.know(file)
self.data = api.know(file)
traditional_chinese = ["cht", "tc", "traditional", "zht", "hant", "big5", u"", u"雙語"]
brazilian_portuguese = ["pt-br", "pob", "pb", "brazilian", "brasil", "brazil"]
if 'subtitle' in data:
for detected_language in data['subtitle']:
if 'subtitle' in self.data:
for detected_language in self.data['subtitle']:
if 'language' in detected_language:
language = detected_language['language'].alpha3
if language == 'zho' and 'name' in detected_language:
@ -44,11 +51,11 @@ class EmbeddedSubsReader:
if os.path.splitext(file)[1] == '.mkv':
with open(file, 'rb') as f:
try:
mkv = enzyme.MKV(f)
self.data = enzyme.MKV(f)
except MalformedMKVError:
logging.error('BAZARR cannot analyze this MKV with our built-in MKV parser, you should install ffmpeg: ' + file)
else:
for subtitle_track in mkv.subtitle_tracks:
for subtitle_track in self.data.subtitle_tracks:
hearing_impaired = False
if subtitle_track.name:
if 'sdh' in subtitle_track.name.lower():
@ -56,6 +63,9 @@ class EmbeddedSubsReader:
subtitles_list.append([subtitle_track.language, subtitle_track.forced, hearing_impaired,
subtitle_track.codec_id])
if self.cache['type'] and self.cache['id']:
cache_save_ffprobe(original_path, self.cache['type'], self.cache['id'], subtitles_list)
return subtitles_list

View File

@ -4,7 +4,7 @@ import os
import requests
import logging
from database import database, dict_converter, get_exclusion_clause
from utils import cache_is_valid
from config import settings, url_sonarr
from helper import path_mappings
from list_subtitles import store_subtitles, series_full_scan_subtitles
@ -22,9 +22,9 @@ def update_all_episodes():
def sync_episodes():
logging.debug('BAZARR Starting episodes sync from Sonarr.')
apikey_sonarr = settings.sonarr.apikey
# Get current episodes id in DB
current_episodes_db = database.execute("SELECT sonarrEpisodeId, path, sonarrSeriesId FROM table_episodes")
current_episodes_db = database.execute("SELECT sonarrEpisodeId FROM table_episodes")
current_episodes_db_list = [x['sonarrEpisodeId'] for x in current_episodes_db]
@ -32,10 +32,10 @@ def sync_episodes():
episodes_to_update = []
episodes_to_add = []
altered_episodes = []
# Get sonarrId for each series from database
seriesIdList = database.execute("SELECT sonarrSeriesId, title FROM table_shows")
for i, seriesId in enumerate(seriesIdList):
# Get episodes data for a series from Sonarr
url_sonarr_api_episode = url_sonarr() + "/api/episode?seriesId=" + str(seriesId['sonarrSeriesId']) + "&apikey=" + apikey_sonarr
@ -66,6 +66,11 @@ def sync_episodes():
else:
sceneName = None
if 'size' in episode['episodeFile']:
fileSize = int(episode['episodeFile']['size'])
else:
fileSize = 0
try:
format, resolution = episode['episodeFile']['quality']['quality']['name'].split('-')
except:
@ -79,12 +84,14 @@ def sync_episodes():
if 'videoCodec' in episode['episodeFile']['mediaInfo']:
videoCodec = episode['episodeFile']['mediaInfo']['videoCodec']
videoCodec = SonarrFormatVideoCodec(videoCodec)
else: videoCodec = None
else:
videoCodec = None
if 'audioCodec' in episode['episodeFile']['mediaInfo']:
audioCodec = episode['episodeFile']['mediaInfo']['audioCodec']
audioCodec = SonarrFormatAudioCodec(audioCodec)
else: audioCodec = None
else:
audioCodec = None
else:
videoCodec = None
audioCodec = None
@ -102,37 +109,35 @@ def sync_episodes():
# Add episodes in sonarr to current episode list
current_episodes_sonarr.append(episode['id'])
info = {
'sonarrSeriesId': episode['seriesId'],
'sonarrEpisodeId': episode['id'],
'title': episode['title'],
'path': episode['episodeFile']['path'],
'season': episode['seasonNumber'],
'episode': episode['episodeNumber'],
'scene_name': sceneName,
'monitored': str(bool(episode['monitored'])),
'format': format,
'resolution': resolution,
'video_codec': videoCodec,
'audio_codec': audioCodec,
'episode_file_id': episode['episodeFile']['id'],
'audio_language': str(audio_language),
'file_size': fileSize,
}
if episode['id'] in current_episodes_db_list:
episodes_to_update.append({'sonarrSeriesId': episode['seriesId'],
'sonarrEpisodeId': episode['id'],
'title': episode['title'],
'path': episode['episodeFile']['path'],
'season': episode['seasonNumber'],
'episode': episode['episodeNumber'],
'scene_name': sceneName,
'monitored': str(bool(episode['monitored'])),
'format': format,
'resolution': resolution,
'video_codec': videoCodec,
'audio_codec': audioCodec,
'episode_file_id': episode['episodeFile']['id'],
'audio_language': str(audio_language)})
if not cache_is_valid(info['path'], info['file_size'], 'episode', info['sonarrEpisodeId']):
logging.debug('Path and/or Size is not the same. Invalidating ffprobe cache data for: [%s:%s, %s].',
'episode', info['sonarrEpisodeId'], info['path'])
info.update({'file_ffprobe': None})
episodes_to_update.append(info)
else:
episodes_to_add.append({'sonarrSeriesId': episode['seriesId'],
'sonarrEpisodeId': episode['id'],
'title': episode['title'],
'path': episode['episodeFile']['path'],
'season': episode['seasonNumber'],
'episode': episode['episodeNumber'],
'scene_name': sceneName,
'monitored': str(bool(episode['monitored'])),
'format': format,
'resolution': resolution,
'video_codec': videoCodec,
'audio_codec': audioCodec,
'episode_file_id': episode['episodeFile']['id'],
'audio_language': str(audio_language)})
info.update({'file_ffprobe': None})
episodes_to_add.append(info)
# Remove old episodes from DB
removed_episodes = list(set(current_episodes_db_list) - set(current_episodes_sonarr))
@ -148,7 +153,7 @@ def sync_episodes():
episode_in_db_list = []
episodes_in_db = database.execute("SELECT sonarrSeriesId, sonarrEpisodeId, title, path, season, episode, "
"scene_name, monitored, format, resolution, video_codec, audio_codec, "
"episode_file_id, audio_language FROM table_episodes")
"episode_file_id, audio_language, file_ffprobe FROM table_episodes")
for item in episodes_in_db:
episode_in_db_list.append(item)
@ -180,7 +185,8 @@ def sync_episodes():
# Store subtitles for added or modified episodes
for i, altered_episode in enumerate(altered_episodes, 1):
store_subtitles(altered_episode[1], path_mappings.path_replace(altered_episode[1]))
store_subtitles(altered_episode[1], path_mappings.path_replace(altered_episode[1]),
'episode', altered_episode[0])
logging.debug('BAZARR All episodes synced from Sonarr into database.')

View File

@ -6,7 +6,7 @@ import logging
from config import settings, url_radarr
from helper import path_mappings
from utils import get_radarr_version
from utils import get_radarr_version, cache_is_valid
from list_subtitles import store_subtitles_movie, movies_full_scan_subtitles
from get_subtitle import movies_download_subtitles
@ -39,7 +39,7 @@ def update_movies():
else:
audio_profiles = get_profile_list()
tagsDict = get_tags()
# Get movies data from radarr
if radarr_version.startswith('0'):
url_radarr_api_movies = url_radarr() + "/api/movie?apikey=" + apikey_radarr
@ -63,8 +63,8 @@ def update_movies():
return
else:
# Get current movies in DB
current_movies_db = database.execute("SELECT tmdbId, path, radarrId FROM table_movies")
current_movies_db = database.execute("SELECT tmdbId FROM table_movies")
current_movies_db_list = [x['tmdbId'] for x in current_movies_db]
current_movies_radarr = []
@ -96,12 +96,17 @@ def update_movies():
fanart = movie['images'][1]['url']
except:
fanart = ""
if 'sceneName' in movie['movieFile']:
sceneName = movie['movieFile']['sceneName']
else:
sceneName = None
if 'size' in movie['movieFile']:
fileSize = movie['movieFile']['size']
else:
fileSize = 0
alternativeTitles = None
if radarr_version.startswith('0'):
if 'alternativeTitles' in movie:
@ -110,8 +115,10 @@ def update_movies():
if 'alternateTitles' in movie:
alternativeTitles = str([item['title'] for item in movie['alternateTitles']])
if 'imdbId' in movie: imdbId = movie['imdbId']
else: imdbId = None
if 'imdbId' in movie:
imdbId = movie['imdbId']
else:
imdbId = None
try:
format, resolution = movie['movieFile']['quality']['quality']['name'].split('-')
@ -167,55 +174,43 @@ def update_movies():
# Add movies in radarr to current movies list
current_movies_radarr.append(str(movie['tmdbId']))
info = {
'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': fileSize,
}
if str(movie['tmdbId']) in current_movies_db_list:
movies_to_update.append({'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)})
if not cache_is_valid(info['path'], info['file_size'], 'movie', info['radarrId']):
logging.debug('Path and/or Size is not the same. Invalidating ffprobe cache data for: [%s:%s, %s].',
'movie', info['radarrId'], info['path'])
info.update({'file_ffprobe': None})
movies_to_update.append(info)
else:
movies_to_add.append({'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})
info.update({'file_ffprobe': None, 'profileId': movie_default_profile})
movies_to_add.append(info)
else:
logging.error(
'BAZARR Radarr returned a movie without a file path: ' + movie["path"] + separator +
movie['movieFile']['relativePath'])
logging.error('BAZARR Radarr returned a movie without a file path: ' + movie["path"] + separator + movie['movieFile']['relativePath'])
# Remove old movies from DB
removed_movies = list(set(current_movies_db_list) - set(current_movies_radarr))
@ -261,7 +256,8 @@ def update_movies():
# Store subtitles for added or modified movies
for i, altered_movie in enumerate(altered_movies, 1):
store_subtitles_movie(altered_movie[1], path_mappings.path_replace_movie(altered_movie[1]))
store_subtitles_movie(altered_movie[1], path_mappings.path_replace_movie(altered_movie[1]),
'movie', altered_movie[2])
logging.debug('BAZARR All movies synced from Radarr into database.')
@ -355,7 +351,7 @@ def RadarrFormatVideoCodec(videoFormat, videoCodecID, videoCodecLibrary):
if videoCodecLibrary and videoCodecID and videoFormat == "MPEG-4 Visual":
if videoCodecID.endswith("XVID") or videoCodecLibrary.startswith("XviD"): return "XviD"
if videoCodecID.endswith("DIV3") or videoCodecID.endswith("DIVX") or videoCodecID.endswith(
"DX50") or videoCodecLibrary.startswith("DivX"): return "DivX"
"DX50") or videoCodecLibrary.startswith("DivX"): return "DivX"
if videoFormat == "VC-1": return "VC1"
if videoFormat == "WMV2":
return "WMV"

View File

@ -248,7 +248,7 @@ def download_subtitle(path, language, audio_language, hi, forced, providers, pro
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) + "%."
downloaded_provider + " with a score of " + str(percent_score) + "%."
if media_type == 'series':
episode_metadata = database.execute("SELECT sonarrSeriesId, sonarrEpisodeId FROM "
@ -668,7 +668,7 @@ def manual_upload_subtitle(path, language, forced, title, scene_name, media_type
sub = Subtitle(
lang_obj,
mods = get_array_from(settings.general.subzero_mods)
mods=get_array_from(settings.general.subzero_mods)
)
sub.content = subtitle.read()
@ -723,7 +723,7 @@ def manual_upload_subtitle(path, language, forced, title, scene_name, media_type
sync_subtitles(video_path=path, srt_path=subtitle_path, srt_lang=uploaded_language_code3, media_type=media_type,
percent_score=100, radarr_id=movie_metadata['radarrId'])
if use_postprocessing :
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)
@ -791,7 +791,8 @@ def series_download_subtitles(no):
score = result[4]
subs_id = result[6]
subs_path = result[7]
store_subtitles(episode['path'], path_mappings.path_replace(episode['path']))
store_subtitles(episode['path'], path_mappings.path_replace(episode['path']),
'episode', episode['sonarrEpisodeId'])
history_log(1, no, episode['sonarrEpisodeId'], message, path, language_code, provider, score,
subs_id, subs_path)
send_notifications(no, episode['sonarrEpisodeId'], message)
@ -848,7 +849,8 @@ def episode_download_subtitles(no):
score = result[4]
subs_id = result[6]
subs_path = result[7]
store_subtitles(episode['path'], path_mappings.path_replace(episode['path']))
store_subtitles(episode['path'], path_mappings.path_replace(episode['path']),
'episode', episode['sonarrEpisodeId'])
history_log(1, episode['sonarrSeriesId'], episode['sonarrEpisodeId'], message, path,
language_code, provider, score, subs_id, subs_path)
send_notifications(episode['sonarrSeriesId'], episode['sonarrEpisodeId'], message)
@ -908,7 +910,8 @@ def movies_download_subtitles(no):
score = result[4]
subs_id = result[6]
subs_path = result[7]
store_subtitles_movie(movie['path'], path_mappings.path_replace_movie(movie['path']))
store_subtitles_movie(movie['path'], path_mappings.path_replace_movie(movie['path']),
'movie', movie['radarrId'])
history_log_movie(1, no, message, path, language_code, provider, score, subs_id, subs_path)
send_notifications_movie(no, message)
else:
@ -978,7 +981,8 @@ def wanted_download_subtitles(path, l, count_episodes):
score = result[4]
subs_id = result[6]
subs_path = result[7]
store_subtitles(episode['path'], path_mappings.path_replace(episode['path']))
store_subtitles(episode['path'], path_mappings.path_replace(episode['path']),
'episode', episode['sonarrEpisodeId'])
history_log(1, episode['sonarrSeriesId'], episode['sonarrEpisodeId'], message, path,
language_code, provider, score, subs_id, subs_path)
send_notifications(episode['sonarrSeriesId'], episode['sonarrEpisodeId'], message)
@ -1046,7 +1050,8 @@ def wanted_download_subtitles_movie(path, l, count_movies):
score = result[4]
subs_id = result[6]
subs_path = result[7]
store_subtitles_movie(movie['path'], path_mappings.path_replace_movie(movie['path']))
store_subtitles_movie(movie['path'], path_mappings.path_replace_movie(movie['path']),
'movie', movie['radarrId'])
history_log_movie(1, movie['radarrId'], message, path, language_code, provider, score,
subs_id, subs_path)
send_notifications_movie(movie['radarrId'], message)
@ -1240,8 +1245,8 @@ def upgrade_subtitles():
"table_episodes on table_episodes.sonarrEpisodeId = "
"table_history.sonarrEpisodeId WHERE action IN "
"(" + ','.join(map(str, query_actions)) + ") AND timestamp > ? AND "
"score is not null" + get_exclusion_clause('series') + " GROUP BY "
"table_history.video_path, table_history.language",
"score is not null" + get_exclusion_clause('series') + " GROUP BY "
"table_history.video_path, table_history.language",
(minimum_timestamp,))
upgradable_episodes_not_perfect = []
for upgradable_episode in upgradable_episodes:
@ -1271,8 +1276,8 @@ def upgrade_subtitles():
"table_movies.monitored FROM table_history_movie INNER JOIN table_movies "
"on table_movies.radarrId = table_history_movie.radarrId WHERE action IN "
"(" + ','.join(map(str, query_actions)) + ") AND timestamp > ? AND score "
"is not null" + get_exclusion_clause('movie') + " GROUP BY "
"table_history_movie.video_path, table_history_movie.language",
"is not null" + get_exclusion_clause('movie') + " GROUP BY "
"table_history_movie.video_path, table_history_movie.language",
(minimum_timestamp,))
upgradable_movies_not_perfect = []
for upgradable_movie in upgradable_movies:
@ -1347,7 +1352,8 @@ def upgrade_subtitles():
score = result[4]
subs_id = result[6]
subs_path = result[7]
store_subtitles(episode['video_path'], path_mappings.path_replace(episode['video_path']))
store_subtitles(episode['video_path'], path_mappings.path_replace(episode['video_path']),
'episode', episode['sonarrEpisodeId'])
history_log(3, episode['sonarrSeriesId'], episode['sonarrEpisodeId'], message, path,
language_code, provider, score, subs_id, subs_path)
send_notifications(episode['sonarrSeriesId'], episode['sonarrEpisodeId'], message)
@ -1406,8 +1412,8 @@ def upgrade_subtitles():
score = result[4]
subs_id = result[6]
subs_path = result[7]
store_subtitles_movie(movie['video_path'],
path_mappings.path_replace_movie(movie['video_path']))
store_subtitles_movie(movie['video_path'], path_mappings.path_replace_movie(movie['video_path']),
'movie', movie['radarrId'])
history_log_movie(3, movie['radarrId'], message, path, language_code, provider, score, subs_id, subs_path)
send_notifications_movie(movie['radarrId'], message)

View File

@ -24,14 +24,14 @@ global hi_regex
hi_regex = re.compile(r'[*¶♫♪].{3,}[*¶♫♪]|[\[\(\{].{3,}[\]\)\}](?<!{\\an\d})')
def store_subtitles(original_path, reversed_path):
def store_subtitles(original_path, reversed_path, record_type=None, record_id=None):
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)
subtitle_languages = embedded_subs_reader.list_languages(reversed_path, original_path, record_type, record_id)
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 \
@ -59,10 +59,10 @@ def store_subtitles(original_path, reversed_path):
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 = [".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 = [".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:
@ -122,7 +122,7 @@ def store_subtitles(original_path, reversed_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,))
(original_path,))
for episode in matching_episodes:
if episode:
@ -132,20 +132,20 @@ def store_subtitles(original_path, reversed_path):
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 store_subtitles_movie(original_path, reversed_path):
def store_subtitles_movie(original_path, reversed_path, record_type=None, record_id=None):
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)
subtitle_languages = embedded_subs_reader.list_languages(reversed_path, original_path, record_type, record_id)
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 \
@ -173,10 +173,10 @@ def store_subtitles_movie(original_path, reversed_path):
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 = [".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 = [".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 ''
@ -224,7 +224,7 @@ def store_subtitles_movie(original_path, reversed_path):
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,))
@ -237,7 +237,7 @@ def store_subtitles_movie(original_path, reversed_path):
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
@ -370,7 +370,6 @@ def list_missing_subtitles_movies(no=None, epno=None, send_event=True):
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:
@ -468,41 +467,43 @@ def list_missing_subtitles_movies(no=None, epno=None, send_event=True):
def series_full_scan_subtitles():
episodes = database.execute("SELECT path FROM table_episodes")
episodes = database.execute("SELECT sonarrEpisodeId, path FROM table_episodes")
for i, episode in enumerate(episodes, 1):
store_subtitles(episode['path'], path_mappings.path_replace(episode['path']))
store_subtitles(episode['path'], path_mappings.path_replace(episode['path']),
'episode', episode['sonarrEpisodeId'])
gc.collect()
def movies_full_scan_subtitles():
movies = database.execute("SELECT path FROM table_movies")
movies = database.execute("SELECT radarrId, path FROM table_movies")
for i, movie in enumerate(movies, 1):
store_subtitles_movie(movie['path'], path_mappings.path_replace_movie(movie['path']))
store_subtitles_movie(movie['path'], path_mappings.path_replace_movie(movie['path']),
'movie', movie['radarrId'])
gc.collect()
def series_scan_subtitles(no):
episodes = database.execute("SELECT path FROM table_episodes WHERE sonarrSeriesId=? ORDER BY sonarrEpisodeId",
episodes = database.execute("SELECT sonarrEpisodeId, path FROM table_episodes WHERE sonarrSeriesId=? ORDER BY sonarrEpisodeId",
(no,))
for episode in episodes:
store_subtitles(episode['path'], path_mappings.path_replace(episode['path']))
store_subtitles(episode['path'], path_mappings.path_replace(episode['path']), 'episode', episode['sonarrEpisodeId'])
def movies_scan_subtitles(no):
movies = database.execute("SELECT path FROM table_movies WHERE radarrId=? ORDER BY radarrId", (no,))
movies = database.execute("SELECT radarrId, path FROM table_movies WHERE radarrId=? ORDER BY radarrId", (no,))
for movie in movies:
store_subtitles_movie(movie['path'], path_mappings.path_replace_movie(movie['path']))
store_subtitles_movie(movie['path'], path_mappings.path_replace_movie(movie['path']), 'movie', movie['radarrId'])
def get_external_subtitles_path(file, subtitle):
fld = os.path.dirname(file)
if settings.general.subfolder == "current":
path = os.path.join(fld, subtitle)
elif settings.general.subfolder == "absolute":
@ -523,7 +524,7 @@ def get_external_subtitles_path(file, subtitle):
path = None
else:
path = None
return path
@ -536,7 +537,7 @@ def guess_external_subtitles(dest_folder, subtitles):
detected_language = None
# to improve performance, skip detection of files larger that 1M
if os.path.getsize(subtitle_path) > 1*1024*1024:
if os.path.getsize(subtitle_path) > 1 * 1024 * 1024:
logging.debug("BAZARR subtitles file is too large to be text based. Skipping this file: " +
subtitle_path)
continue
@ -547,10 +548,10 @@ def guess_external_subtitles(dest_folder, subtitles):
try:
text = text.decode('utf-8')
detected_language = guess_language(text)
#add simplified and traditional chinese detection
# add simplified and traditional chinese detection
if detected_language == 'zh':
traditional_chinese_fuzzy = [u"", u"雙語"]
traditional_chinese = [".cht", ".tc", ".zh-tw", ".zht",".zh-hant",".zhhant",".zh_hant",".hant", ".big5", ".traditional"]
traditional_chinese = [".cht", ".tc", ".zh-tw", ".zht", ".zh-hant", ".zhhant", ".zh_hant", ".hant", ".big5", ".traditional"]
if str(os.path.splitext(subtitle)[0]).lower().endswith(tuple(traditional_chinese)) or (str(subtitle_path).lower())[:-5] in traditional_chinese_fuzzy:
detected_language == 'zt'
except UnicodeDecodeError:

View File

@ -291,7 +291,7 @@ def delete_subtitles(media_type, language, forced, hi, media_path, subtitles_pat
elif forced in [True, 'true', 'True']:
language_log += ':forced'
language_string += ' forced'
result = language_string + " subtitles deleted from disk."
if media_type == 'series':
@ -299,26 +299,30 @@ def delete_subtitles(media_type, language, forced, hi, media_path, subtitles_pat
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)
store_subtitles(path_mappings.path_replace_reverse(media_path), media_path,
'episode', sonarr_episode_id)
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)
store_subtitles(path_mappings.path_replace_reverse(media_path), media_path,
'episode', sonarr_episode_id)
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)
store_subtitles_movie(path_mappings.path_replace_reverse_movie(media_path), media_path,
'movie', radarr_id)
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)
store_subtitles_movie(path_mappings.path_replace_reverse_movie(media_path), media_path,
'movie', radarr_id)
notify_radarr(radarr_id)
return True
@ -399,7 +403,66 @@ def translate_subtitles_file(video_path, source_srt_file, to_lang, forced, hi):
return dest_srt_file
def check_credentials(user, pw):
username = settings.auth.username
password = settings.auth.password
return hashlib.md5(pw.encode('utf-8')).hexdigest() == password and user == username
return hashlib.md5(pw.encode('utf-8')).hexdigest() == password and user == username
def cache_get_ffprobe(path, record_type=None, record_id=None):
record = {
'id': record_id,
'type': record_type,
'ffprobe': None
}
if record_type == 'episode':
item = database.execute("SELECT sonarrEpisodeId, file_ffprobe FROM table_episodes WHERE sonarrEpisodeId = ? AND path = ?",
(record_id, path,), only_one=True)
if item:
record.update({'id': item['sonarrEpisodeId'], 'type': 'episode'})
if item['file_ffprobe'] is not None:
record.update({'ffprobe': json.loads(item['file_ffprobe'])})
logging.debug('Returning cached results for: [%s:%s, %s]. (%s)', record['type'], record['id'], path, record['ffprobe'])
return record
if record_type == 'movie':
item = database.execute("SELECT radarrId, file_ffprobe FROM table_movies WHERE radarrId = ? AND path = ?",
(record_id, path,), only_one=True)
if item:
record.update({'id': item['radarrId'], 'type': 'movie'})
if item['file_ffprobe'] is not None:
record.update({'ffprobe': json.loads(item['file_ffprobe'])})
logging.debug('Returning cached results for: [%s:%s, %s]. (%s)', record['type'], record['id'], path, record['ffprobe'])
return record
def cache_save_ffprobe(path, record_type, record_id, ffprobe):
if record_type == 'movie':
database.execute("UPDATE table_movies SET file_ffprobe = ? WHERE path = ? AND radarrId = ?",
(json.dumps(ffprobe), path, record_id))
if record_type == 'episode':
database.execute("UPDATE table_episodes SET file_ffprobe = ? WHERE path = ? AND sonarrEpisodeId = ?",
(json.dumps(ffprobe), path, record_id))
logging.debug('Saving ffprobe records [%s:%s, %s]. (%s)', record_type, record_id, path, ffprobe)
def cache_is_valid(path, file_size, record_type, record_id):
if record_type == 'movie':
item = database.execute("SELECT path, file_size FROM table_movies WHERE radarrId = ?",
(record_id,), only_one=True)
else:
item = database.execute("SELECT path, file_size FROM table_episodes WHERE sonarrEpisodeId = ?",
(record_id,), only_one=True)
if item:
return str(item['path']) == str(path) and int(item['file_size']) == int(file_size)
return False