summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authormorpheus65535 <[email protected]>2023-08-29 17:17:30 -0400
committermorpheus65535 <[email protected]>2023-08-29 17:17:30 -0400
commit995ae1b5b8f475f9ce5f15b030ad74ca428b2e91 (patch)
treecf8338d1f3779fd5dd64859631c6c2ce3b9c1288
parent162dbc0eee6e38511f97aebcc4cfe8ce913d3623 (diff)
downloadbazarr-995ae1b5b8f475f9ce5f15b030ad74ca428b2e91.tar.gz
bazarr-995ae1b5b8f475f9ce5f15b030ad74ca428b2e91.zip
Improved UI feedback on multiple search, download and upload issues. #2235
-rw-r--r--bazarr/api/episodes/blacklist.py25
-rw-r--r--bazarr/api/episodes/episodes_subtitles.py50
-rw-r--r--bazarr/api/movies/blacklist.py23
-rw-r--r--bazarr/api/movies/movies.py9
-rw-r--r--bazarr/api/movies/movies_subtitles.py46
-rw-r--r--bazarr/api/providers/providers_episodes.py7
-rw-r--r--bazarr/api/providers/providers_movies.py7
-rw-r--r--bazarr/api/series/series.py9
-rw-r--r--bazarr/api/subtitles/subtitles.py34
-rw-r--r--bazarr/api/system/settings.py2
-rw-r--r--bazarr/app/database.py2
-rw-r--r--bazarr/subtitles/mass_download/movies.py10
-rw-r--r--bazarr/subtitles/mass_download/series.py9
-rw-r--r--bazarr/subtitles/tools/score.py1
-rw-r--r--bazarr/subtitles/tools/subsyncer.py27
-rw-r--r--bazarr/subtitles/tools/translate.py6
16 files changed, 181 insertions, 86 deletions
diff --git a/bazarr/api/episodes/blacklist.py b/bazarr/api/episodes/blacklist.py
index e62a7850a..7bcab005b 100644
--- a/bazarr/api/episodes/blacklist.py
+++ b/bazarr/api/episodes/blacklist.py
@@ -88,6 +88,7 @@ class EpisodesBlacklist(Resource):
@api_ns_episodes_blacklist.response(200, 'Success')
@api_ns_episodes_blacklist.response(401, 'Not Authenticated')
@api_ns_episodes_blacklist.response(404, 'Episode not found')
+ @api_ns_episodes_blacklist.response(410, 'Subtitles file not found or permission issue.')
def post(self):
"""Add an episodes subtitles to blacklist"""
args = self.post_request_parser.parse_args()
@@ -113,17 +114,19 @@ class EpisodesBlacklist(Resource):
provider=provider,
subs_id=subs_id,
language=language)
- delete_subtitles(media_type='series',
- language=language,
- forced=False,
- hi=False,
- media_path=path_mappings.path_replace(media_path),
- subtitles_path=subtitles_path,
- sonarr_series_id=sonarr_series_id,
- sonarr_episode_id=sonarr_episode_id)
- episode_download_subtitles(sonarr_episode_id)
- event_stream(type='episode-history')
- return '', 200
+ if delete_subtitles(media_type='series',
+ language=language,
+ forced=False,
+ hi=False,
+ media_path=path_mappings.path_replace(media_path),
+ subtitles_path=subtitles_path,
+ sonarr_series_id=sonarr_series_id,
+ sonarr_episode_id=sonarr_episode_id):
+ episode_download_subtitles(sonarr_episode_id)
+ event_stream(type='episode-history')
+ return '', 200
+ else:
+ return 'Subtitles file not found or permission issue.', 410
delete_request_parser = reqparse.RequestParser()
delete_request_parser.add_argument('all', type=str, required=False, help='Empty episodes subtitles blacklist')
diff --git a/bazarr/api/episodes/episodes_subtitles.py b/bazarr/api/episodes/episodes_subtitles.py
index b1e786031..67f1add7b 100644
--- a/bazarr/api/episodes/episodes_subtitles.py
+++ b/bazarr/api/episodes/episodes_subtitles.py
@@ -37,6 +37,8 @@ class EpisodesSubtitles(Resource):
@api_ns_episodes_subtitles.response(204, 'Success')
@api_ns_episodes_subtitles.response(401, 'Not Authenticated')
@api_ns_episodes_subtitles.response(404, 'Episode not found')
+ @api_ns_episodes_subtitles.response(409, 'Unable to save subtitles file. Permission of path mapping issue?')
+ @api_ns_episodes_subtitles.response(410, 'Episode file not found. Path mapping issue?')
def patch(self):
"""Download an episode subtitles"""
args = self.patch_request_parser.parse_args()
@@ -55,10 +57,15 @@ class EpisodesSubtitles(Resource):
if not episodeInfo:
return 'Episode not found', 404
- title = episodeInfo.title
episodePath = path_mappings.path_replace(episodeInfo.path)
+
+ if not os.path.exists(episodePath):
+ return 'Episode file not found. Path mapping issue?', 410
+
sceneName = episodeInfo.sceneName or "None"
+ title = episodeInfo.title
+
language = args.get('language')
hi = args.get('hi').capitalize()
forced = args.get('forced').capitalize()
@@ -79,11 +86,10 @@ class EpisodesSubtitles(Resource):
store_subtitles(result.path, episodePath)
else:
event_stream(type='episode', payload=sonarrEpisodeId)
-
except OSError:
- pass
-
- return '', 204
+ return 'Unable to save subtitles file. Permission of path mapping issue?', 409
+ else:
+ return '', 204
post_request_parser = reqparse.RequestParser()
post_request_parser.add_argument('seriesid', type=int, required=True, help='Series ID')
@@ -99,6 +105,8 @@ class EpisodesSubtitles(Resource):
@api_ns_episodes_subtitles.response(204, 'Success')
@api_ns_episodes_subtitles.response(401, 'Not Authenticated')
@api_ns_episodes_subtitles.response(404, 'Episode not found')
+ @api_ns_episodes_subtitles.response(409, 'Unable to save subtitles file. Permission of path mapping issue?')
+ @api_ns_episodes_subtitles.response(410, 'Episode file not found. Path mapping issue?')
def post(self):
"""Upload an episode subtitles"""
args = self.post_request_parser.parse_args()
@@ -115,6 +123,9 @@ class EpisodesSubtitles(Resource):
episodePath = path_mappings.path_replace(episodeInfo.path)
+ if not os.path.exists(episodePath):
+ return 'Episode file not found. Path mapping issue?', 410
+
audio_language = get_audio_profile_languages(episodeInfo.audio_language)
if len(audio_language) and isinstance(audio_language[0], dict):
audio_language = audio_language[0]
@@ -149,11 +160,10 @@ class EpisodesSubtitles(Resource):
if not settings.general.getboolean('dont_notify_manual_actions'):
send_notifications(sonarrSeriesId, sonarrEpisodeId, result.message)
store_subtitles(result.path, episodePath)
-
except OSError:
- pass
-
- return '', 204
+ return 'Unable to save subtitles file. Permission of path mapping issue?', 409
+ else:
+ return '', 204
delete_request_parser = reqparse.RequestParser()
delete_request_parser.add_argument('seriesid', type=int, required=True, help='Series ID')
@@ -168,6 +178,7 @@ class EpisodesSubtitles(Resource):
@api_ns_episodes_subtitles.response(204, 'Success')
@api_ns_episodes_subtitles.response(401, 'Not Authenticated')
@api_ns_episodes_subtitles.response(404, 'Episode not found')
+ @api_ns_episodes_subtitles.response(410, 'Subtitles file not found or permission issue.')
def delete(self):
"""Delete an episode subtitles"""
args = self.delete_request_parser.parse_args()
@@ -190,13 +201,14 @@ class EpisodesSubtitles(Resource):
subtitlesPath = path_mappings.path_replace_reverse(subtitlesPath)
- delete_subtitles(media_type='series',
- language=language,
- forced=forced,
- hi=hi,
- media_path=episodePath,
- subtitles_path=subtitlesPath,
- sonarr_series_id=sonarrSeriesId,
- sonarr_episode_id=sonarrEpisodeId)
-
- return '', 204
+ if delete_subtitles(media_type='series',
+ language=language,
+ forced=forced,
+ hi=hi,
+ media_path=episodePath,
+ subtitles_path=subtitlesPath,
+ sonarr_series_id=sonarrSeriesId,
+ sonarr_episode_id=sonarrEpisodeId):
+ return '', 204
+ else:
+ return 'Subtitles file not found or permission issue.', 410
diff --git a/bazarr/api/movies/blacklist.py b/bazarr/api/movies/blacklist.py
index 118d4e9cb..22bb09ce9 100644
--- a/bazarr/api/movies/blacklist.py
+++ b/bazarr/api/movies/blacklist.py
@@ -81,6 +81,7 @@ class MoviesBlacklist(Resource):
@api_ns_movies_blacklist.response(200, 'Success')
@api_ns_movies_blacklist.response(401, 'Not Authenticated')
@api_ns_movies_blacklist.response(404, 'Movie not found')
+ @api_ns_movies_blacklist.response(410, 'Subtitles file not found or permission issue.')
def post(self):
"""Add a movies subtitles to blacklist"""
args = self.post_request_parser.parse_args()
@@ -107,16 +108,18 @@ class MoviesBlacklist(Resource):
provider=provider,
subs_id=subs_id,
language=language)
- delete_subtitles(media_type='movie',
- language=language,
- forced=forced,
- hi=hi,
- media_path=path_mappings.path_replace_movie(media_path),
- subtitles_path=subtitles_path,
- radarr_id=radarr_id)
- movies_download_subtitles(radarr_id)
- event_stream(type='movie-history')
- return '', 200
+ if delete_subtitles(media_type='movie',
+ language=language,
+ forced=forced,
+ hi=hi,
+ media_path=path_mappings.path_replace_movie(media_path),
+ subtitles_path=subtitles_path,
+ radarr_id=radarr_id):
+ movies_download_subtitles(radarr_id)
+ event_stream(type='movie-history')
+ return '', 200
+ else:
+ return 'Subtitles file not found or permission issue.', 410
delete_request_parser = reqparse.RequestParser()
delete_request_parser.add_argument('all', type=str, required=False, help='Empty movies subtitles blacklist')
diff --git a/bazarr/api/movies/movies.py b/bazarr/api/movies/movies.py
index f2303f4cf..ec181b2f8 100644
--- a/bazarr/api/movies/movies.py
+++ b/bazarr/api/movies/movies.py
@@ -166,6 +166,7 @@ class Movies(Resource):
@api_ns_movies.response(204, 'Success')
@api_ns_movies.response(400, 'Unknown action')
@api_ns_movies.response(401, 'Not Authenticated')
+ @api_ns_movies.response(410, 'Movie file not found. Path mapping issue?')
def patch(self):
"""Run actions on specific movies"""
args = self.patch_request_parser.parse_args()
@@ -175,8 +176,12 @@ class Movies(Resource):
movies_scan_subtitles(radarrid)
return '', 204
elif action == "search-missing":
- movies_download_subtitles(radarrid)
- return '', 204
+ try:
+ movies_download_subtitles(radarrid)
+ except OSError:
+ return 'Movie file not found. Path mapping issue?', 410
+ else:
+ return '', 204
elif action == "search-wanted":
wanted_search_missing_subtitles_movies()
return '', 204
diff --git a/bazarr/api/movies/movies_subtitles.py b/bazarr/api/movies/movies_subtitles.py
index fd4dd953f..10584caf7 100644
--- a/bazarr/api/movies/movies_subtitles.py
+++ b/bazarr/api/movies/movies_subtitles.py
@@ -1,6 +1,5 @@
# coding=utf-8
-import contextlib
import os
import logging
@@ -37,6 +36,8 @@ class MoviesSubtitles(Resource):
@api_ns_movies_subtitles.response(204, 'Success')
@api_ns_movies_subtitles.response(401, 'Not Authenticated')
@api_ns_movies_subtitles.response(404, 'Movie not found')
+ @api_ns_movies_subtitles.response(409, 'Unable to save subtitles file. Permission of path mapping issue?')
+ @api_ns_movies_subtitles.response(410, 'Movie file not found. Path mapping issue?')
def patch(self):
"""Download a movie subtitles"""
args = self.patch_request_parser.parse_args()
@@ -55,6 +56,10 @@ class MoviesSubtitles(Resource):
return 'Movie not found', 404
moviePath = path_mappings.path_replace_movie(movieInfo.path)
+
+ if not os.path.exists(moviePath):
+ return 'Movie file not found. Path mapping issue?', 410
+
sceneName = movieInfo.sceneName or 'None'
title = movieInfo.title
@@ -69,7 +74,7 @@ class MoviesSubtitles(Resource):
else:
audio_language = None
- with contextlib.suppress(OSError):
+ try:
result = list(generate_subtitles(moviePath, [(language, hi, forced)], audio_language,
sceneName, title, 'movie', profile_id=get_profile_id(movie_id=radarrId)))
if result:
@@ -78,7 +83,10 @@ class MoviesSubtitles(Resource):
store_subtitles_movie(result.path, moviePath)
else:
event_stream(type='movie', payload=radarrId)
- return '', 204
+ except OSError:
+ return 'Unable to save subtitles file. Permission of path mapping issue?', 409
+ else:
+ return '', 204
# POST: Upload Subtitles
post_request_parser = reqparse.RequestParser()
@@ -94,6 +102,8 @@ class MoviesSubtitles(Resource):
@api_ns_movies_subtitles.response(204, 'Success')
@api_ns_movies_subtitles.response(401, 'Not Authenticated')
@api_ns_movies_subtitles.response(404, 'Movie not found')
+ @api_ns_movies_subtitles.response(409, 'Unable to save subtitles file. Permission of path mapping issue?')
+ @api_ns_movies_subtitles.response(410, 'Movie file not found. Path mapping issue?')
def post(self):
"""Upload a movie subtitles"""
# TODO: Support Multiply Upload
@@ -109,6 +119,9 @@ class MoviesSubtitles(Resource):
moviePath = path_mappings.path_replace_movie(movieInfo.path)
+ if not os.path.exists(moviePath):
+ return 'Movie file not found. Path mapping issue?', 410
+
audio_language = get_audio_profile_languages(movieInfo.audio_language)
if len(audio_language) and isinstance(audio_language[0], dict):
audio_language = audio_language[0]
@@ -125,7 +138,7 @@ class MoviesSubtitles(Resource):
if not isinstance(ext, str) or ext.lower() not in SUBTITLE_EXTENSIONS:
raise ValueError('A subtitle of an invalid format was uploaded.')
- with contextlib.suppress(OSError):
+ try:
result = manual_upload_subtitle(path=moviePath,
language=language,
forced=forced,
@@ -143,7 +156,10 @@ class MoviesSubtitles(Resource):
if not settings.general.getboolean('dont_notify_manual_actions'):
send_notifications_movie(radarrId, result.message)
store_subtitles_movie(result.path, moviePath)
- return '', 204
+ except OSError:
+ return 'Unable to save subtitles file. Permission of path mapping issue?', 409
+ else:
+ return '', 204
# DELETE: Delete Subtitles
delete_request_parser = reqparse.RequestParser()
@@ -158,6 +174,7 @@ class MoviesSubtitles(Resource):
@api_ns_movies_subtitles.response(204, 'Success')
@api_ns_movies_subtitles.response(401, 'Not Authenticated')
@api_ns_movies_subtitles.response(404, 'Movie not found')
+ @api_ns_movies_subtitles.response(410, 'Subtitles file not found or permission issue.')
def delete(self):
"""Delete a movie subtitles"""
args = self.delete_request_parser.parse_args()
@@ -179,12 +196,13 @@ class MoviesSubtitles(Resource):
subtitlesPath = path_mappings.path_replace_reverse_movie(subtitlesPath)
- delete_subtitles(media_type='movie',
- language=language,
- forced=forced,
- hi=hi,
- media_path=moviePath,
- subtitles_path=subtitlesPath,
- radarr_id=radarrId)
-
- return '', 204
+ if delete_subtitles(media_type='movie',
+ language=language,
+ forced=forced,
+ hi=hi,
+ media_path=moviePath,
+ subtitles_path=subtitlesPath,
+ radarr_id=radarrId):
+ return '', 204
+ else:
+ return 'Subtitles file not found or permission issue.', 410
diff --git a/bazarr/api/providers/providers_episodes.py b/bazarr/api/providers/providers_episodes.py
index f8fa516b8..8b9c72228 100644
--- a/bazarr/api/providers/providers_episodes.py
+++ b/bazarr/api/providers/providers_episodes.py
@@ -1,5 +1,7 @@
# coding=utf-8
+import os
+
from flask_restx import Resource, Namespace, reqparse, fields
from app.database import TableEpisodes, TableShows, get_audio_profile_languages, get_profile_id, database, select
@@ -42,6 +44,7 @@ class ProviderEpisodes(Resource):
@api_ns_providers_episodes.marshal_with(get_response_model, envelope='data', code=200)
@api_ns_providers_episodes.response(401, 'Not Authenticated')
@api_ns_providers_episodes.response(404, 'Episode not found')
+ @api_ns_providers_episodes.response(410, 'Episode file not found. Path mapping issue?')
@api_ns_providers_episodes.doc(parser=get_request_parser)
def get(self):
"""Search manually for an episode subtitles"""
@@ -62,6 +65,10 @@ class ProviderEpisodes(Resource):
title = episodeInfo.title
episodePath = path_mappings.path_replace(episodeInfo.path)
+
+ if not os.path.exists(episodePath):
+ return 'Episode file not found. Path mapping issue?', 410
+
sceneName = episodeInfo.sceneName or "None"
profileId = episodeInfo.profileId
diff --git a/bazarr/api/providers/providers_movies.py b/bazarr/api/providers/providers_movies.py
index fcc8241e8..07df28785 100644
--- a/bazarr/api/providers/providers_movies.py
+++ b/bazarr/api/providers/providers_movies.py
@@ -1,5 +1,7 @@
# coding=utf-8
+import os
+
from flask_restx import Resource, Namespace, reqparse, fields
from app.database import TableMovies, get_audio_profile_languages, get_profile_id, database, select
@@ -43,6 +45,7 @@ class ProviderMovies(Resource):
@api_ns_providers_movies.marshal_with(get_response_model, envelope='data', code=200)
@api_ns_providers_movies.response(401, 'Not Authenticated')
@api_ns_providers_movies.response(404, 'Movie not found')
+ @api_ns_providers_movies.response(410, 'Movie file not found. Path mapping issue?')
@api_ns_providers_movies.doc(parser=get_request_parser)
def get(self):
"""Search manually for a movie subtitles"""
@@ -61,6 +64,10 @@ class ProviderMovies(Resource):
title = movieInfo.title
moviePath = path_mappings.path_replace_movie(movieInfo.path)
+
+ if not os.path.exists(moviePath):
+ return 'Movie file not found. Path mapping issue?', 410
+
sceneName = movieInfo.sceneName or "None"
profileId = movieInfo.profileId
diff --git a/bazarr/api/series/series.py b/bazarr/api/series/series.py
index 6a90f6190..0d6d1e8de 100644
--- a/bazarr/api/series/series.py
+++ b/bazarr/api/series/series.py
@@ -199,6 +199,7 @@ class Series(Resource):
@api_ns_series.response(204, 'Success')
@api_ns_series.response(400, 'Unknown action')
@api_ns_series.response(401, 'Not Authenticated')
+ @api_ns_series.response(410, 'Series directory not found. Path mapping issue?')
def patch(self):
"""Run actions on specific series"""
args = self.patch_request_parser.parse_args()
@@ -208,8 +209,12 @@ class Series(Resource):
series_scan_subtitles(seriesid)
return '', 204
elif action == "search-missing":
- series_download_subtitles(seriesid)
- return '', 204
+ try:
+ series_download_subtitles(seriesid)
+ except OSError:
+ return 'Series directory not found. Path mapping issue?', 410
+ else:
+ return '', 204
elif action == "search-wanted":
wanted_search_missing_subtitles_series()
return '', 204
diff --git a/bazarr/api/subtitles/subtitles.py b/bazarr/api/subtitles/subtitles.py
index f71081220..bf655099a 100644
--- a/bazarr/api/subtitles/subtitles.py
+++ b/bazarr/api/subtitles/subtitles.py
@@ -42,6 +42,8 @@ class Subtitles(Resource):
@api_ns_subtitles.response(204, 'Success')
@api_ns_subtitles.response(401, 'Not Authenticated')
@api_ns_subtitles.response(404, 'Episode/movie not found')
+ @api_ns_subtitles.response(409, 'Unable to edit subtitles file. Check logs.')
+ @api_ns_subtitles.response(410, 'Subtitles file not found. Path mapping issue?')
def patch(self):
"""Apply mods/tools on external subtitles"""
args = self.patch_request_parser.parse_args()
@@ -52,6 +54,9 @@ class Subtitles(Resource):
media_type = args.get('type')
id = args.get('id')
+ if not os.path.exists(subtitles_path):
+ return 'Subtitles file not found. Path mapping issue?', 410
+
if media_type == 'episode':
metadata = database.execute(
select(TableEpisodes.path, TableEpisodes.sonarrSeriesId)
@@ -80,8 +85,11 @@ class Subtitles(Resource):
srt_lang=language, media_type='series', sonarr_series_id=metadata.sonarrSeriesId,
sonarr_episode_id=id)
else:
- subsync.sync(video_path=video_path, srt_path=subtitles_path,
- srt_lang=language, media_type='movies', radarr_id=id)
+ try:
+ subsync.sync(video_path=video_path, srt_path=subtitles_path,
+ srt_lang=language, media_type='movies', radarr_id=id)
+ except OSError:
+ return 'Unable to edit subtitles file. Check logs.', 409
del subsync
gc.collect()
elif action == 'translate':
@@ -89,16 +97,22 @@ class Subtitles(Resource):
dest_language = language
forced = True if args.get('forced') == 'true' else False
hi = True if args.get('hi') == 'true' else False
- translate_subtitles_file(video_path=video_path, source_srt_file=subtitles_path,
- from_lang=from_language, to_lang=dest_language, forced=forced, hi=hi,
- media_type="series" if media_type == "episode" else "movies",
- sonarr_series_id=metadata.sonarrSeriesId if media_type == "episode" else None,
- sonarr_episode_id=id,
- radarr_id=id)
+ try:
+ translate_subtitles_file(video_path=video_path, source_srt_file=subtitles_path,
+ from_lang=from_language, to_lang=dest_language, forced=forced, hi=hi,
+ media_type="series" if media_type == "episode" else "movies",
+ sonarr_series_id=metadata.sonarrSeriesId if media_type == "episode" else None,
+ sonarr_episode_id=id,
+ radarr_id=id)
+ except OSError:
+ return 'Unable to edit subtitles file. Check logs.', 409
else:
use_original_format = True if args.get('original_format') == 'true' else False
- subtitles_apply_mods(language=language, subtitle_path=subtitles_path, mods=[action],
- use_original_format=use_original_format, video_path=video_path)
+ try:
+ subtitles_apply_mods(language=language, subtitle_path=subtitles_path, mods=[action],
+ use_original_format=use_original_format, video_path=video_path)
+ except OSError:
+ return 'Unable to edit subtitles file. Check logs.', 409
# apply chmod if required
chmod = int(settings.general.chmod, 8) if not sys.platform.startswith(
diff --git a/bazarr/api/system/settings.py b/bazarr/api/system/settings.py
index 2e9eb7a24..bad7e9dc8 100644
--- a/bazarr/api/system/settings.py
+++ b/bazarr/api/system/settings.py
@@ -108,7 +108,7 @@ class SystemSettings(Resource):
item = json.loads(item)
database.execute(
update(TableSettingsNotifier).values(
- enabled=int(item['enabled'] == True),
+ enabled=int(item['enabled'] is True),
url=item['url'])
.where(TableSettingsNotifier.name == item['name']))
diff --git a/bazarr/app/database.py b/bazarr/app/database.py
index 645276ea5..b33bc0a40 100644
--- a/bazarr/app/database.py
+++ b/bazarr/app/database.py
@@ -12,7 +12,7 @@ from datetime import datetime
from sqlalchemy import create_engine, inspect, DateTime, ForeignKey, Integer, LargeBinary, Text, func, text
# importing here to be indirectly imported in other modules later
from sqlalchemy import update, delete, select, func # noqa W0611
-from sqlalchemy.orm import scoped_session, sessionmaker, relationship, mapped_column
+from sqlalchemy.orm import scoped_session, sessionmaker, mapped_column
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.pool import NullPool
diff --git a/bazarr/subtitles/mass_download/movies.py b/bazarr/subtitles/mass_download/movies.py
index 297f03078..ed8fec2c1 100644
--- a/bazarr/subtitles/mass_download/movies.py
+++ b/bazarr/subtitles/mass_download/movies.py
@@ -4,6 +4,7 @@
import ast
import logging
import operator
+import os
from functools import reduce
@@ -36,6 +37,11 @@ def movies_download_subtitles(no):
logging.debug("BAZARR no movie with that radarrId can be found in database:", str(no))
return
+ moviePath = path_mappings.path_replace_movie(movie.path)
+
+ if not os.path.exists(moviePath):
+ raise OSError
+
if ast.literal_eval(movie.missing_subtitles):
count_movie = len(ast.literal_eval(movie.missing_subtitles))
else:
@@ -67,7 +73,7 @@ def movies_download_subtitles(no):
value=0,
count=count_movie)
- for result in generate_subtitles(path_mappings.path_replace_movie(movie.path),
+ for result in generate_subtitles(moviePath,
languages,
audio_language,
str(movie.sceneName),
@@ -76,7 +82,7 @@ def movies_download_subtitles(no):
check_if_still_required=True):
if result:
- store_subtitles_movie(movie.path, path_mappings.path_replace_movie(movie.path))
+ store_subtitles_movie(movie.path, moviePath)
history_log_movie(1, no, result)
send_notifications_movie(no, result.message)
diff --git a/bazarr/subtitles/mass_download/series.py b/bazarr/subtitles/mass_download/series.py
index 3b4d8e58d..4a9dda021 100644
--- a/bazarr/subtitles/mass_download/series.py
+++ b/bazarr/subtitles/mass_download/series.py
@@ -4,6 +4,7 @@
import ast
import logging
import operator
+import os
from functools import reduce
@@ -19,6 +20,14 @@ from ..download import generate_subtitles
def series_download_subtitles(no):
+ series_row = database.execute(
+ select(TableShows.path)
+ .where(TableShows.sonarrSeriesId == no))\
+ .first()
+
+ if series_row and not os.path.exists(path_mappings.path_replace(series_row.path)):
+ raise OSError
+
conditions = [(TableEpisodes.sonarrSeriesId == no),
(TableEpisodes.missing_subtitles != '[]')]
conditions += get_exclusion_clause('series')
diff --git a/bazarr/subtitles/tools/score.py b/bazarr/subtitles/tools/score.py
index c35347bb8..11771354e 100644
--- a/bazarr/subtitles/tools/score.py
+++ b/bazarr/subtitles/tools/score.py
@@ -8,6 +8,7 @@ from app.config import get_settings
logger = logging.getLogger(__name__)
+
class Score:
media = None
defaults = {}
diff --git a/bazarr/subtitles/tools/subsyncer.py b/bazarr/subtitles/tools/subsyncer.py
index 5667622ac..8e815fa25 100644
--- a/bazarr/subtitles/tools/subsyncer.py
+++ b/bazarr/subtitles/tools/subsyncer.py
@@ -52,24 +52,25 @@ class SubSyncer:
logging.debug('BAZARR FFmpeg used is %s', ffmpeg_exe)
self.ffmpeg_path = os.path.dirname(ffmpeg_exe)
+ 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('force_audio'):
+ unparsed_args.append('--no-fix-framerate')
+ unparsed_args.append('--reference-stream')
+ unparsed_args.append('a:0')
+ if settings.subsync.getboolean('debug'):
+ unparsed_args.append('--make-test-case')
+ parser = make_parser()
+ self.args = parser.parse_args(args=unparsed_args)
+ if os.path.isfile(self.srtout):
+ os.remove(self.srtout)
+ logging.debug('BAZARR deleted the previous subtitles synchronization attempt file.')
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('force_audio'):
- unparsed_args.append('--no-fix-framerate')
- unparsed_args.append('--reference-stream')
- unparsed_args.append('a:0')
- if settings.subsync.getboolean('debug'):
- unparsed_args.append('--make-test-case')
- parser = make_parser()
- self.args = parser.parse_args(args=unparsed_args)
- if os.path.isfile(self.srtout):
- os.remove(self.srtout)
- logging.debug('BAZARR deleted the previous subtitles synchronization attempt file.')
result = run(self.args)
except Exception:
logging.exception('BAZARR an exception occurs during the synchronization process for this subtitles: '
'{0}'.format(self.srtin))
+ raise OSError
else:
if settings.subsync.getboolean('debug'):
return result
diff --git a/bazarr/subtitles/tools/translate.py b/bazarr/subtitles/tools/translate.py
index 8d870ff3f..1761ac50a 100644
--- a/bazarr/subtitles/tools/translate.py
+++ b/bazarr/subtitles/tools/translate.py
@@ -81,7 +81,11 @@ def translate_subtitles_file(video_path, source_srt_file, from_lang, to_lang, fo
except IndexError:
logging.error(f'BAZARR is unable to translate malformed subtitles: {source_srt_file}')
return False
- subs.save(dest_srt_file)
+ try:
+ subs.save(dest_srt_file)
+ except OSError:
+ logging.error(f'BAZARR is unable to save translated subtitles to {dest_srt_file}')
+ raise OSError
message = f"{language_from_alpha2(from_lang)} subtitles translated to {language_from_alpha3(to_lang)}."