From 7fc50a20a8860aa986bba53802cfe9f384686260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20V=C3=A9zina?= <5130500+morpheus65535@users.noreply.github.com> Date: Sat, 15 Aug 2020 08:30:04 -0400 Subject: [PATCH 01/21] Version bump. --- bazarr/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bazarr/main.py b/bazarr/main.py index 4446c725a..8a2bad4bf 100644 --- a/bazarr/main.py +++ b/bazarr/main.py @@ -1,6 +1,6 @@ # coding=utf-8 -bazarr_version = '0.9.0.2' +bazarr_version = '0.9.0.3' import os os.environ["BAZARR_VERSION"] = bazarr_version From 36cf8ca344a571774dc19badf1f7d2e7449da8ab Mon Sep 17 00:00:00 2001 From: josdion Date: Sun, 16 Aug 2020 11:01:21 +0300 Subject: [PATCH 02/21] subssabbz, subsunacs, yavkanet - add frame rate to release info - add subtitle frame rate to release info - better handling of exceptions while dolwnloading subtitles --- libs/subliminal_patch/providers/subssabbz.py | 30 ++++++++------ libs/subliminal_patch/providers/subsunacs.py | 41 +++++++++++--------- libs/subliminal_patch/providers/yavkanet.py | 30 ++++++++------ 3 files changed, 61 insertions(+), 40 deletions(-) diff --git a/libs/subliminal_patch/providers/subssabbz.py b/libs/subliminal_patch/providers/subssabbz.py index 386e3c19f..960d36429 100644 --- a/libs/subliminal_patch/providers/subssabbz.py +++ b/libs/subliminal_patch/providers/subssabbz.py @@ -55,7 +55,12 @@ class SubsSabBzSubtitle(Subtitle): self.video = video self.fps = fps self.num_cds = num_cds - self.release_info = os.path.splitext(filename)[0] + self.release_info = filename + if fps: + if video.fps and float(video.fps) == fps: + self.release_info += " [{:.3f}]".format(fps) + else: + self.release_info += " [{:.3f}]".format(fps) @property def id(self): @@ -168,7 +173,7 @@ class SubsSabBzProvider(Provider): element = a_element_wrapper.find('a') if element: link = element.get('href') - notes = element.get('onmouseover') + notes = re.sub(r'ddrivetip\(\'(.*)\',\'#[0-9]+\'\)', r'\1', element.get('onmouseover')) title = element.get_text() try: @@ -248,12 +253,15 @@ class SubsSabBzProvider(Provider): else: logger.info('Cache file: %s', codecs.encode(cache_key, 'hex_codec').decode('utf-8')) - archive_stream = io.BytesIO(request.content) - if is_rarfile(archive_stream): - return self.process_archive_subtitle_files(RarFile(archive_stream), language, video, link, fps, num_cds) - elif is_zipfile(archive_stream): - return self.process_archive_subtitle_files(ZipFile(archive_stream), language, video, link, fps, num_cds) - else: - logger.error('Ignore unsupported archive %r', request.headers) - region.delete(cache_key) - return [] + try: + archive_stream = io.BytesIO(request.content) + if is_rarfile(archive_stream): + return self.process_archive_subtitle_files(RarFile(archive_stream), language, video, link, fps, num_cds) + elif is_zipfile(archive_stream): + return self.process_archive_subtitle_files(ZipFile(archive_stream), language, video, link, fps, num_cds) + except: + pass + + logger.error('Ignore unsupported archive %r', request.headers) + region.delete(cache_key) + return [] diff --git a/libs/subliminal_patch/providers/subsunacs.py b/libs/subliminal_patch/providers/subsunacs.py index 19c5eff86..137d2f7bf 100644 --- a/libs/subliminal_patch/providers/subsunacs.py +++ b/libs/subliminal_patch/providers/subsunacs.py @@ -55,7 +55,12 @@ class SubsUnacsSubtitle(Subtitle): self.video = video self.fps = fps self.num_cds = num_cds - self.release_info = os.path.splitext(filename)[0] + self.release_info = filename + if fps: + if video.fps and float(video.fps) == fps: + self.release_info += " [{:.3f}]".format(fps) + else: + self.release_info += " [{:.3f}]".format(fps) @property def id(self): @@ -168,7 +173,7 @@ class SubsUnacsProvider(Provider): element = a_element_wrapper.find('a', {'class': 'tooltip'}) if element: link = element.get('href') - notes = element.get('title') + notes = re.sub(r'()', r"", element.get('title')) title = element.get_text() try: @@ -230,11 +235,8 @@ class SubsUnacsProvider(Provider): is_7zip = isinstance(archiveStream, SevenZipFile) if is_7zip: - try: - file_content = archiveStream.readall() - file_list = sorted(file_content) - except: - return [] + file_content = archiveStream.readall() + file_list = sorted(file_content) else: file_list = sorted(archiveStream.namelist()) @@ -268,14 +270,17 @@ class SubsUnacsProvider(Provider): else: logger.info('Cache file: %s', codecs.encode(cache_key, 'hex_codec').decode('utf-8')) - archive_stream = io.BytesIO(request.content) - if is_rarfile(archive_stream): - return self.process_archive_subtitle_files(RarFile(archive_stream), language, video, link, fps, num_cds) - elif is_zipfile(archive_stream): - return self.process_archive_subtitle_files(ZipFile(archive_stream), language, video, link, fps, num_cds) - elif archive_stream.seek(0) == 0 and is_7zfile(archive_stream): - return self.process_archive_subtitle_files(SevenZipFile(archive_stream), language, video, link, fps, num_cds) - else: - logger.error('Ignore unsupported archive %r', request.headers) - region.delete(cache_key) - return [] + try: + archive_stream = io.BytesIO(request.content) + if is_rarfile(archive_stream): + return self.process_archive_subtitle_files(RarFile(archive_stream), language, video, link, fps, num_cds) + elif is_zipfile(archive_stream): + return self.process_archive_subtitle_files(ZipFile(archive_stream), language, video, link, fps, num_cds) + elif archive_stream.seek(0) == 0 and is_7zfile(archive_stream): + return self.process_archive_subtitle_files(SevenZipFile(archive_stream), language, video, link, fps, num_cds) + except: + pass + + logger.error('Ignore unsupported archive %r', request.headers) + region.delete(cache_key) + return [] diff --git a/libs/subliminal_patch/providers/yavkanet.py b/libs/subliminal_patch/providers/yavkanet.py index 6de60ef35..4555fd177 100644 --- a/libs/subliminal_patch/providers/yavkanet.py +++ b/libs/subliminal_patch/providers/yavkanet.py @@ -37,7 +37,12 @@ class YavkaNetSubtitle(Subtitle): self.type = type self.video = video self.fps = fps - self.release_info = os.path.splitext(filename)[0] + self.release_info = filename + if fps: + if video.fps and float(video.fps) == fps: + self.release_info += " [{:.3f}]".format(fps) + else: + self.release_info += " [{:.3f}]".format(fps) @property def id(self): @@ -141,7 +146,7 @@ class YavkaNetProvider(Provider): element = row.find('a', {'class': 'selector'}) if element: link = element.get('href') - notes = element.get('content') + notes = re.sub(r'(?s)(.*)

', r"\1", element.get('content')) title = element.get_text() try: @@ -205,12 +210,15 @@ class YavkaNetProvider(Provider): else: logger.info('Cache file: %s', codecs.encode(cache_key, 'hex_codec').decode('utf-8')) - archive_stream = io.BytesIO(request.content) - if is_rarfile(archive_stream): - return self.process_archive_subtitle_files(RarFile(archive_stream), language, video, link, fps) - elif is_zipfile(archive_stream): - return self.process_archive_subtitle_files(ZipFile(archive_stream), language, video, link, fps) - else: - logger.error('Ignore unsupported archive %r', request.headers) - region.delete(cache_key) - return [] + try: + archive_stream = io.BytesIO(request.content) + if is_rarfile(archive_stream): + return self.process_archive_subtitle_files(RarFile(archive_stream), language, video, link, fps) + elif is_zipfile(archive_stream): + return self.process_archive_subtitle_files(ZipFile(archive_stream), language, video, link, fps) + except: + pass + + logger.error('Ignore unsupported archive %r', request.headers) + region.delete(cache_key) + return [] From b4165408fbd6afbfe9992a335aa35f4a89fa9b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20V=C3=A9zina?= <5130500+morpheus65535@users.noreply.github.com> Date: Mon, 17 Aug 2020 23:52:48 -0400 Subject: [PATCH 03/21] Another attempt to fix #1034. --- bazarr/get_providers.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/bazarr/get_providers.py b/bazarr/get_providers.py index a29abac35..5e65d4eea 100644 --- a/bazarr/get_providers.py +++ b/bazarr/get_providers.py @@ -30,8 +30,8 @@ hours_until_end_of_day = time_until_end_of_day().seconds // 3600 + 1 VALID_THROTTLE_EXCEPTIONS = (TooManyRequests, DownloadLimitExceeded, ServiceUnavailable, APIThrottled, ParseResponseError, IPAddressBlocked) -VALID_COUNT_EXCEPTIONS = ('TooManyRequests', 'ServiceUnavailable', 'APIThrottled', requests.Timeout, - requests.ReadTimeout, socket.timeout) +VALID_COUNT_EXCEPTIONS = ('TooManyRequests', 'ServiceUnavailable', 'APIThrottled', requests.exceptions.Timeout, + requests.exceptions.ConnectTimeout, requests.exceptions.ReadTimeout, socket.timeout) PROVIDER_THROTTLE_MAP = { "default": { @@ -40,9 +40,10 @@ PROVIDER_THROTTLE_MAP = { ServiceUnavailable: (datetime.timedelta(minutes=20), "20 minutes"), APIThrottled: (datetime.timedelta(minutes=10), "10 minutes"), ParseResponseError: (datetime.timedelta(hours=6), "6 hours"), - requests.Timeout: (datetime.timedelta(hours=1), "1 hour"), + requests.exceptions.Timeout: (datetime.timedelta(hours=1), "1 hour"), socket.timeout: (datetime.timedelta(hours=1), "1 hour"), - requests.ReadTimeout: (datetime.timedelta(hours=1), "1 hour"), + requests.exceptions.ConnectTimeout: (datetime.timedelta(hours=1), "1 hour"), + requests.exceptions.ReadTimeout: (datetime.timedelta(hours=1), "1 hour"), }, "opensubtitles": { TooManyRequests: (datetime.timedelta(hours=3), "3 hours"), From 55cff621397bd218bbad66bd48200f32f01cd015 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20V=C3=A9zina?= <5130500+morpheus65535@users.noreply.github.com> Date: Tue, 18 Aug 2020 09:12:01 -0400 Subject: [PATCH 04/21] Fix for #1074. --- bazarr/subsyncer.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bazarr/subsyncer.py b/bazarr/subsyncer.py index b0cfa018c..0d85665a5 100644 --- a/bazarr/subsyncer.py +++ b/bazarr/subsyncer.py @@ -49,9 +49,11 @@ class SubSyncer: '{0}'.format(self.srtin)) else: if result['sync_was_successful']: + offset_seconds = result['offset_seconds'] or 0 + framerate_scale_factor = result['framerate_scale_factor'] or 0 message = "{0} subtitles synchronization ended with an offset of {1} seconds and a framerate scale " \ - "factor of {2}.".format(language_from_alpha3(srt_lang), result['offset_seconds'], - "{:.2f}".format(result['framerate_scale_factor'])) + "factor of {2}.".format(language_from_alpha3(srt_lang), offset_seconds, + "{:.2f}".format(framerate_scale_factor)) if media_type == 'series': history_log(action=5, sonarr_series_id=sonarr_series_id, sonarr_episode_id=sonarr_episode_id, From f740231e641fd679e4744f12d4e54542f491bdaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20V=C3=A9zina?= <5130500+morpheus65535@users.noreply.github.com> Date: Tue, 18 Aug 2020 13:20:45 -0400 Subject: [PATCH 05/21] Fix for missing language name from Radarr v3. --- bazarr/get_movies.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bazarr/get_movies.py b/bazarr/get_movies.py index 39f24ce62..b056bb819 100644 --- a/bazarr/get_movies.py +++ b/bazarr/get_movies.py @@ -151,7 +151,8 @@ def update_movies(): audio_language = profile_id_to_language(movie['qualityProfileId'], audio_profiles) else: if len(movie['movieFile']['languages']): - audio_language = movie['movieFile']['languages'][0]['name'] + if 'name' in movie['movieFile']['languages'][0]: + audio_language = movie['movieFile']['languages'][0]['name'] tags = [d['label'] for d in tagsDict if d['id'] in movie['tags']] From d95dc2b8233da3f0767ee7b0118cc553ac2c8cc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20V=C3=A9zina?= <5130500+morpheus65535@users.noreply.github.com> Date: Tue, 18 Aug 2020 15:24:31 -0400 Subject: [PATCH 06/21] Another fix for Radarr v3. --- bazarr/get_movies.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bazarr/get_movies.py b/bazarr/get_movies.py index b056bb819..ffa19051e 100644 --- a/bazarr/get_movies.py +++ b/bazarr/get_movies.py @@ -150,7 +150,7 @@ def update_movies(): if radarr_version.startswith('0'): audio_language = profile_id_to_language(movie['qualityProfileId'], audio_profiles) else: - if len(movie['movieFile']['languages']): + if 'language' in movie['movieFile'] and len(movie['movieFile']['languages']): if 'name' in movie['movieFile']['languages'][0]: audio_language = movie['movieFile']['languages'][0]['name'] From d6ce71b16f85a1c6d5ba61fdf0ac125647752f86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20V=C3=A9zina?= <5130500+morpheus65535@users.noreply.github.com> Date: Tue, 18 Aug 2020 15:28:07 -0400 Subject: [PATCH 07/21] Another fix for Radarr v3. --- bazarr/get_movies.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bazarr/get_movies.py b/bazarr/get_movies.py index ffa19051e..ce730f9af 100644 --- a/bazarr/get_movies.py +++ b/bazarr/get_movies.py @@ -150,7 +150,7 @@ def update_movies(): if radarr_version.startswith('0'): audio_language = profile_id_to_language(movie['qualityProfileId'], audio_profiles) else: - if 'language' in movie['movieFile'] and len(movie['movieFile']['languages']): + if 'languages' in movie['movieFile'] and len(movie['movieFile']['languages']): if 'name' in movie['movieFile']['languages'][0]: audio_language = movie['movieFile']['languages'][0]['name'] From 5dbde75893e984b667c8e35f224bff48fd7825e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20V=C3=A9zina?= <5130500+morpheus65535@users.noreply.github.com> Date: Tue, 18 Aug 2020 16:35:06 -0400 Subject: [PATCH 08/21] Another attempt to fix audio languages for Radarr v3. --- bazarr/get_movies.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bazarr/get_movies.py b/bazarr/get_movies.py index ce730f9af..ff3505795 100644 --- a/bazarr/get_movies.py +++ b/bazarr/get_movies.py @@ -151,8 +151,11 @@ def update_movies(): audio_language = profile_id_to_language(movie['qualityProfileId'], audio_profiles) else: if 'languages' in movie['movieFile'] and len(movie['movieFile']['languages']): - if 'name' in movie['movieFile']['languages'][0]: - audio_language = movie['movieFile']['languages'][0]['name'] + for item in movie['movieFile']['languages']: + if isinstance(item, dict): + if 'name' in item: + audio_language = item['name'] + break tags = [d['label'] for d in tagsDict if d['id'] in movie['tags']] From 6ad4843cdfbe213141f14ff760e4117ed6688d5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20V=C3=A9zina?= <5130500+morpheus65535@users.noreply.github.com> Date: Wed, 19 Aug 2020 15:23:43 -0400 Subject: [PATCH 09/21] Multiple fixes to ffsubsync. --- libs/ffsubsync/ffsubsync.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/libs/ffsubsync/ffsubsync.py b/libs/ffsubsync/ffsubsync.py index 18d772c12..31815762f 100644 --- a/libs/ffsubsync/ffsubsync.py +++ b/libs/ffsubsync/ffsubsync.py @@ -41,12 +41,15 @@ def make_test_case(args, npy_savename, sync_was_successful): raise ValueError('need non-null npy_savename') tar_dir = '{}.{}'.format( args.reference, - datetime.now().strftime('%Y-%m-%d-%H:%M:%S') + datetime.now().strftime('%Y-%m-%d-%H-%M-%S') ) logger.info('creating test archive {}.tar.gz...'.format(tar_dir)) os.mkdir(tar_dir) try: - shutil.move('ffsubsync.log', tar_dir) + log_path = 'ffsubsync.log' + if args.log_dir_path and os.path.isdir(args.log_dir_path): + log_path = os.path.join(args.log_dir_path, log_path) + shutil.move(log_path, tar_dir) shutil.copy(args.srtin, tar_dir) if sync_was_successful: shutil.move(args.srtout, tar_dir) @@ -62,10 +65,10 @@ def make_test_case(args, npy_savename, sync_was_successful): if archive_format in supported_formats: shutil.make_archive(tar_dir, 'gztar', os.curdir, tar_dir) break - else: - logger.error('failed to create test archive; no formats supported ' - '(this should not happen)') - return 1 + else: + logger.error('failed to create test archive; no formats supported ' + '(this should not happen)') + return 1 logger.info('...done') finally: shutil.rmtree(tar_dir) @@ -265,7 +268,10 @@ def run(args): result['retval'] = 1 return result if args.make_test_case: - handler = logging.FileHandler('ffsubsync.log') + log_path = 'ffsubsync.log' + if args.log_dir_path and os.path.isdir(args.log_dir_path): + log_path = os.path.join(args.log_dir_path, log_path) + handler = logging.FileHandler(log_path) logger.addHandler(handler) if args.extract_subs_from_stream is not None: result['retval'] = extract_subtitles_from_reference(args) @@ -286,6 +292,8 @@ def run(args): srt_pipes = make_srt_pipes(args) sync_was_successful = try_sync(args, reference_pipe, srt_pipes, result) if args.make_test_case: + handler.close() + logger.removeHandler(handler) result['retval'] += make_test_case(args, npy_savename, sync_was_successful) return result @@ -354,6 +362,8 @@ def add_cli_only_args(parser): '--ffmpeg-path', '--ffmpegpath', default=None, help='Where to look for ffmpeg and ffprobe. Uses the system PATH by default.' ) + parser.add_argument('--log-dir-path', default=None, help='Where to save ffsubsync.log file (must be an existing ' + 'directory).') parser.add_argument('--vlc-mode', action='store_true', help=argparse.SUPPRESS) parser.add_argument('--gui-mode', action='store_true', help=argparse.SUPPRESS) From 88452468cf88ae14335c5115e66c3c97d69d1796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20V=C3=A9zina?= <5130500+morpheus65535@users.noreply.github.com> Date: Wed, 19 Aug 2020 15:40:33 -0400 Subject: [PATCH 10/21] Added debug mode for subtitles synchronization. --- bazarr/config.py | 3 ++- bazarr/subsyncer.py | 41 ++++++++++++++++++++++-------------- views/settingssubtitles.html | 17 +++++++++++++-- 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/bazarr/config.py b/bazarr/config.py index b266280a2..72fe3cb3e 100644 --- a/bazarr/config.py +++ b/bazarr/config.py @@ -162,7 +162,8 @@ defaults = { 'use_subsync_threshold': 'False', 'subsync_threshold': '90', 'use_subsync_movie_threshold': 'False', - 'subsync_movie_threshold': '70' + 'subsync_movie_threshold': '70', + 'debug': 'False' } } diff --git a/bazarr/subsyncer.py b/bazarr/subsyncer.py index 0d85665a5..220f492ae 100644 --- a/bazarr/subsyncer.py +++ b/bazarr/subsyncer.py @@ -5,6 +5,8 @@ from utils import get_binary from utils import history_log, history_log_movie from get_languages import alpha2_from_alpha3, language_from_alpha3 from helper import path_mappings +from config import settings +from get_args import args class SubSyncer: @@ -15,12 +17,13 @@ class SubSyncer: self.ffmpeg_path = None self.args = None self.vad = 'subs_then_auditok' + self.log_dir_path = os.path.join(args.config_dir, 'log') def sync(self, video_path, srt_path, srt_lang, media_type, sonarr_series_id=None, sonarr_episode_id=None, radarr_id=None): self.reference = video_path self.srtin = srt_path - self.srtout = None + self.srtout = '{}.synced.srt'.format(os.path.splitext(self.srtin)[0]) self.args = None ffprobe_exe = get_binary('ffprobe') @@ -39,8 +42,10 @@ class SubSyncer: self.ffmpeg_path = os.path.dirname(ffmpeg_exe) try: - unparsed_args = [self.reference, '-i', self.srtin, '--overwrite-input', '--ffmpegpath', self.ffmpeg_path, - '--vad', self.vad] + 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) @@ -49,20 +54,24 @@ class SubSyncer: '{0}'.format(self.srtin)) else: if result['sync_was_successful']: - offset_seconds = result['offset_seconds'] or 0 - framerate_scale_factor = result['framerate_scale_factor'] or 0 - message = "{0} subtitles synchronization ended with an offset of {1} seconds and a framerate scale " \ - "factor of {2}.".format(language_from_alpha3(srt_lang), offset_seconds, - "{:.2f}".format(framerate_scale_factor)) + if not settings.subsync.getboolean('debug'): + os.remove(self.srtin) + os.rename(self.srtout, self.srtin) + + offset_seconds = result['offset_seconds'] or 0 + framerate_scale_factor = result['framerate_scale_factor'] or 0 + message = "{0} subtitles synchronization ended with an offset of {1} seconds and a framerate " \ + "scale factor of {2}.".format(language_from_alpha3(srt_lang), offset_seconds, + "{:.2f}".format(framerate_scale_factor)) - if media_type == 'series': - history_log(action=5, sonarr_series_id=sonarr_series_id, sonarr_episode_id=sonarr_episode_id, - description=message, video_path=path_mappings.path_replace_reverse(self.reference), - language=alpha2_from_alpha3(srt_lang), subtitles_path=srt_path) - else: - history_log_movie(action=5, radarr_id=radarr_id, description=message, - video_path=path_mappings.path_replace_reverse_movie(self.reference), - language=alpha2_from_alpha3(srt_lang), subtitles_path=srt_path) + if media_type == 'series': + history_log(action=5, sonarr_series_id=sonarr_series_id, sonarr_episode_id=sonarr_episode_id, + description=message, video_path=path_mappings.path_replace_reverse(self.reference), + language=alpha2_from_alpha3(srt_lang), subtitles_path=srt_path) + else: + history_log_movie(action=5, radarr_id=radarr_id, description=message, + video_path=path_mappings.path_replace_reverse_movie(self.reference), + language=alpha2_from_alpha3(srt_lang), subtitles_path=srt_path) else: logging.error('BAZARR unable to sync subtitles: {0}'.format(self.srtin)) diff --git a/views/settingssubtitles.html b/views/settingssubtitles.html index c04197aad..e01012f93 100644 --- a/views/settingssubtitles.html +++ b/views/settingssubtitles.html @@ -412,14 +412,26 @@ {% endif %}
- Subtitles synchronization + Automatic subtitles synchronization
- + +
+
+
+
+ Subtitles synchronization debugging +
+
+ +
@@ -680,6 +692,7 @@ $('#settings-general-chmod_enabled').prop('checked', {{'true' if settings.general.getboolean('chmod_enabled') else 'false'}}).trigger('change'); $('#settings-subsync-use_subsync').prop('checked', {{'true' if settings.subsync.getboolean('use_subsync') else 'false'}}).trigger('change'); $('#settings-subsync-use_subsync_threshold').prop('checked', {{'true' if settings.subsync.getboolean('use_subsync_threshold') else 'false'}}).trigger('change'); + $('#settings-subsync-debug').prop('checked', {{'true' if settings.subsync.getboolean('debug') else 'false'}}).trigger('change'); $('#settings-subsync-use_subsync_movie_threshold').prop('checked', {{'true' if settings.subsync.getboolean('use_subsync_movie_threshold') else 'false'}}).trigger('change'); $('#settings-general-use_postprocessing').prop('checked', {{'true' if settings.general.getboolean('use_postprocessing') else 'false'}}).trigger('change'); $('#settings-general-use_postprocessing_threshold').prop('checked', {{'true' if settings.general.getboolean('use_postprocessing_threshold') else 'false'}}).trigger('change'); From ebde79a8cd5efcbc1d9584a71ed652f7e983060a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20V=C3=A9zina?= <5130500+morpheus65535@users.noreply.github.com> Date: Thu, 20 Aug 2020 10:19:34 -0400 Subject: [PATCH 11/21] Switched to the actual episodes audio language instead of series audio profile language. --- bazarr/api.py | 13 +++++++++---- bazarr/database.py | 1 + bazarr/get_episodes.py | 15 ++++++++++++--- bazarr/get_subtitle.py | 12 ++++++------ views/episodes.html | 10 +++++++--- views/series.html | 4 ++-- views/serieseditor.html | 2 +- 7 files changed, 38 insertions(+), 19 deletions(-) diff --git a/bazarr/api.py b/bazarr/api.py index c61da14bf..a40fd6e3a 100644 --- a/bazarr/api.py +++ b/bazarr/api.py @@ -462,6 +462,11 @@ class Episodes(Resource): # Add Datatables rowId item.update({"DT_RowId": 'row_' + str(item['sonarrEpisodeId'])}) + # Parse audio language + item.update({"audio_language": {"name": item['audio_language'], + "code2": alpha2_from_language(item['audio_language']) or None, + "code3": alpha3_from_language(item['audio_language']) or None}}) + # Parse subtitles if item['subtitles']: item.update({"subtitles": ast.literal_eval(item['subtitles'])}) @@ -540,8 +545,8 @@ class EpisodesSubtitlesDownload(Resource): title = request.form.get('title') providers_list = get_providers() providers_auth = get_providers_auth() - audio_language = database.execute("SELECT audio_language FROM table_shows WHERE sonarrSeriesId=?", - (sonarrSeriesId,), only_one=True)['audio_language'] + audio_language = database.execute("SELECT audio_language FROM table_episodes WHERE sonarrEpisodeId=?", + (sonarrEpisodeId,), only_one=True)['audio_language'] try: result = download_subtitle(episodePath, language, audio_language, hi, forced, providers_list, providers_auth, sceneName, @@ -609,8 +614,8 @@ class EpisodesSubtitlesManualDownload(Resource): sonarrEpisodeId = request.form.get('sonarrEpisodeId') title = request.form.get('title') providers_auth = get_providers_auth() - audio_language = database.execute("SELECT audio_language FROM table_shows WHERE sonarrSeriesId=?", - (sonarrSeriesId,), only_one=True)['audio_language'] + audio_language = database.execute("SELECT audio_language FROM table_episodes WHERE sonarrEpisodeId=?", + (sonarrEpisodeId,), only_one=True)['audio_language'] try: result = manual_download_subtitle(episodePath, language, audio_language, hi, forced, subtitle, diff --git a/bazarr/database.py b/bazarr/database.py index 15e9c2d60..5046f9974 100644 --- a/bazarr/database.py +++ b/bazarr/database.py @@ -99,6 +99,7 @@ def db_upgrade(): ['table_episodes', 'video_codec', 'text'], ['table_episodes', 'audio_codec', 'text'], ['table_episodes', 'episode_file_id', 'integer'], + ['table_episodes', 'audio_language', 'text'], ['table_movies', 'sortTitle', 'text'], ['table_movies', 'year', 'text'], ['table_movies', 'alternativeTitles', 'text'], diff --git a/bazarr/get_episodes.py b/bazarr/get_episodes.py index d9e485422..1e303a8f5 100644 --- a/bazarr/get_episodes.py +++ b/bazarr/get_episodes.py @@ -85,6 +85,13 @@ def sync_episodes(): videoCodec = None audioCodec = None + audio_language = None + if 'language' in episode['episodeFile'] and len(episode['episodeFile']['language']): + item = episode['episodeFile']['language'] + if isinstance(item, dict): + if 'name' in item: + audio_language = item['name'] + # Add episodes in sonarr to current episode list current_episodes_sonarr.append(episode['id']) @@ -101,7 +108,8 @@ def sync_episodes(): 'resolution': resolution, 'video_codec': videoCodec, 'audio_codec': audioCodec, - 'episode_file_id': episode['episodeFile']['id']}) + 'episode_file_id': episode['episodeFile']['id'], + 'audio_language': audio_language}) else: episodes_to_add.append({'sonarrSeriesId': episode['seriesId'], 'sonarrEpisodeId': episode['id'], @@ -115,7 +123,8 @@ def sync_episodes(): 'resolution': resolution, 'video_codec': videoCodec, 'audio_codec': audioCodec, - 'episode_file_id': episode['episodeFile']['id']}) + 'episode_file_id': episode['episodeFile']['id'], + 'audio_language': audio_language}) # Remove old episodes from DB removed_episodes = list(set(current_episodes_db_list) - set(current_episodes_sonarr)) @@ -131,7 +140,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 FROM table_episodes") + "episode_file_id, audio_language FROM table_episodes") for item in episodes_in_db: episode_in_db_list.append(item) diff --git a/bazarr/get_subtitle.py b/bazarr/get_subtitle.py index b30d5a911..4ac1fc120 100644 --- a/bazarr/get_subtitle.py +++ b/bazarr/get_subtitle.py @@ -641,7 +641,7 @@ def manual_upload_subtitle(path, language, forced, title, scene_name, media_type def series_download_subtitles(no): episodes_details = database.execute("SELECT table_episodes.path, table_episodes.missing_subtitles, monitored, " "table_episodes.sonarrEpisodeId, table_episodes.scene_name, table_shows.tags, " - "table_shows.seriesType FROM table_episodes INNER JOIN table_shows on " + "table_shows.seriesType, table_episodes.audio_language FROM table_episodes INNER JOIN table_shows on " "table_shows.sonarrSeriesId = table_episodes.sonarrSeriesId WHERE " "table_episodes.sonarrSeriesId=? and missing_subtitles!='[]'", (no,)) episodes_details = filter_exclusions(episodes_details, 'series') @@ -650,7 +650,7 @@ def series_download_subtitles(no): return series_details = database.execute( - "SELECT hearing_impaired, audio_language, title, forced FROM table_shows WHERE sonarrSeriesId=?", + "SELECT hearing_impaired, title, forced FROM table_shows WHERE sonarrSeriesId=?", (no,), only_one=True) if not series_details: logging.debug("BAZARR no series with that sonarrSeriesId can be found in database:", str(no)) @@ -667,7 +667,7 @@ def series_download_subtitles(no): if language is not None: result = download_subtitle(path_mappings.path_replace(episode['path']), str(alpha3_from_alpha2(language.split(':')[0])), - series_details['audio_language'], + episode['audio_language'], series_details['hearing_impaired'], "True" if len(language.split(':')) > 1 else "False", providers_list, @@ -697,7 +697,7 @@ def episode_download_subtitles(no): episodes_details = database.execute("SELECT table_episodes.path, table_episodes.missing_subtitles, monitored, " "table_episodes.sonarrEpisodeId, table_episodes.scene_name, table_shows.tags, " "table_shows.hearing_impaired, table_shows.title, table_shows.sonarrSeriesId, " - "table_shows.forced, table_shows.audio_language, table_shows.seriesType FROM " + "table_shows.forced, table_episodes.audio_language, table_shows.seriesType FROM " "table_episodes LEFT JOIN table_shows on table_episodes.sonarrSeriesId = " "table_shows.sonarrSeriesId WHERE sonarrEpisodeId=?", (no,)) episodes_details = filter_exclusions(episodes_details, 'series') @@ -792,7 +792,7 @@ def movies_download_subtitles(no): def wanted_download_subtitles(path, l, count_episodes): episodes_details = database.execute("SELECT table_episodes.path, table_episodes.missing_subtitles, " "table_episodes.sonarrEpisodeId, table_episodes.sonarrSeriesId, " - "table_shows.hearing_impaired, table_shows.audio_language, table_episodes.scene_name," + "table_shows.hearing_impaired, table_episodes.audio_language, table_episodes.scene_name," "table_episodes.failedAttempts, table_shows.title, table_shows.forced " "FROM table_episodes LEFT JOIN table_shows on " "table_episodes.sonarrSeriesId = table_shows.sonarrSeriesId " @@ -1071,7 +1071,7 @@ def upgrade_subtitles(): if settings.general.getboolean('use_sonarr'): upgradable_episodes = database.execute("SELECT table_history.video_path, table_history.language, " "table_history.score, table_shows.hearing_impaired, " - "table_shows.audio_language, table_episodes.scene_name, table_episodes.title," + "table_episodes.audio_language, table_episodes.scene_name, table_episodes.title," "table_episodes.sonarrSeriesId, table_episodes.sonarrEpisodeId," "MAX(table_history.timestamp) as timestamp, table_episodes.monitored, " "table_shows.languages, table_shows.forced, table_shows.tags, " diff --git a/views/episodes.html b/views/episodes.html index 9d6995ae1..0fa3509e9 100644 --- a/views/episodes.html +++ b/views/episodes.html @@ -113,6 +113,7 @@ Episode Title + Audio Language Existing Subtitles Missing Subtitles Manual Search @@ -232,7 +233,7 @@
- Audio Language + Audio Profile
@@ -579,6 +580,9 @@ } } }, + { + data: 'audio_language.name' + }, { data: null, render: function (data) { @@ -629,7 +633,7 @@ data: null, render: function (data) { if (data.desired_languages !== '[]') { - return ''; + return ''; } else { return '' } @@ -876,7 +880,7 @@ $('#upload_sonarrSeriesId').val($(this).data("sonarrseriesid")); $('#upload_sonarrEpisodeId').val($(this).data("sonarrepisodeid")); $('#upload_title').val($(this).data("episode_title")); - $('#upload_audioLanguage').val(seriesDetails['audio_language']['name']); + $('#upload_audioLanguage').val($(this).data("audio_language")); $('#manual_language_select').empty(); $.each(enabledLanguages, function (i, item) { diff --git a/views/series.html b/views/series.html index ad3afab83..74171b032 100644 --- a/views/series.html +++ b/views/series.html @@ -22,7 +22,7 @@ Name Path Exist - Audio Language + Audio Profile Subtitles Languages Hearing-Impaired Forced @@ -46,7 +46,7 @@
- Audio Language + Audio Profile
diff --git a/views/serieseditor.html b/views/serieseditor.html index 81a13d438..016b2371b 100644 --- a/views/serieseditor.html +++ b/views/serieseditor.html @@ -16,7 +16,7 @@ Name - Audio Language + Audio Profile Subtitles Languages Hearing-Impaired Forced From 138af20bb6423e79a22b5670047f54495e5decbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20V=C3=A9zina?= <5130500+morpheus65535@users.noreply.github.com> Date: Thu, 20 Aug 2020 22:12:47 -0400 Subject: [PATCH 12/21] Ignore path mappings if both sides are the same. --- bazarr/helper.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bazarr/helper.py b/bazarr/helper.py index 4d7f1b432..4307affde 100644 --- a/bazarr/helper.py +++ b/bazarr/helper.py @@ -16,8 +16,8 @@ class PathMappings: self.path_mapping_movies = [] def update(self): - self.path_mapping_series = ast.literal_eval(settings.general.path_mappings) - self.path_mapping_movies = ast.literal_eval(settings.general.path_mappings_movie) + self.path_mapping_series = [x for x in ast.literal_eval(settings.general.path_mappings) if x[0] != x[1]] + self.path_mapping_movies = [x for x in ast.literal_eval(settings.general.path_mappings_movie) if x[0] != x[1]] def path_replace(self, path): if path is None: From bb38d5397cbc94e53a8aa6ff3f1a7e59639cdfcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20V=C3=A9zina?= <5130500+morpheus65535@users.noreply.github.com> Date: Sun, 23 Aug 2020 21:10:59 -0400 Subject: [PATCH 13/21] Moving UI API key authentication to X-Api-Key header. --- bazarr/api.py | 5 ++++- views/_main.html | 9 +-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/bazarr/api.py b/bazarr/api.py index a40fd6e3a..9db482869 100644 --- a/bazarr/api.py +++ b/bazarr/api.py @@ -54,8 +54,11 @@ def authenticate(actual_method): apikey_settings = settings.auth.apikey apikey_get = request.args.get('apikey') apikey_post = request.form.get('apikey') + apikey_header = None + if 'X-Api-Key' in request.headers: + apikey_header = request.headers['X-Api-Key'] - if apikey_settings in [apikey_get, apikey_post]: + if apikey_settings in [apikey_get, apikey_post, apikey_header]: return actual_method(*args, **kwargs) return abort(401, message="Unauthorized") diff --git a/views/_main.html b/views/_main.html index 014a4dfa4..adb4eec35 100644 --- a/views/_main.html +++ b/views/_main.html @@ -495,14 +495,7 @@ // Add apikey to all AJAX requests. $.ajaxSetup({ - data: { - apikey: "{{ settings.auth.apikey }}" - } - }); - $.ajaxPrefilter(function (options, originalOptions, jqXHR) { - if (originalOptions.data instanceof FormData) { - originalOptions.data.append("apikey", "{{ settings.auth.apikey }}"); - } + headers: { 'X-Api-Key': "{{ settings.auth.apikey }}" } }); $(window).on('beforeunload', function () { From 8940ee617d23abca843b7c93ca313353dd59d36e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20V=C3=A9zina?= <5130500+morpheus65535@users.noreply.github.com> Date: Sun, 23 Aug 2020 22:38:13 -0400 Subject: [PATCH 14/21] Merged upstream changes in ffsubsync --- libs/ffsubsync/ffsubsync.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libs/ffsubsync/ffsubsync.py b/libs/ffsubsync/ffsubsync.py index 31815762f..b05249297 100644 --- a/libs/ffsubsync/ffsubsync.py +++ b/libs/ffsubsync/ffsubsync.py @@ -63,12 +63,12 @@ def make_test_case(args, npy_savename, sync_was_successful): preferred_formats = ['gztar', 'bztar', 'xztar', 'zip', 'tar'] for archive_format in preferred_formats: if archive_format in supported_formats: - shutil.make_archive(tar_dir, 'gztar', os.curdir, tar_dir) + shutil.make_archive(tar_dir, archive_format, os.curdir, tar_dir) break - else: - logger.error('failed to create test archive; no formats supported ' - '(this should not happen)') - return 1 + else: + logger.error('failed to create test archive; no formats supported ' + '(this should not happen)') + return 1 logger.info('...done') finally: shutil.rmtree(tar_dir) From be821176006cc8ffdacefc51e141b61c8fb02061 Mon Sep 17 00:00:00 2001 From: josdion Date: Tue, 25 Aug 2020 19:05:33 +0300 Subject: [PATCH 15/21] Fix #1089 - YIFY Subtitles server URL update --- .../providers/yifysubtitles.py | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/libs/subliminal_patch/providers/yifysubtitles.py b/libs/subliminal_patch/providers/yifysubtitles.py index 59d683577..e41dc6c69 100644 --- a/libs/subliminal_patch/providers/yifysubtitles.py +++ b/libs/subliminal_patch/providers/yifysubtitles.py @@ -95,7 +95,7 @@ class YifySubtitlesProvider(Provider): ] languages = {Language(l, c) for (_, l, c) in YifyLanguages} - server_url = 'https://www.yifysubtitles.com' + server_urls = ['https://yifysubtitles.org', 'https://www.yifysubtitles.com'] video_types = (Movie,) def initialize(self): @@ -112,20 +112,20 @@ class YifySubtitlesProvider(Provider): def terminate(self): self.session.close() - def _parse_row(self, row, languages): + def _parse_row(self, row, languages, server_url): td = row.findAll('td') rating = int(td[0].text) sub_lang = td[1].text release = re.sub(r'^subtitle ', '', td[2].text) sub_link = td[2].find('a').get('href') - sub_link = re.sub(r'^/subtitles/', self.server_url + '/subtitle/', sub_link) + '.zip' + page_link = server_url + sub_link + sub_link = re.sub(r'^/subtitles/', server_url + '/subtitle/', sub_link) + '.zip' hi = True if td[3].find('span', {'class': 'hi-subtitle'}) else False uploader = td[4].text - page_link = self.server_url + td[5].find('a').get('href') _, l, c = next(x for x in self.YifyLanguages if x[0] == sub_lang) lang = Language(l, c) - if languages & set([lang]): + if languages & {lang}: return [YifySubtitle(lang, page_link, release, uploader, sub_link, rating, hi)] return [] @@ -134,9 +134,13 @@ class YifySubtitlesProvider(Provider): subtitles = [] logger.info('Searching subtitle %r', imdb_id) - response = self.session.get(self.server_url + '/movie-imdb/' + imdb_id, - allow_redirects=False, timeout=10, - headers={'Referer': self.server_url}) + for server_url in self.server_urls: + response = self.session.get(server_url + '/movie-imdb/' + imdb_id, + allow_redirects=False, timeout=10, + headers={'Referer': server_url}) + if response.status_code == 200: + break + response.raise_for_status() if response.status_code != 200: @@ -150,7 +154,7 @@ class YifySubtitlesProvider(Provider): for row in rows: try: - subtitles = subtitles + self._parse_row(row, languages) + subtitles = subtitles + self._parse_row(row, languages, server_url) except Exception as e: pass From 32f6d0861d2c1baf83ee07ffb4543009d5cf6ac0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20V=C3=A9zina?= <5130500+morpheus65535@users.noreply.github.com> Date: Fri, 28 Aug 2020 22:09:38 -0400 Subject: [PATCH 16/21] Improvement to mass editor loading speed. --- bazarr/api.py | 62 +++++++++++++++++++++++++++++++++++++++++ views/movieseditor.html | 4 +-- views/serieseditor.html | 4 +-- 3 files changed, 66 insertions(+), 4 deletions(-) diff --git a/bazarr/api.py b/bazarr/api.py index 9db482869..5189a9bf7 100644 --- a/bazarr/api.py +++ b/bazarr/api.py @@ -389,6 +389,36 @@ class Series(Resource): return '', 204 +class SeriesEditor(Resource): + @authenticate + def get(self, **kwargs): + draw = request.args.get('draw') + + result = database.execute("SELECT sonarrSeriesId, title, languages, hearing_impaired, forced, audio_language " + "FROM table_shows ORDER BY sortTitle") + + row_count = len(result) + + for item in result: + # Add Datatables rowId + item.update({"DT_RowId": 'row_' + str(item['sonarrSeriesId'])}) + + # Parse audio language + item.update({"audio_language": {"name": item['audio_language'], + "code2": alpha2_from_language(item['audio_language']) or None, + "code3": alpha3_from_language(item['audio_language']) or None}}) + + # Parse desired languages + if item['languages'] and item['languages'] != 'None': + item.update({"languages": ast.literal_eval(item['languages'])}) + for i, subs in enumerate(item['languages']): + item['languages'][i] = {"name": language_from_alpha2(subs), + "code2": subs, + "code3": alpha3_from_alpha2(subs)} + + return jsonify(draw=draw, recordsTotal=row_count, recordsFiltered=row_count, data=result) + + class SeriesEditSave(Resource): @authenticate def post(self): @@ -924,6 +954,36 @@ class Movies(Resource): return '', 204 +class MoviesEditor(Resource): + @authenticate + def get(self): + draw = request.args.get('draw') + + result = database.execute("SELECT radarrId, title, languages, hearing_impaired, forced, audio_language " + "FROM table_movies ORDER BY sortTitle") + + row_count = len(result) + + for item in result: + # Add Datatables rowId + item.update({"DT_RowId": 'row_' + str(item['radarrId'])}) + + # Parse audio language + item.update({"audio_language": {"name": item['audio_language'], + "code2": alpha2_from_language(item['audio_language']) or None, + "code3": alpha3_from_language(item['audio_language']) or None}}) + + # Parse desired languages + if item['languages'] and item['languages'] != 'None': + item.update({"languages": ast.literal_eval(item['languages'])}) + for i, subs in enumerate(item['languages']): + item['languages'][i] = {"name": language_from_alpha2(subs), + "code2": subs, + "code3": alpha3_from_alpha2(subs)} + + return jsonify(draw=draw, recordsTotal=row_count, recordsFiltered=row_count, data=result) + + class MoviesEditSave(Resource): @authenticate def post(self): @@ -1843,6 +1903,7 @@ api.add_resource(SystemStatus, '/systemstatus') api.add_resource(SystemReleases, '/systemreleases') api.add_resource(Series, '/series') +api.add_resource(SeriesEditor, '/series_editor') api.add_resource(SeriesEditSave, '/series_edit_save') api.add_resource(Episodes, '/episodes') api.add_resource(EpisodesSubtitlesDelete, '/episodes_subtitles_delete') @@ -1856,6 +1917,7 @@ api.add_resource(EpisodesHistory, '/episodes_history') api.add_resource(EpisodesTools, '/episodes_tools') api.add_resource(Movies, '/movies') +api.add_resource(MoviesEditor, '/movies_editor') api.add_resource(MoviesEditSave, '/movies_edit_save') api.add_resource(MovieSubtitlesDelete, '/movie_subtitles_delete') api.add_resource(MovieSubtitlesDownload, '/movie_subtitles_download') diff --git a/views/movieseditor.html b/views/movieseditor.html index 97bd75a60..f87c9ab0e 100644 --- a/views/movieseditor.html +++ b/views/movieseditor.html @@ -67,7 +67,7 @@ var event_json = JSON.parse(event); if (event_json.type === 'movies_editor' && event_json.action === 'update') { $.ajax({ - url: "{{ url_for('api.movies') }}", + url: "{{ url_for('api.movieseditor') }}", success: function (data) { if (data.data.length) { $('#movies').DataTable().ajax.reload(resetPaging = false); @@ -96,7 +96,7 @@ lengthChange: true, responsive: true, paging: false, - ajax: "{{ url_for('api.movies') }}", + ajax: "{{ url_for('api.movieseditor') }}", columnDefs: [{ orderable: false, className: 'select-checkbox', diff --git a/views/serieseditor.html b/views/serieseditor.html index 016b2371b..058422338 100644 --- a/views/serieseditor.html +++ b/views/serieseditor.html @@ -67,7 +67,7 @@ var event_json = JSON.parse(event); if (event_json.type === 'series_editor' && event_json.action === 'update') { $.ajax({ - url: "{{ url_for('api.series') }}", + url: "{{ url_for('api.serieseditor') }}", success: function (data) { if (data.data.length) { $('#series').DataTable().ajax.reload(resetPaging = false); @@ -96,7 +96,7 @@ lengthChange: true, responsive: true, paging: false, - ajax: "{{ url_for('api.series') }}", + ajax: "{{ url_for('api.serieseditor') }}", columnDefs: [{ orderable: false, className: 'select-checkbox', From 221f92d09a399d06f2f7f1c3031609f903ab6541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20V=C3=A9zina?= <5130500+morpheus65535@users.noreply.github.com> Date: Tue, 1 Sep 2020 12:30:31 -0400 Subject: [PATCH 17/21] Improvement to each DB requests that need to filter out monitored, tags or series type. --- bazarr/api.py | 49 ++++++++++++++++++++---------------------- bazarr/config.py | 10 +++++++++ bazarr/database.py | 33 ++++++++++++++-------------- bazarr/get_episodes.py | 14 ++++++------ bazarr/get_movies.py | 10 ++++----- bazarr/get_subtitle.py | 36 ++++++++++++++----------------- 6 files changed, 78 insertions(+), 74 deletions(-) diff --git a/bazarr/api.py b/bazarr/api.py index 5189a9bf7..cfed43a75 100644 --- a/bazarr/api.py +++ b/bazarr/api.py @@ -18,7 +18,7 @@ from config import settings, base_url, save_settings from init import * import logging -from database import database, filter_exclusions +from database import database, get_exclusion_clause from helper import path_mappings from get_languages import language_from_alpha3, language_from_alpha2, alpha2_from_alpha3, alpha2_from_language, \ alpha3_from_language, alpha3_from_alpha2 @@ -86,8 +86,7 @@ class BadgesSeries(Resource): missing_episodes = database.execute("SELECT table_shows.tags, table_episodes.monitored, table_shows.seriesType " "FROM table_episodes INNER JOIN table_shows on table_shows.sonarrSeriesId =" " table_episodes.sonarrSeriesId WHERE missing_subtitles is not null AND " - "missing_subtitles != '[]'") - missing_episodes = filter_exclusions(missing_episodes, 'series') + "missing_subtitles != '[]'" + get_exclusion_clause('series')) missing_episodes = len(missing_episodes) result = { @@ -100,8 +99,7 @@ class BadgesMovies(Resource): @authenticate def get(self): missing_movies = database.execute("SELECT tags, monitored FROM table_movies WHERE missing_subtitles is not " - "null AND missing_subtitles != '[]'") - missing_movies = filter_exclusions(missing_movies, 'movie') + "null AND missing_subtitles != '[]'" + get_exclusion_clause('movie')) missing_movies = len(missing_movies) result = { @@ -330,8 +328,8 @@ class Series(Resource): "table_shows.seriesType FROM table_episodes INNER JOIN table_shows " "on table_shows.sonarrSeriesId = table_episodes.sonarrSeriesId " "WHERE table_episodes.sonarrSeriesId=? AND missing_subtitles is not " - "null AND missing_subtitles != '[]'", (item['sonarrSeriesId'],)) - episodeMissingCount = filter_exclusions(episodeMissingCount, 'series') + "null AND missing_subtitles != '[]'" + + get_exclusion_clause('series'), (item['sonarrSeriesId'],)) episodeMissingCount = len(episodeMissingCount) item.update({"episodeMissingCount": episodeMissingCount}) @@ -339,8 +337,8 @@ class Series(Resource): episodeFileCount = database.execute("SELECT table_shows.tags, table_episodes.monitored, " "table_shows.seriesType FROM table_episodes INNER JOIN table_shows on " "table_shows.sonarrSeriesId = table_episodes.sonarrSeriesId WHERE " - "table_episodes.sonarrSeriesId=?", (item['sonarrSeriesId'],)) - episodeFileCount = filter_exclusions(episodeFileCount, 'series') + "table_episodes.sonarrSeriesId=?" + get_exclusion_clause('series'), + (item['sonarrSeriesId'],)) episodeFileCount = len(episodeFileCount) item.update({"episodeFileCount": episodeFileCount}) @@ -460,7 +458,7 @@ class SeriesEditSave(Resource): list_missing_subtitles(no=seriesId, send_event=False) event_stream(type='series_editor', action='update') - event_stream(type='badges') + event_stream(type='badges_series') return '', 204 @@ -1024,7 +1022,7 @@ class MoviesEditSave(Resource): list_missing_subtitles_movies(no=radarrId, send_event=False) event_stream(type='movies_editor', action='update') - event_stream(type='badges') + event_stream(type='badges_movies') return '', 204 @@ -1329,9 +1327,9 @@ class HistorySeries(Resource): "table_shows.seriesType FROM table_history INNER JOIN table_episodes on " "table_episodes.sonarrEpisodeId = table_history.sonarrEpisodeId INNER JOIN table_shows on " "table_shows.sonarrSeriesId = table_episodes.sonarrSeriesId WHERE action IN (" + - ','.join(map(str, query_actions)) + ") AND timestamp > ? AND score is not null GROUP BY " - "table_history.video_path, table_history.language", (minimum_timestamp,)) - upgradable_episodes = filter_exclusions(upgradable_episodes, 'series') + ','.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", + (minimum_timestamp,)) for upgradable_episode in upgradable_episodes: if upgradable_episode['timestamp'] > minimum_timestamp: @@ -1432,9 +1430,8 @@ class HistoryMovies(Resource): upgradable_movies = database.execute( "SELECT video_path, MAX(timestamp) as timestamp, score, tags, 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 GROUP BY video_path, " - "language", (minimum_timestamp,)) - upgradable_movies = filter_exclusions(upgradable_movies, 'movie') + ','.join(map(str, query_actions)) + ") AND timestamp > ? AND score is not NULL" + + get_exclusion_clause('movie') + " GROUP BY video_path, language", (minimum_timestamp,)) for upgradable_movie in upgradable_movies: if upgradable_movie['timestamp'] > minimum_timestamp: @@ -1571,8 +1568,8 @@ class WantedSeries(Resource): data_count = database.execute("SELECT table_episodes.monitored, table_shows.tags, table_shows.seriesType FROM " "table_episodes INNER JOIN table_shows on table_shows.sonarrSeriesId = " - "table_episodes.sonarrSeriesId WHERE table_episodes.missing_subtitles != '[]'") - data_count = filter_exclusions(data_count, 'series') + "table_episodes.sonarrSeriesId WHERE table_episodes.missing_subtitles != '[]'" + + get_exclusion_clause('series')) row_count = len(data_count) data = database.execute("SELECT table_shows.title as seriesTitle, table_episodes.monitored, " "table_episodes.season || 'x' || table_episodes.episode as episode_number, " @@ -1581,8 +1578,8 @@ class WantedSeries(Resource): "table_episodes.sonarrEpisodeId, table_episodes.scene_name, table_shows.tags, " "table_episodes.failedAttempts, table_shows.seriesType FROM table_episodes INNER JOIN " "table_shows on table_shows.sonarrSeriesId = table_episodes.sonarrSeriesId WHERE " - "table_episodes.missing_subtitles != '[]' ORDER BY table_episodes._rowid_ DESC") - data = filter_exclusions(data, 'series')[int(start):int(start)+int(length)] + "table_episodes.missing_subtitles != '[]'" + get_exclusion_clause('series') + + " ORDER BY table_episodes._rowid_ DESC LIMIT " + length + " OFFSET " + start) for item in data: # Parse missing subtitles @@ -1614,13 +1611,13 @@ class WantedMovies(Resource): length = request.args.get('length') or -1 draw = request.args.get('draw') - data_count = database.execute("SELECT tags, monitored FROM table_movies WHERE missing_subtitles != '[]'") - data_count = filter_exclusions(data_count, 'movie') + data_count = database.execute("SELECT tags, monitored FROM table_movies WHERE missing_subtitles != '[]'" + + get_exclusion_clause('movie')) row_count = len(data_count) data = database.execute("SELECT title, missing_subtitles, radarrId, path, hearing_impaired, sceneName, " - "failedAttempts, tags, monitored FROM table_movies WHERE missing_subtitles != '[]' " - "ORDER BY _rowid_ DESC") - data = filter_exclusions(data, 'movie')[int(start):int(start)+int(length)] + "failedAttempts, tags, monitored FROM table_movies WHERE missing_subtitles != '[]'" + + get_exclusion_clause('movie') + " ORDER BY _rowid_ DESC LIMIT " + length + " OFFSET " + + start) for item in data: # Parse missing subtitles diff --git a/bazarr/config.py b/bazarr/config.py index 72fe3cb3e..e45165a4c 100644 --- a/bazarr/config.py +++ b/bazarr/config.py @@ -228,6 +228,11 @@ def save_settings(settings_items): 'settings-proxy-password']: configure_proxy = True + if key in ['settings-sonarr-excluded_tags', 'settings-sonarr-only_monitored', + 'settings-sonarr-excluded_series_types', 'settings.radarr.excluded_tags', + 'settings-radarr-only_monitored']: + exclusion_updated = True + if settings_keys[0] == 'settings': settings[settings_keys[1]][settings_keys[2]] = str(value) @@ -253,6 +258,11 @@ def save_settings(settings_items): if configure_proxy: configure_proxy_func() + if exclusion_updated: + from event_handler import event_stream + event_stream(type='badges_series') + event_stream(type='badges_movies') + def url_sonarr(): if settings.sonarr.getboolean('ssl'): diff --git a/bazarr/database.py b/bazarr/database.py index 5046f9974..005d96345 100644 --- a/bazarr/database.py +++ b/bazarr/database.py @@ -149,28 +149,29 @@ def db_upgrade(): "provider text, subs_id text, language text)") -def filter_exclusions(dicts_list, type): +def get_exclusion_clause(type): + where_clause = '' if type == 'series': tagsList = ast.literal_eval(settings.sonarr.excluded_tags) - monitoredOnly = settings.sonarr.getboolean('only_monitored') + for tag in tagsList: + where_clause += ' AND table_shows.tags NOT LIKE "%\'' + tag + '\'%"' else: tagsList = ast.literal_eval(settings.radarr.excluded_tags) - monitoredOnly = settings.radarr.getboolean('only_monitored') + for tag in tagsList: + where_clause += ' AND table_movies.tags NOT LIKE "%\'' + tag + '\'%"' - # Filter tags - dictsList_tags_filtered = [item for item in dicts_list if set(tagsList).isdisjoint(ast.literal_eval(item['tags']))] - - # Filter monitored - if monitoredOnly: - dictsList_monitored_filtered = [item for item in dictsList_tags_filtered if item['monitored'] == 'True'] + if type == 'series': + monitoredOnly = settings.sonarr.getboolean('only_monitored') + if monitoredOnly: + where_clause += ' AND table_episodes.monitored = "True"' else: - dictsList_monitored_filtered = dictsList_tags_filtered + monitoredOnly = settings.radarr.getboolean('only_monitored') + if monitoredOnly: + where_clause += ' AND table_movies.monitored = "True"' - # Filter series type if type == 'series': - dictsList_types_filtered = [item for item in dictsList_monitored_filtered if item['seriesType'] not in - ast.literal_eval(settings.sonarr.excluded_series_types)] - else: - dictsList_types_filtered = dictsList_monitored_filtered + typesList = ast.literal_eval(settings.sonarr.excluded_series_types) + for type in typesList: + where_clause += ' AND table_shows.seriesType != "' + type + '"' - return dictsList_types_filtered + return where_clause diff --git a/bazarr/get_episodes.py b/bazarr/get_episodes.py index 1e303a8f5..8e8bee97c 100644 --- a/bazarr/get_episodes.py +++ b/bazarr/get_episodes.py @@ -1,7 +1,7 @@ # coding=utf-8 import requests import logging -from database import database, dict_converter +from database import database, dict_converter, get_exclusion_clause from config import settings, url_sonarr from helper import path_mappings @@ -180,11 +180,13 @@ def sync_episodes(): if len(altered_episodes) <= 5: logging.debug("BAZARR No more than 5 episodes were added during this sync then we'll search for subtitles.") for altered_episode in altered_episodes: - if settings.sonarr.getboolean('only_monitored'): - if altered_episode[2] == 'True': - episode_download_subtitles(altered_episode[0]) - else: - episode_download_subtitles(altered_episode[0]) + data = database.execute("SELECT table_episodes.sonarrEpisodeId, table_episodes.monitored, table_shows.tags," + " table_shows.seriesType FROM table_episodes LEFT JOIN table_shows on " + "table_episodes.sonarrSeriesId = table_shows.sonarrSeriesId WHERE " + "sonarrEpisodeId = ?" + get_exclusion_clause('series'), (altered_episode[0],), + only_one=True) + + episode_download_subtitles(data['sonarrEpisodeId']) else: logging.debug("BAZARR More than 5 episodes were added during this sync then we wont search for subtitles right now.") diff --git a/bazarr/get_movies.py b/bazarr/get_movies.py index ff3505795..3fcc8a849 100644 --- a/bazarr/get_movies.py +++ b/bazarr/get_movies.py @@ -10,7 +10,7 @@ from utils import get_radarr_version from list_subtitles import store_subtitles_movie, list_missing_subtitles_movies, movies_full_scan_subtitles from get_subtitle import movies_download_subtitles -from database import database, dict_converter +from database import database, dict_converter, get_exclusion_clause def update_all_movies(): @@ -265,11 +265,9 @@ def update_movies(): if len(altered_movies) <= 5: logging.debug("BAZARR No more than 5 movies were added during this sync then we'll search for subtitles.") for altered_movie in altered_movies: - if settings.radarr.getboolean('only_monitored'): - if altered_movie[3] == 'True': - movies_download_subtitles(altered_movie[2]) - else: - movies_download_subtitles(altered_movie[2]) + data = database.execute("SELECT * FROM table_movies WHERE radarrId = ?" + + get_exclusion_clause('movie'), (altered_movie[2],), only_one=True) + movies_download_subtitles(data['radarrId']) else: logging.debug("BAZARR More than 5 movies were added during this sync then we wont search for subtitles.") diff --git a/bazarr/get_subtitle.py b/bazarr/get_subtitle.py index 4ac1fc120..7ef841614 100644 --- a/bazarr/get_subtitle.py +++ b/bazarr/get_subtitle.py @@ -29,11 +29,10 @@ from notifier import send_notifications, send_notifications_movie from get_providers import get_providers, get_providers_auth, provider_throttle, provider_pool from knowit import api from subsyncer import subsync -from database import database, dict_mapper, filter_exclusions +from database import database, dict_mapper, get_exclusion_clause from analytics import track_event from locale import getpreferredencoding -import chardet def get_video(path, title, sceneName, providers=None, media_type="movie"): @@ -641,10 +640,10 @@ def manual_upload_subtitle(path, language, forced, title, scene_name, media_type def series_download_subtitles(no): episodes_details = database.execute("SELECT table_episodes.path, table_episodes.missing_subtitles, monitored, " "table_episodes.sonarrEpisodeId, table_episodes.scene_name, table_shows.tags, " - "table_shows.seriesType, table_episodes.audio_language FROM table_episodes INNER JOIN table_shows on " - "table_shows.sonarrSeriesId = table_episodes.sonarrSeriesId WHERE " - "table_episodes.sonarrSeriesId=? and missing_subtitles!='[]'", (no,)) - episodes_details = filter_exclusions(episodes_details, 'series') + "table_shows.seriesType, table_episodes.audio_language FROM table_episodes " + "INNER JOIN table_shows on table_shows.sonarrSeriesId = " + "table_episodes.sonarrSeriesId WHERE table_episodes.sonarrSeriesId=? and " + "missing_subtitles!='[]'" + get_exclusion_clause('series'), (no,)) if not episodes_details: logging.debug("BAZARR no episode for that sonarrSeriesId can be found in database:", str(no)) return @@ -699,8 +698,8 @@ def episode_download_subtitles(no): "table_shows.hearing_impaired, table_shows.title, table_shows.sonarrSeriesId, " "table_shows.forced, table_episodes.audio_language, table_shows.seriesType FROM " "table_episodes LEFT JOIN table_shows on table_episodes.sonarrSeriesId = " - "table_shows.sonarrSeriesId WHERE sonarrEpisodeId=?", (no,)) - episodes_details = filter_exclusions(episodes_details, 'series') + "table_shows.sonarrSeriesId WHERE sonarrEpisodeId=?" + + get_exclusion_clause('series'), (no,)) if not episodes_details: logging.debug("BAZARR no episode with that sonarrEpisodeId can be found in database:", str(no)) return @@ -743,8 +742,7 @@ def episode_download_subtitles(no): def movies_download_subtitles(no): movies = database.execute( "SELECT path, missing_subtitles, audio_language, radarrId, sceneName, hearing_impaired, title, forced, tags, " - "monitored FROM table_movies WHERE radarrId=?", (no,)) - movies = filter_exclusions(movies, 'movie') + "monitored FROM table_movies WHERE radarrId=?" + get_exclusion_clause('movie'), (no,)) if not len(movies): logging.debug("BAZARR no movie with that radarrId can be found in database:", str(no)) return @@ -911,8 +909,7 @@ def wanted_search_missing_subtitles_series(): episodes = database.execute("SELECT table_episodes.path, table_shows.tags, table_episodes.monitored, " "table_shows.seriesType FROM table_episodes INNER JOIN table_shows on " "table_shows.sonarrSeriesId = table_episodes.sonarrSeriesId WHERE missing_subtitles != " - "'[]'") - episodes = filter_exclusions(episodes, 'series') + "'[]'" + get_exclusion_clause('series')) # path_replace dict_mapper.path_replace(episodes) @@ -929,8 +926,8 @@ def wanted_search_missing_subtitles_series(): def wanted_search_missing_subtitles_movies(): - movies = database.execute("SELECT path, tags, monitored FROM table_movies WHERE missing_subtitles != '[]'") - movies = filter_exclusions(movies, 'movie') + movies = database.execute("SELECT path, tags, monitored FROM table_movies WHERE missing_subtitles != '[]'" + + get_exclusion_clause('movie')) # path_replace dict_mapper.path_replace_movie(movies) @@ -1079,11 +1076,10 @@ def upgrade_subtitles(): "table_shows.sonarrSeriesId = table_history.sonarrSeriesId INNER JOIN " "table_episodes on table_episodes.sonarrEpisodeId = " "table_history.sonarrEpisodeId WHERE action IN " - "(" + ','.join(map(str, query_actions)) + - ") AND timestamp > ? AND score is not null GROUP BY " + "(" + ','.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", (minimum_timestamp,)) - upgradable_episodes = filter_exclusions(upgradable_episodes, 'series') upgradable_episodes_not_perfect = [] for upgradable_episode in upgradable_episodes: if upgradable_episode['timestamp'] > minimum_timestamp: @@ -1111,9 +1107,9 @@ 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 GROUP BY table_history_movie.video_path, " - "table_history_movie.language", (minimum_timestamp,)) - upgradable_movies = filter_exclusions(upgradable_movies, 'movie') + "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: if upgradable_movie['timestamp'] > minimum_timestamp: From 7eda4116a035cf6fd547b07eeede2b962c33fbcc Mon Sep 17 00:00:00 2001 From: Isak Samsten Date: Wed, 2 Sep 2020 15:28:42 +0200 Subject: [PATCH 18/21] Add attribute `raw_timestamp` for API consumption --- bazarr/api.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bazarr/api.py b/bazarr/api.py index cfed43a75..c28178474 100644 --- a/bazarr/api.py +++ b/bazarr/api.py @@ -745,6 +745,7 @@ class EpisodesHistory(Resource): "sonarrEpisodeId, subs_id, video_path, subtitles_path FROM table_history " "WHERE sonarrEpisodeId=? ORDER BY timestamp DESC", (episodeid,)) for item in episode_history: + item['raw_timestamp'] = item['timestamp'] item['timestamp'] = "
" + \ @@ -1229,6 +1230,7 @@ class MovieHistory(Resource): "video_path, subtitles_path FROM table_history_movie WHERE radarrId=? ORDER " "BY timestamp DESC", (radarrid,)) for item in movie_history: + item['raw_timestamp'] = item['timestamp'] item['timestamp'] = "
" + \ @@ -1373,6 +1375,7 @@ class HistorySeries(Resource): # Make timestamp pretty if item['timestamp']: + item['raw_timestamp'] = item['timestamp'] item['timestamp'] = pretty.date(int(item['timestamp'])) if item['path']: @@ -1472,6 +1475,7 @@ class HistoryMovies(Resource): # Make timestamp pretty if item['timestamp']: + item['raw_timestamp'] = item['timestamp'] item['timestamp'] = pretty.date(int(item['timestamp'])) if item['video_path']: @@ -1674,6 +1678,7 @@ class BlacklistSeries(Resource): "OFFSET ?", (length, start)) for item in data: + item['raw_timestamp'] = item['timestamp'] # Make timestamp pretty item.update({'timestamp': pretty.date(datetime.datetime.fromtimestamp(item['timestamp']))}) @@ -1751,6 +1756,7 @@ class BlacklistMovies(Resource): "OFFSET ?", (length, start)) for item in data: + item['raw_timestamp'] = item['timestamp'] # Make timestamp pretty item.update({'timestamp': pretty.date(datetime.datetime.fromtimestamp(item['timestamp']))}) From 60b3b2d7f133f2e18dbecc0dc3107ced5676843e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20V=C3=A9zina?= <5130500+morpheus65535@users.noreply.github.com> Date: Thu, 3 Sep 2020 06:33:24 -0400 Subject: [PATCH 19/21] Fix for save_settings --- bazarr/config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bazarr/config.py b/bazarr/config.py index e45165a4c..3adddc3a4 100644 --- a/bazarr/config.py +++ b/bazarr/config.py @@ -182,6 +182,7 @@ def save_settings(settings_items): update_schedule = False update_path_map = False configure_proxy = False + exclusion_updated = False for key, value in settings_items: # Intercept database stored settings From 1f8194c25a6b5bd975c9cdfc46269c88b3a5b456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20V=C3=A9zina?= <5130500+morpheus65535@users.noreply.github.com> Date: Sun, 6 Sep 2020 08:28:38 -0400 Subject: [PATCH 20/21] Update ffsubsync --- libs/ffsubsync/_version.py | 4 ++-- libs/ffsubsync/ffsubsync.py | 22 ++++++++++++++-------- libs/ffsubsync/speech_transformers.py | 2 +- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/libs/ffsubsync/_version.py b/libs/ffsubsync/_version.py index 83abafbaf..fac1f364c 100644 --- a/libs/ffsubsync/_version.py +++ b/libs/ffsubsync/_version.py @@ -24,8 +24,8 @@ def get_keywords(): # each be defined on a line of their own. _version.py will just call # get_keywords(). git_refnames = " (HEAD -> master)" - git_full = "997749de8aac74ec19137a2e641b97ef1bba81ea" - git_date = "2020-08-04 20:06:18 -0700" + git_full = "ce46d91fa2d325a13c2830f8030a316ed49b6cc9" + git_date = "2020-09-05 11:15:34 -0700" keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} return keywords diff --git a/libs/ffsubsync/ffsubsync.py b/libs/ffsubsync/ffsubsync.py index b05249297..e3b08430b 100644 --- a/libs/ffsubsync/ffsubsync.py +++ b/libs/ffsubsync/ffsubsync.py @@ -49,7 +49,7 @@ def make_test_case(args, npy_savename, sync_was_successful): log_path = 'ffsubsync.log' if args.log_dir_path and os.path.isdir(args.log_dir_path): log_path = os.path.join(args.log_dir_path, log_path) - shutil.move(log_path, tar_dir) + shutil.copy(log_path, tar_dir) shutil.copy(args.srtin, tar_dir) if sync_was_successful: shutil.move(args.srtout, tar_dir) @@ -267,12 +267,14 @@ def run(args): 'when reference composed of subtitles') result['retval'] = 1 return result + log_handler = None + log_path = None if args.make_test_case: log_path = 'ffsubsync.log' if args.log_dir_path and os.path.isdir(args.log_dir_path): log_path = os.path.join(args.log_dir_path, log_path) - handler = logging.FileHandler(log_path) - logger.addHandler(handler) + log_handler = logging.FileHandler(log_path) + logger.addHandler(log_handler) if args.extract_subs_from_stream is not None: result['retval'] = extract_subtitles_from_reference(args) return result @@ -291,10 +293,14 @@ def run(args): return result srt_pipes = make_srt_pipes(args) sync_was_successful = try_sync(args, reference_pipe, srt_pipes, result) - if args.make_test_case: - handler.close() - logger.removeHandler(handler) - result['retval'] += make_test_case(args, npy_savename, sync_was_successful) + if log_handler is not None and log_path is not None: + assert args.make_test_case + log_handler.close() + logger.removeHandler(log_handler) + try: + result['retval'] += make_test_case(args, npy_savename, sync_was_successful) + finally: + os.remove(log_path) return result @@ -363,7 +369,7 @@ def add_cli_only_args(parser): help='Where to look for ffmpeg and ffprobe. Uses the system PATH by default.' ) parser.add_argument('--log-dir-path', default=None, help='Where to save ffsubsync.log file (must be an existing ' - 'directory).') + 'directory).') parser.add_argument('--vlc-mode', action='store_true', help=argparse.SUPPRESS) parser.add_argument('--gui-mode', action='store_true', help=argparse.SUPPRESS) diff --git a/libs/ffsubsync/speech_transformers.py b/libs/ffsubsync/speech_transformers.py index 02a7f332b..8290f82f9 100644 --- a/libs/ffsubsync/speech_transformers.py +++ b/libs/ffsubsync/speech_transformers.py @@ -233,7 +233,7 @@ class VideoSpeechTransformer(TransformerMixin): if not in_bytes: break newstuff = len(in_bytes) / float(bytes_per_frame) / self.frame_rate - if simple_progress + newstuff > total_duration: + if total_duration is not None and simple_progress + newstuff > total_duration: newstuff = total_duration - simple_progress simple_progress += newstuff pbar.update(newstuff) From 72041d3fd2a80c52a569e91bd3a1afcad71a325c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Louis=20V=C3=A9zina?= <5130500+morpheus65535@users.noreply.github.com> Date: Sun, 6 Sep 2020 08:43:10 -0400 Subject: [PATCH 21/21] Fix for #1098 --- libs/subliminal_patch/providers/subdivx.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/subliminal_patch/providers/subdivx.py b/libs/subliminal_patch/providers/subdivx.py index 998460ff0..f144a4cdc 100644 --- a/libs/subliminal_patch/providers/subdivx.py +++ b/libs/subliminal_patch/providers/subdivx.py @@ -168,7 +168,8 @@ class SubdivxSubtitlesProvider(Provider): download_link = self._get_download_link(subtitle) # download zip / rar file with the subtitle - response = self.session.get(download_link, headers={'Referer': subtitle.page_link}, timeout=30) + response = self.session.get(self.server_url + download_link, headers={'Referer': subtitle.page_link}, + timeout=30) self._check_response(response) # open the compressed archive