diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7f8c15659..0d050ccc0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -76,7 +76,7 @@ jobs: uses: actions/checkout@v4 - name: Set up Python 3.8 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: "3.8" diff --git a/.github/workflows/test_bazarr_execution.yml b/.github/workflows/test_bazarr_execution.yml index da31638c0..b7ded4c96 100644 --- a/.github/workflows/test_bazarr_execution.yml +++ b/.github/workflows/test_bazarr_execution.yml @@ -35,7 +35,7 @@ jobs: working-directory: ${{ env.UI_DIRECTORY }} - name: Set up Python 3.8 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: "3.8" diff --git a/bazarr/app/config.py b/bazarr/app/config.py index 5e9d74bbc..cda51d0ef 100644 --- a/bazarr/app/config.py +++ b/bazarr/app/config.py @@ -7,6 +7,7 @@ import logging import re from urllib.parse import quote_plus +from utilities.binaries import BinaryNotFound, get_binary from literals import EXIT_VALIDATION_ERROR from utilities.central import stop_bazarr from subliminal.cache import region @@ -54,6 +55,14 @@ class Validator(OriginalValidator): ) +def check_parser_binary(value): + try: + get_binary(value) + except BinaryNotFound as e: + raise ValidationError(f"Executable '{value}' not found in search path. Please install before making this selection.") + return True + + validators = [ # general section Validator('general.flask_secret_key', must_exist=True, default=hexlify(os.urandom(16)).decode(), @@ -119,7 +128,7 @@ validators = [ Validator('general.dont_notify_manual_actions', must_exist=True, default=False, is_type_of=bool), Validator('general.hi_extension', must_exist=True, default='hi', is_type_of=str, is_in=['hi', 'cc', 'sdh']), Validator('general.embedded_subtitles_parser', must_exist=True, default='ffprobe', is_type_of=str, - is_in=['ffprobe', 'mediainfo']), + is_in=['ffprobe', 'mediainfo'], condition=check_parser_binary), Validator('general.default_und_audio_lang', must_exist=True, default='', is_type_of=str), Validator('general.default_und_embedded_subtitles_lang', must_exist=True, default='', is_type_of=str), Validator('general.parse_embedded_audio_track', must_exist=True, default=False, is_type_of=bool), diff --git a/bazarr/radarr/info.py b/bazarr/radarr/info.py index c6a3181f3..aec8d65d6 100644 --- a/bazarr/radarr/info.py +++ b/bazarr/radarr/info.py @@ -3,7 +3,7 @@ import logging import requests import datetime -import json +from requests.exceptions import JSONDecodeError from dogpile.cache import make_region @@ -34,13 +34,13 @@ class GetRadarrInfo: if 'version' in radarr_json: radarr_version = radarr_json['version'] else: - raise json.decoder.JSONDecodeError - except json.decoder.JSONDecodeError: + raise JSONDecodeError + except JSONDecodeError: try: rv = f"{url_radarr()}/api/v3/system/status?apikey={settings.radarr.apikey}" radarr_version = requests.get(rv, timeout=int(settings.radarr.http_timeout), verify=False, headers=headers).json()['version'] - except json.decoder.JSONDecodeError: + except JSONDecodeError: logging.debug('BAZARR cannot get Radarr version') radarr_version = 'unknown' except Exception: diff --git a/bazarr/sonarr/info.py b/bazarr/sonarr/info.py index e7fcb8f89..5bccf27a2 100644 --- a/bazarr/sonarr/info.py +++ b/bazarr/sonarr/info.py @@ -3,7 +3,7 @@ import logging import requests import datetime -import json +from requests.exceptions import JSONDecodeError from dogpile.cache import make_region @@ -34,13 +34,13 @@ class GetSonarrInfo: if 'version' in sonarr_json: sonarr_version = sonarr_json['version'] else: - raise json.decoder.JSONDecodeError - except json.decoder.JSONDecodeError: + raise JSONDecodeError + except JSONDecodeError: try: sv = f"{url_sonarr()}/api/v3/system/status?apikey={settings.sonarr.apikey}" sonarr_version = requests.get(sv, timeout=int(settings.sonarr.http_timeout), verify=False, headers=headers).json()['version'] - except json.decoder.JSONDecodeError: + except JSONDecodeError: logging.debug('BAZARR cannot get Sonarr version') sonarr_version = 'unknown' except Exception: diff --git a/bazarr/utilities/backup.py b/bazarr/utilities/backup.py index 136a959b1..a28eadef5 100644 --- a/bazarr/utilities/backup.py +++ b/bazarr/utilities/backup.py @@ -33,7 +33,7 @@ def get_restore_path(): def get_backup_files(fullpath=True): backup_file_pattern = os.path.join(get_backup_path(), 'bazarr_backup_v*.zip') file_list = glob(backup_file_pattern) - file_list.sort(key=os.path.getmtime) + file_list.sort(key=os.path.getmtime, reverse=True) if fullpath: return file_list else: diff --git a/custom_libs/subliminal_patch/providers/hdbits.py b/custom_libs/subliminal_patch/providers/hdbits.py index 10793b9ea..19196aecd 100644 --- a/custom_libs/subliminal_patch/providers/hdbits.py +++ b/custom_libs/subliminal_patch/providers/hdbits.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- import functools -from json import JSONDecodeError +from requests.exceptions import JSONDecodeError import logging import re import time diff --git a/custom_libs/subliminal_patch/providers/ktuvit.py b/custom_libs/subliminal_patch/providers/ktuvit.py index 9bb746547..699349601 100644 --- a/custom_libs/subliminal_patch/providers/ktuvit.py +++ b/custom_libs/subliminal_patch/providers/ktuvit.py @@ -3,6 +3,7 @@ import io import logging import os import json +from requests.exceptions import JSONDecodeError from subzero.language import Language from guessit import guessit @@ -144,7 +145,7 @@ class KtuvitProvider(Provider): self.session.headers["Pragma"] = "no-cache" self.session.headers["Cache-Control"] = "no-cache" self.session.headers["Content-Type"] = "application/json" - self.session.headers["User-Agent"]: os.environ.get( + self.session.headers["User-Agent"] = os.environ.get( "SZ_USER_AGENT", "Sub-Zero/2" ) @@ -161,13 +162,13 @@ class KtuvitProvider(Provider): is_success = self.parse_d_response( r, "IsSuccess", False, "Authentication to the provider" ) - except json.decoder.JSONDecodeError: + except JSONDecodeError: logger.info("Failed to Login to Ktuvit") if not is_success: error_message = '' try: error_message = self.parse_d_response(r, "ErrorMessage", "[None]") - except json.decode.JSONDecoderError: + except JSONDecodeError: raise AuthenticationError( "Error Logging in to Ktuvit Provider: " + str(r.content) ) @@ -473,8 +474,8 @@ class KtuvitProvider(Provider): try: response_content = response.json() - except json.decoder.JSONDecodeError as ex: - raise json.decoder.JSONDecodeError( + except JSONDecodeError as ex: + raise JSONDecodeError( "Unable to parse JSON returned while getting " + message, ex.doc, ex.pos ) else: @@ -486,11 +487,11 @@ class KtuvitProvider(Provider): value = response_content.get(field, default_value) if not value and value != default_value: - raise json.decoder.JSONDecodeError( + raise JSONDecodeError( "Missing " + message, str(response_content), 0 ) else: - raise json.decoder.JSONDecodeError( + raise JSONDecodeError( "Incomplete JSON returned while getting " + message, str(response_content), 0 diff --git a/custom_libs/subliminal_patch/providers/subdivx.py b/custom_libs/subliminal_patch/providers/subdivx.py index 4b250a2a2..ae8625f47 100644 --- a/custom_libs/subliminal_patch/providers/subdivx.py +++ b/custom_libs/subliminal_patch/providers/subdivx.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import -from json import JSONDecodeError +from requests.exceptions import JSONDecodeError import logging import random import re diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 78e8bdf83..4282c78a2 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -34,7 +34,7 @@ "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", "@types/lodash": "^4.17.0", - "@types/node": "^20.11.26", + "@types/node": "^20.11.29", "@types/react": "^18.2.65", "@types/react-dom": "^18.2.21", "@types/react-table": "^7.7.19", @@ -3910,9 +3910,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.11.26", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.26.tgz", - "integrity": "sha512-YwOMmyhNnAWijOBQweOJnQPl068Oqd4K3OFbTc6AHJwzweUwwWG3GIFY74OKks2PJUDkQPeddOQES9mLn1CTEQ==", + "version": "20.11.29", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.29.tgz", + "integrity": "sha512-P99thMkD/1YkCvAtOd6/zGedKNA0p2fj4ZpjCzcNiSCBWgm3cNRTBfa/qjFnsKkkojxu4vVLtWpesnZ9+ap+gA==", "dev": true, "dependencies": { "undici-types": "~5.26.4" diff --git a/frontend/package.json b/frontend/package.json index 05f5e07e0..14bea1d1e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -38,7 +38,7 @@ "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", "@types/lodash": "^4.17.0", - "@types/node": "^20.11.26", + "@types/node": "^20.11.29", "@types/react": "^18.2.65", "@types/react-dom": "^18.2.21", "@types/react-table": "^7.7.19",