Added languages profile settings to prevent downloaded subtitles from being converted to srt.

This commit is contained in:
maxwillx 2022-03-14 17:54:36 -07:00 committed by GitHub
parent 684797d6e4
commit 33a9e512ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 71 additions and 20 deletions

3
.gitignore vendored
View File

@ -10,6 +10,9 @@ bazarr.pid
.idea .idea
.vscode .vscode
# LSP
pyrightconfig.json
# Middleware # Middleware
VERSION VERSION

View File

@ -66,6 +66,7 @@ class ProviderEpisodes(Resource):
hi = request.form.get('hi').capitalize() hi = request.form.get('hi').capitalize()
forced = request.form.get('forced').capitalize() forced = request.form.get('forced').capitalize()
use_original_format = request.form.get('original_format').capitalize()
selected_provider = request.form.get('provider') selected_provider = request.form.get('provider')
subtitle = request.form.get('subtitle') subtitle = request.form.get('subtitle')
@ -77,8 +78,7 @@ class ProviderEpisodes(Resource):
try: try:
result = manual_download_subtitle(episodePath, audio_language, hi, forced, subtitle, selected_provider, result = manual_download_subtitle(episodePath, audio_language, hi, forced, subtitle, selected_provider,
sceneName, title, 'series', sceneName, title, 'series', use_original_format, profile_id=get_profile_id(episode_id=sonarrEpisodeId))
profile_id=get_profile_id(episode_id=sonarrEpisodeId))
if result is not None: if result is not None:
message = result[0] message = result[0]
path = result[1] path = result[1]

View File

@ -13,6 +13,7 @@ from notifier import send_notifications_movie
from list_subtitles import store_subtitles_movie from list_subtitles import store_subtitles_movie
from ..utils import authenticate from ..utils import authenticate
import logging
class ProviderMovies(Resource): class ProviderMovies(Resource):
@ -64,6 +65,8 @@ class ProviderMovies(Resource):
hi = request.form.get('hi').capitalize() hi = request.form.get('hi').capitalize()
forced = request.form.get('forced').capitalize() forced = request.form.get('forced').capitalize()
use_original_format = request.form.get('original_format').capitalize()
logging.debug(f"use_original_format {use_original_format}")
selected_provider = request.form.get('provider') selected_provider = request.form.get('provider')
subtitle = request.form.get('subtitle') subtitle = request.form.get('subtitle')
@ -75,7 +78,7 @@ class ProviderMovies(Resource):
try: try:
result = manual_download_subtitle(moviePath, audio_language, hi, forced, subtitle, selected_provider, result = manual_download_subtitle(moviePath, audio_language, hi, forced, subtitle, selected_provider,
sceneName, title, 'movie', profile_id=get_profile_id(movie_id=radarrId)) sceneName, title, 'movie', use_original_format, profile_id=get_profile_id(movie_id=radarrId))
if result is not None: if result is not None:
message = result[0] message = result[0]
path = result[1] path = result[1]

View File

@ -73,7 +73,8 @@ class Subtitles(Resource):
else: else:
return '', 404 return '', 404
else: else:
subtitles_apply_mods(language, subtitles_path, [action]) use_original_format = True if request.form.get('original_format') == 'true' else False
subtitles_apply_mods(language, subtitles_path, [action], use_original_format)
# apply chmod if required # apply chmod if required
chmod = int(settings.general.chmod, 8) if not sys.platform.startswith( chmod = int(settings.general.chmod, 8) if not sys.platform.startswith(

View File

@ -59,6 +59,7 @@ class SystemSettings(Resource):
TableLanguagesProfiles.items: json.dumps(item['items']), TableLanguagesProfiles.items: json.dumps(item['items']),
TableLanguagesProfiles.mustContain: item['mustContain'], TableLanguagesProfiles.mustContain: item['mustContain'],
TableLanguagesProfiles.mustNotContain: item['mustNotContain'], TableLanguagesProfiles.mustNotContain: item['mustNotContain'],
TableLanguagesProfiles.originalFormat: item['originalFormat'] if item['originalFormat'] != 'null' else None,
})\ })\
.where(TableLanguagesProfiles.profileId == item['profileId'])\ .where(TableLanguagesProfiles.profileId == item['profileId'])\
.execute() .execute()
@ -72,6 +73,7 @@ class SystemSettings(Resource):
TableLanguagesProfiles.items: json.dumps(item['items']), TableLanguagesProfiles.items: json.dumps(item['items']),
TableLanguagesProfiles.mustContain: item['mustContain'], TableLanguagesProfiles.mustContain: item['mustContain'],
TableLanguagesProfiles.mustNotContain: item['mustNotContain'], TableLanguagesProfiles.mustNotContain: item['mustNotContain'],
TableLanguagesProfiles.originalFormat: item['originalFormat'] if item['originalFormat'] != 'null' else None,
}).execute() }).execute()
for profileId in existing: for profileId in existing:
# Unassign this profileId from series and movies # Unassign this profileId from series and movies

View File

@ -131,6 +131,7 @@ class TableHistoryMovie(BaseModel):
class TableLanguagesProfiles(BaseModel): class TableLanguagesProfiles(BaseModel):
cutoff = IntegerField(null=True) cutoff = IntegerField(null=True)
originalFormat = BooleanField(null=True)
items = TextField() items = TextField()
name = TextField() name = TextField()
profileId = AutoField() profileId = AutoField()
@ -332,6 +333,7 @@ def migrate_db():
migrator.add_column('table_history_movie', 'subtitles_path', TextField(null=True)), migrator.add_column('table_history_movie', 'subtitles_path', TextField(null=True)),
migrator.add_column('table_languages_profiles', 'mustContain', TextField(null=True)), migrator.add_column('table_languages_profiles', 'mustContain', TextField(null=True)),
migrator.add_column('table_languages_profiles', 'mustNotContain', TextField(null=True)), migrator.add_column('table_languages_profiles', 'mustNotContain', TextField(null=True)),
migrator.add_column('table_languages_profiles', 'originalFormat', BooleanField(null=True)),
) )
@ -402,7 +404,8 @@ def update_profile_id_list():
TableLanguagesProfiles.cutoff, TableLanguagesProfiles.cutoff,
TableLanguagesProfiles.items, TableLanguagesProfiles.items,
TableLanguagesProfiles.mustContain, TableLanguagesProfiles.mustContain,
TableLanguagesProfiles.mustNotContain).dicts() TableLanguagesProfiles.mustNotContain,
TableLanguagesProfiles.originalFormat).dicts()
profile_id_list = list(profile_id_list) profile_id_list = list(profile_id_list)
for profile in profile_id_list: for profile in profile_id_list:
profile['items'] = json.loads(profile['items']) profile['items'] = json.loads(profile['items'])
@ -434,7 +437,7 @@ def get_desired_languages(profile_id):
if profile_id and profile_id != 'null': if profile_id and profile_id != 'null':
for profile in profile_id_list: for profile in profile_id_list:
profileId, name, cutoff, items, mustContain, mustNotContain = profile.values() profileId, name, cutoff, items, mustContain, mustNotContain, originalFormat = profile.values()
if profileId == int(profile_id): if profileId == int(profile_id):
languages = [x['language'] for x in items] languages = [x['language'] for x in items]
break break
@ -450,7 +453,7 @@ def get_profile_id_name(profile_id):
if profile_id and profile_id != 'null': if profile_id and profile_id != 'null':
for profile in profile_id_list: for profile in profile_id_list:
profileId, name, cutoff, items, mustContain, mustNotContain = profile.values() profileId, name, cutoff, items, mustContain, mustNotContain, originalFormat = profile.values()
if profileId == int(profile_id): if profileId == int(profile_id):
name_from_id = name name_from_id = name
break break
@ -467,7 +470,7 @@ def get_profile_cutoff(profile_id):
if profile_id and profile_id != 'null': if profile_id and profile_id != 'null':
cutoff_language = [] cutoff_language = []
for profile in profile_id_list: for profile in profile_id_list:
profileId, name, cutoff, items, mustContain, mustNotContain = profile.values() profileId, name, cutoff, items, mustContain, mustNotContain, originalFormat = profile.values()
if cutoff: if cutoff:
if profileId == int(profile_id): if profileId == int(profile_id):
for item in items: for item in items:

View File

@ -72,8 +72,10 @@ def generate_subtitles(path, languages, audio_language, sceneName, title, media_
if not subtitles: if not subtitles:
continue continue
subtitle_formats = set()
for s in subtitles: for s in subtitles:
s.mods = subz_mods s.mods = subz_mods
subtitle_formats.add(s.format)
try: try:
fld = get_target_folder(path) fld = get_target_folder(path)
@ -84,7 +86,7 @@ def generate_subtitles(path, languages, audio_language, sceneName, title, media_
tags=None, # fixme tags=None, # fixme
directory=fld, directory=fld,
chmod=chmod, chmod=chmod,
# formats=("srt", "vtt") formats=tuple(subtitle_formats),
path_decoder=force_unicode path_decoder=force_unicode
) )
except Exception as e: except Exception as e:

View File

@ -31,7 +31,7 @@ def manual_search(path, profile_id, providers, sceneName, title, media_type):
pool = _get_pool(media_type, profile_id) pool = _get_pool(media_type, profile_id)
language_set, initial_language_set = _get_language_obj(profile_id=profile_id) language_set, initial_language_set, original_format = _get_language_obj(profile_id=profile_id)
also_forced = any([x.forced for x in initial_language_set]) also_forced = any([x.forced for x in initial_language_set])
_set_forced_providers(also_forced=also_forced, pool=pool) _set_forced_providers(also_forced=also_forced, pool=pool)
@ -136,6 +136,7 @@ def manual_search(path, profile_id, providers, sceneName, title, media_type):
provider=s.provider_name, provider=s.provider_name,
subtitle=codecs.encode(pickle.dumps(s.make_picklable()), "base64").decode(), subtitle=codecs.encode(pickle.dumps(s.make_picklable()), "base64").decode(),
url=s.page_link, url=s.page_link,
original_format=original_format,
matches=list(matches), matches=list(matches),
dont_matches=list(not_matched), dont_matches=list(not_matched),
release_info=releases, release_info=releases,
@ -153,7 +154,7 @@ def manual_search(path, profile_id, providers, sceneName, title, media_type):
@update_pools @update_pools
def manual_download_subtitle(path, audio_language, hi, forced, subtitle, provider, sceneName, title, media_type, def manual_download_subtitle(path, audio_language, hi, forced, subtitle, provider, sceneName, title, media_type,
profile_id): use_original_format, profile_id):
logging.debug('BAZARR Manually downloading Subtitles for this file: ' + path) logging.debug('BAZARR Manually downloading Subtitles for this file: ' + path)
if settings.general.getboolean('utf8_encode'): if settings.general.getboolean('utf8_encode'):
@ -170,6 +171,8 @@ def manual_download_subtitle(path, audio_language, hi, forced, subtitle, provide
subtitle.language.forced = True subtitle.language.forced = True
else: else:
subtitle.language.forced = False subtitle.language.forced = False
if use_original_format == 'True':
subtitle.use_original_format = use_original_format
subtitle.mods = get_array_from(settings.general.subzero_mods) subtitle.mods = get_array_from(settings.general.subzero_mods)
video = get_video(force_unicode(path), title, sceneName, providers={provider}, media_type=media_type) video = get_video(force_unicode(path), title, sceneName, providers={provider}, media_type=media_type)
if video: if video:
@ -195,7 +198,7 @@ def manual_download_subtitle(path, audio_language, hi, forced, subtitle, provide
tags=None, # fixme tags=None, # fixme
directory=get_target_folder(path), directory=get_target_folder(path),
chmod=chmod, chmod=chmod,
# formats=("srt", "vtt") formats=(subtitle.format,),
path_decoder=force_unicode) path_decoder=force_unicode)
except Exception: except Exception:
logging.exception('BAZARR Error saving Subtitles file to disk for this file:' + path) logging.exception('BAZARR Error saving Subtitles file to disk for this file:' + path)
@ -228,8 +231,9 @@ def _get_language_obj(profile_id):
initial_language_set = set() initial_language_set = set()
language_set = set() language_set = set()
# where [3] is items list of dict(id, lang, forced, hi) profile = get_profiles_list(profile_id=int(profile_id))
language_items = get_profiles_list(profile_id=int(profile_id))['items'] language_items = profile['items']
original_format = profile['originalFormat']
for language in language_items: for language in language_items:
forced = language['forced'] forced = language['forced']
@ -259,7 +263,7 @@ def _get_language_obj(profile_id):
continue continue
language_set.add(lang_obj_hi) language_set.add(lang_obj_hi)
return language_set, initial_language_set return language_set, initial_language_set, original_format
def _set_forced_providers(also_forced, pool): def _set_forced_providers(also_forced, pool):

View File

@ -63,7 +63,7 @@ def manual_upload_subtitle(path, language, forced, hi, title, scene_name, media_
tags=None, # fixme tags=None, # fixme
directory=get_target_folder(path), directory=get_target_folder(path),
chmod=chmod, chmod=chmod,
# formats=("srt", "vtt") formats=(sub.format,),
path_decoder=force_unicode) path_decoder=force_unicode)
except Exception: except Exception:
logging.exception('BAZARR Error saving Subtitles file to disk for this file:' + path) logging.exception('BAZARR Error saving Subtitles file to disk for this file:' + path)

View File

@ -415,7 +415,7 @@ def delete_subtitles(media_type, language, forced, hi, media_path, subtitles_pat
return True return True
def subtitles_apply_mods(language, subtitle_path, mods): def subtitles_apply_mods(language, subtitle_path, mods, use_original_format):
language = alpha3_from_alpha2(language) language = alpha3_from_alpha2(language)
custom = CustomLanguage.from_value(language, "alpha3") custom = CustomLanguage.from_value(language, "alpha3")
if custom is None: if custom is None:
@ -423,13 +423,16 @@ def subtitles_apply_mods(language, subtitle_path, mods):
else: else:
lang_obj = custom.subzero_language() lang_obj = custom.subzero_language()
sub = Subtitle(lang_obj, mods=mods) sub = Subtitle(lang_obj, mods=mods, original_format=use_original_format)
with open(subtitle_path, 'rb') as f: with open(subtitle_path, 'rb') as f:
sub.content = f.read() sub.content = f.read()
if not sub.is_valid(): if not sub.is_valid():
logging.exception('BAZARR Invalid subtitle file: ' + subtitle_path) logging.exception('BAZARR Invalid subtitle file: ' + subtitle_path)
return return
if use_original_format:
return
content = sub.get_modified_content() content = sub.get_modified_content()
if content: if content:

View File

@ -35,6 +35,7 @@ declare namespace Language {
items: ProfileItem[]; items: ProfileItem[];
mustContain: string[]; mustContain: string[];
mustNotContain: string[]; mustNotContain: string[];
originalFormat: boolean | null;
} }
} }
@ -252,6 +253,7 @@ interface SearchResultType {
subtitle: any; subtitle: any;
uploader?: string; uploader?: string;
url?: string; url?: string;
original_format: PythonBoolean;
} }
interface ReleaseInfo { interface ReleaseInfo {

View File

@ -72,5 +72,6 @@ declare namespace FormType {
forced: PythonBoolean; forced: PythonBoolean;
provider: string; provider: string;
subtitle: any; subtitle: any;
original_format: PythonBoolean;
} }
} }

View File

@ -52,6 +52,7 @@ const Table: FunctionComponent<Props> = ({
forced, forced,
provider, provider,
subtitle, subtitle,
original_format,
} = result; } = result;
const { sonarrSeriesId: seriesId, sonarrEpisodeId: episodeId } = item; const { sonarrSeriesId: seriesId, sonarrEpisodeId: episodeId } = item;
@ -64,6 +65,7 @@ const Table: FunctionComponent<Props> = ({
forced, forced,
provider, provider,
subtitle, subtitle,
original_format: original_format,
}, },
}); });
}, },

View File

@ -60,6 +60,7 @@ const MovieDetailView: FunctionComponent<Props> = ({ match }) => {
forced, forced,
provider, provider,
subtitle, subtitle,
original_format,
} = result; } = result;
const { radarrId } = item; const { radarrId } = item;
@ -71,6 +72,7 @@ const MovieDetailView: FunctionComponent<Props> = ({ match }) => {
forced, forced,
provider, provider,
subtitle, subtitle,
original_format,
}, },
}); });
}, },

View File

@ -34,6 +34,7 @@ function createDefaultProfile(): Language.Profile {
cutoff: null, cutoff: null,
mustContain: [], mustContain: [],
mustNotContain: [], mustNotContain: [],
originalFormat: false,
}; };
} }
@ -285,6 +286,18 @@ const LanguagesProfileModal: FunctionComponent<Props & BaseModalProps> = (
will be excluded from search results (regex supported). will be excluded from search results (regex supported).
</Message> </Message>
</Input> </Input>
<Input name="Original Format">
<Selector
clearable
options={[
{ label: "Enable", value: true },
{ label: "Disable", value: false },
]}
value={current.originalFormat}
onChange={(value) => updateProfile("originalFormat", value)}
></Selector>
<Message>Download subtitle file without format conversion</Message>
</Input>
</BaseModal> </BaseModal>
); );
}; };

View File

@ -166,6 +166,7 @@ const Table: FunctionComponent = () => {
cutoff: null, cutoff: null,
mustContain: [], mustContain: [],
mustNotContain: [], mustNotContain: [],
originalFormat: false,
}; };
showModal("profile", profile); showModal("profile", profile);
}} }}

View File

@ -61,8 +61,10 @@ class Subtitle(Subtitle_):
pack_data = None pack_data = None
_guessed_encoding = None _guessed_encoding = None
_is_valid = False _is_valid = False
use_original_format = False
format = "srt" # default format is srt
def __init__(self, language, hearing_impaired=False, page_link=None, encoding=None, mods=None): def __init__(self, language, hearing_impaired=False, page_link=None, encoding=None, mods=None, original_format=False):
# set subtitle language to hi if it's hearing_impaired # set subtitle language to hi if it's hearing_impaired
if hearing_impaired: if hearing_impaired:
language = Language.rebuild(language, hi=True) language = Language.rebuild(language, hi=True)
@ -71,6 +73,7 @@ class Subtitle(Subtitle_):
encoding=encoding) encoding=encoding)
self.mods = mods self.mods = mods
self._is_valid = False self._is_valid = False
self.use_original_format = original_format
def __repr__(self): def __repr__(self):
return '<%s %r [%s:%s]>' % ( return '<%s %r [%s:%s]>' % (
@ -257,7 +260,7 @@ class Subtitle(Subtitle_):
return encoding return encoding
def is_valid(self): def is_valid(self):
"""Check if a :attr:`text` is a valid SubRip format. """Check if a :attr:`text` is a valid SubRip format. Note that orignal format will pypass the checking
:return: whether or not the subtitle is valid. :return: whether or not the subtitle is valid.
:rtype: bool :rtype: bool
@ -289,6 +292,12 @@ class Subtitle(Subtitle_):
logger.info("Got FPS from MicroDVD subtitle: %s", subs.fps) logger.info("Got FPS from MicroDVD subtitle: %s", subs.fps)
else: else:
logger.info("Got format: %s", subs.format) logger.info("Got format: %s", subs.format)
if self.use_original_format:
self.format = subs.format
self._is_valid = True
logger.debug("Using original format")
return True
except pysubs2.UnknownFPSError: except pysubs2.UnknownFPSError:
# if parsing failed, use frame rate from provider # if parsing failed, use frame rate from provider
sub_fps = self.get_fps() sub_fps = self.get_fps()