From f5d7b4d3218a7e88f5267d3c58f16fe271afce0e Mon Sep 17 00:00:00 2001 From: Cory Metcalfe Date: Wed, 25 Jan 2023 14:26:22 -0600 Subject: [PATCH] Added configurable request timeout to Sonarr and Radarr --- bazarr/app/config.py | 2 ++ bazarr/radarr/filesystem.py | 2 +- bazarr/radarr/info.py | 4 ++-- bazarr/radarr/notify.py | 2 +- bazarr/radarr/rootfolder.py | 2 +- bazarr/radarr/sync/utils.py | 6 +++--- bazarr/sonarr/filesystem.py | 2 +- bazarr/sonarr/info.py | 4 ++-- bazarr/sonarr/notify.py | 2 +- bazarr/sonarr/rootfolder.py | 2 +- bazarr/sonarr/sync/utils.py | 10 +++++----- frontend/src/pages/Settings/Radarr/index.tsx | 7 +++++++ frontend/src/pages/Settings/Radarr/options.ts | 10 ++++++++++ frontend/src/pages/Settings/Sonarr/index.tsx | 7 +++++++ frontend/src/pages/Settings/Sonarr/options.ts | 10 ++++++++++ 15 files changed, 54 insertions(+), 18 deletions(-) create mode 100644 frontend/src/pages/Settings/Radarr/options.ts create mode 100644 frontend/src/pages/Settings/Sonarr/options.ts diff --git a/bazarr/app/config.py b/bazarr/app/config.py index 0ce861856..18036fece 100644 --- a/bazarr/app/config.py +++ b/bazarr/app/config.py @@ -101,6 +101,7 @@ defaults = { 'port': '8989', 'base_url': '/', 'ssl': 'False', + 'http_timeout': '60', 'apikey': '', 'full_update': 'Daily', 'full_update_day': '6', @@ -119,6 +120,7 @@ defaults = { 'port': '7878', 'base_url': '/', 'ssl': 'False', + 'http_timeout': '60', 'apikey': '', 'full_update': 'Daily', 'full_update_day': '6', diff --git a/bazarr/radarr/filesystem.py b/bazarr/radarr/filesystem.py index a88c317fa..d8cb0e2e9 100644 --- a/bazarr/radarr/filesystem.py +++ b/bazarr/radarr/filesystem.py @@ -21,7 +21,7 @@ def browse_radarr_filesystem(path='#'): "&allowFoldersWithoutTrailingSlashes=true&includeFiles=false&apikey=" + \ settings.radarr.apikey try: - r = requests.get(url_radarr_api_filesystem, timeout=60, verify=False, headers=headers) + r = requests.get(url_radarr_api_filesystem, timeout=int(settings.radarr.http_timeout), verify=False, headers=headers) r.raise_for_status() except requests.exceptions.HTTPError: logging.exception("BAZARR Error trying to get series from Radarr. Http error.") diff --git a/bazarr/radarr/info.py b/bazarr/radarr/info.py index 85d31019f..88f7fbf89 100644 --- a/bazarr/radarr/info.py +++ b/bazarr/radarr/info.py @@ -29,7 +29,7 @@ class GetRadarrInfo: if settings.general.getboolean('use_radarr'): try: rv = url_radarr() + "/api/system/status?apikey=" + settings.radarr.apikey - radarr_json = requests.get(rv, timeout=60, verify=False, headers=headers).json() + radarr_json = requests.get(rv, timeout=int(settings.radarr.http_timeout), verify=False, headers=headers).json() if 'version' in radarr_json: radarr_version = radarr_json['version'] else: @@ -37,7 +37,7 @@ class GetRadarrInfo: except json.decoder.JSONDecodeError: try: rv = url_radarr() + "/api/v3/system/status?apikey=" + settings.radarr.apikey - radarr_version = requests.get(rv, timeout=60, verify=False, headers=headers).json()['version'] + radarr_version = requests.get(rv, timeout=int(settings.radarr.http_timeout), verify=False, headers=headers).json()['version'] except json.decoder.JSONDecodeError: logging.debug('BAZARR cannot get Radarr version') radarr_version = 'unknown' diff --git a/bazarr/radarr/notify.py b/bazarr/radarr/notify.py index e59932e5e..d2204b2b3 100644 --- a/bazarr/radarr/notify.py +++ b/bazarr/radarr/notify.py @@ -18,6 +18,6 @@ def notify_radarr(radarr_id): 'name': 'RescanMovie', 'movieId': int(radarr_id) } - requests.post(url, json=data, timeout=60, verify=False, headers=headers) + requests.post(url, json=data, timeout=int(settings.radarr.http_timeout), verify=False, headers=headers) except Exception: logging.exception('BAZARR cannot notify Radarr') diff --git a/bazarr/radarr/rootfolder.py b/bazarr/radarr/rootfolder.py index 9e0f8cec5..bbf3dd63b 100644 --- a/bazarr/radarr/rootfolder.py +++ b/bazarr/radarr/rootfolder.py @@ -22,7 +22,7 @@ def get_radarr_rootfolder(): url_radarr_api_rootfolder = url_radarr() + "/api/v3/rootfolder?apikey=" + apikey_radarr try: - rootfolder = requests.get(url_radarr_api_rootfolder, timeout=60, verify=False, headers=headers) + rootfolder = requests.get(url_radarr_api_rootfolder, timeout=int(settings.radarr.http_timeout), verify=False, headers=headers) except requests.exceptions.ConnectionError: logging.exception("BAZARR Error trying to get rootfolder from Radarr. Connection Error.") return [] diff --git a/bazarr/radarr/sync/utils.py b/bazarr/radarr/sync/utils.py index 81b0dd814..b36bee50b 100644 --- a/bazarr/radarr/sync/utils.py +++ b/bazarr/radarr/sync/utils.py @@ -18,7 +18,7 @@ def get_profile_list(): url_radarr_api_movies = url_radarr() + "/api/v3/qualityprofile?apikey=" + apikey_radarr try: - profiles_json = requests.get(url_radarr_api_movies, timeout=60, verify=False, headers=headers) + profiles_json = requests.get(url_radarr_api_movies, timeout=int(settings.radarr.http_timeout), verify=False, headers=headers) except requests.exceptions.ConnectionError: logging.exception("BAZARR Error trying to get profiles from Radarr. Connection Error.") except requests.exceptions.Timeout: @@ -50,7 +50,7 @@ def get_tags(): url_radarr_api_series = url_radarr() + "/api/v3/tag?apikey=" + apikey_radarr try: - tagsDict = requests.get(url_radarr_api_series, timeout=60, verify=False, headers=headers) + tagsDict = requests.get(url_radarr_api_series, timeout=int(settings.radarr.http_timeout), verify=False, headers=headers) except requests.exceptions.ConnectionError: logging.exception("BAZARR Error trying to get tags from Radarr. Connection Error.") return [] @@ -79,7 +79,7 @@ def get_movies_from_radarr_api(url, apikey_radarr, radarr_id=None): apikey_radarr try: - r = requests.get(url_radarr_api_movies, timeout=60, verify=False, headers=headers) + r = requests.get(url_radarr_api_movies, timeout=int(settings.radarr.http_timeout), verify=False, headers=headers) if r.status_code == 404: return r.raise_for_status() diff --git a/bazarr/sonarr/filesystem.py b/bazarr/sonarr/filesystem.py index e6eb5fc17..25bb66f08 100644 --- a/bazarr/sonarr/filesystem.py +++ b/bazarr/sonarr/filesystem.py @@ -20,7 +20,7 @@ def browse_sonarr_filesystem(path='#'): "&allowFoldersWithoutTrailingSlashes=true&includeFiles=false&apikey=" + \ settings.sonarr.apikey try: - r = requests.get(url_sonarr_api_filesystem, timeout=60, verify=False, headers=headers) + r = requests.get(url_sonarr_api_filesystem, timeout=int(settings.sonarr.http_timeout), verify=False, headers=headers) r.raise_for_status() except requests.exceptions.HTTPError: logging.exception("BAZARR Error trying to get series from Sonarr. Http error.") diff --git a/bazarr/sonarr/info.py b/bazarr/sonarr/info.py index becb8de68..287f9c774 100644 --- a/bazarr/sonarr/info.py +++ b/bazarr/sonarr/info.py @@ -29,7 +29,7 @@ class GetSonarrInfo: if settings.general.getboolean('use_sonarr'): try: sv = url_sonarr() + "/api/system/status?apikey=" + settings.sonarr.apikey - sonarr_json = requests.get(sv, timeout=60, verify=False, headers=headers).json() + sonarr_json = requests.get(sv, timeout=int(settings.sonarr.http_timeout), verify=False, headers=headers).json() if 'version' in sonarr_json: sonarr_version = sonarr_json['version'] else: @@ -37,7 +37,7 @@ class GetSonarrInfo: except json.decoder.JSONDecodeError: try: sv = url_sonarr() + "/api/v3/system/status?apikey=" + settings.sonarr.apikey - sonarr_version = requests.get(sv, timeout=60, verify=False, headers=headers).json()['version'] + sonarr_version = requests.get(sv, timeout=int(settings.sonarr.http_timeout), verify=False, headers=headers).json()['version'] except json.decoder.JSONDecodeError: logging.debug('BAZARR cannot get Sonarr version') sonarr_version = 'unknown' diff --git a/bazarr/sonarr/notify.py b/bazarr/sonarr/notify.py index 8b124e108..c6d004091 100644 --- a/bazarr/sonarr/notify.py +++ b/bazarr/sonarr/notify.py @@ -18,6 +18,6 @@ def notify_sonarr(sonarr_series_id): 'name': 'RescanSeries', 'seriesId': int(sonarr_series_id) } - requests.post(url, json=data, timeout=60, verify=False, headers=headers) + requests.post(url, json=data, timeout=int(settings.sonarr.http_timeout), verify=False, headers=headers) except Exception: logging.exception('BAZARR cannot notify Sonarr') diff --git a/bazarr/sonarr/rootfolder.py b/bazarr/sonarr/rootfolder.py index 6e71c3d20..a414e5421 100644 --- a/bazarr/sonarr/rootfolder.py +++ b/bazarr/sonarr/rootfolder.py @@ -22,7 +22,7 @@ def get_sonarr_rootfolder(): url_sonarr_api_rootfolder = url_sonarr() + "/api/v3/rootfolder?apikey=" + apikey_sonarr try: - rootfolder = requests.get(url_sonarr_api_rootfolder, timeout=60, verify=False, headers=headers) + rootfolder = requests.get(url_sonarr_api_rootfolder, timeout=int(settings.sonarr.http_timeout), verify=False, headers=headers) except requests.exceptions.ConnectionError: logging.exception("BAZARR Error trying to get rootfolder from Sonarr. Connection Error.") return [] diff --git a/bazarr/sonarr/sync/utils.py b/bazarr/sonarr/sync/utils.py index 031a9c9c9..de13d229e 100644 --- a/bazarr/sonarr/sync/utils.py +++ b/bazarr/sonarr/sync/utils.py @@ -22,7 +22,7 @@ def get_profile_list(): url_sonarr_api_series = url_sonarr() + "/api/v3/languageprofile?apikey=" + apikey_sonarr try: - profiles_json = requests.get(url_sonarr_api_series, timeout=60, verify=False, headers=headers) + profiles_json = requests.get(url_sonarr_api_series, timeout=int(settings.sonarr.http_timeout), verify=False, headers=headers) except requests.exceptions.ConnectionError: logging.exception("BAZARR Error trying to get profiles from Sonarr. Connection Error.") return None @@ -55,7 +55,7 @@ def get_tags(): url_sonarr_api_series = url_sonarr() + "/api/v3/tag?apikey=" + apikey_sonarr try: - tagsDict = requests.get(url_sonarr_api_series, timeout=60, verify=False, headers=headers) + tagsDict = requests.get(url_sonarr_api_series, timeout=int(settings.sonarr.http_timeout), verify=False, headers=headers) except requests.exceptions.ConnectionError: logging.exception("BAZARR Error trying to get tags from Sonarr. Connection Error.") return [] @@ -73,7 +73,7 @@ def get_series_from_sonarr_api(url, apikey_sonarr, sonarr_series_id=None): url_sonarr_api_series = url + "/api/{0}series/{1}?apikey={2}".format( '' if get_sonarr_info.is_legacy() else 'v3/', sonarr_series_id if sonarr_series_id else "", apikey_sonarr) try: - r = requests.get(url_sonarr_api_series, timeout=60, verify=False, headers=headers) + r = requests.get(url_sonarr_api_series, timeout=int(settings.sonarr.http_timeout), verify=False, headers=headers) r.raise_for_status() except requests.exceptions.HTTPError as e: if e.response.status_code: @@ -108,7 +108,7 @@ def get_episodes_from_sonarr_api(url, apikey_sonarr, series_id=None, episode_id= return try: - r = requests.get(url_sonarr_api_episode, timeout=60, verify=False, headers=headers) + r = requests.get(url_sonarr_api_episode, timeout=int(settings.sonarr.http_timeout), verify=False, headers=headers) r.raise_for_status() except requests.exceptions.HTTPError: logging.exception("BAZARR Error trying to get episodes from Sonarr. Http error.") @@ -136,7 +136,7 @@ def get_episodesFiles_from_sonarr_api(url, apikey_sonarr, series_id=None, episod return try: - r = requests.get(url_sonarr_api_episodeFiles, timeout=60, verify=False, headers=headers) + r = requests.get(url_sonarr_api_episodeFiles, timeout=int(settings.sonarr.http_timeout), verify=False, headers=headers) r.raise_for_status() except requests.exceptions.HTTPError: logging.exception("BAZARR Error trying to get episodeFiles from Sonarr. Http error.") diff --git a/frontend/src/pages/Settings/Radarr/index.tsx b/frontend/src/pages/Settings/Radarr/index.tsx index 497ef7873..8cd038ab8 100644 --- a/frontend/src/pages/Settings/Radarr/index.tsx +++ b/frontend/src/pages/Settings/Radarr/index.tsx @@ -9,11 +9,13 @@ import { Number, PathMappingTable, Section, + Selector, Slider, Text, URLTestButton, } from "../components"; import { moviesEnabledKey } from "../keys"; +import { timeoutOptions } from "./options"; const SettingsRadarrView: FunctionComponent = () => { return ( @@ -35,6 +37,11 @@ const SettingsRadarrView: FunctionComponent = () => { onSubmit: (v) => "/" + v, }} > + diff --git a/frontend/src/pages/Settings/Radarr/options.ts b/frontend/src/pages/Settings/Radarr/options.ts new file mode 100644 index 000000000..706e3a4d4 --- /dev/null +++ b/frontend/src/pages/Settings/Radarr/options.ts @@ -0,0 +1,10 @@ +import { SelectorOption } from "@/components"; + +export const timeoutOptions: SelectorOption[] = [ + { label: "60", value: 60 }, + { label: "120", value: 120 }, + { label: "180", value: 180 }, + { label: "240", value: 240 }, + { label: "300", value: 300 }, + { label: "600", value: 600 }, +]; diff --git a/frontend/src/pages/Settings/Sonarr/index.tsx b/frontend/src/pages/Settings/Sonarr/index.tsx index ef2464fd3..1d2125568 100644 --- a/frontend/src/pages/Settings/Sonarr/index.tsx +++ b/frontend/src/pages/Settings/Sonarr/index.tsx @@ -10,12 +10,14 @@ import { Number, PathMappingTable, Section, + Selector, Slider, Text, URLTestButton, } from "../components"; import { seriesEnabledKey } from "../keys"; import { seriesTypeOptions } from "../options"; +import { timeoutOptions } from "./options"; const SettingsSonarrView: FunctionComponent = () => { return ( @@ -37,6 +39,11 @@ const SettingsSonarrView: FunctionComponent = () => { onSubmit: (v) => "/" + v, }} > + diff --git a/frontend/src/pages/Settings/Sonarr/options.ts b/frontend/src/pages/Settings/Sonarr/options.ts new file mode 100644 index 000000000..706e3a4d4 --- /dev/null +++ b/frontend/src/pages/Settings/Sonarr/options.ts @@ -0,0 +1,10 @@ +import { SelectorOption } from "@/components"; + +export const timeoutOptions: SelectorOption[] = [ + { label: "60", value: 60 }, + { label: "120", value: 120 }, + { label: "180", value: 180 }, + { label: "240", value: 240 }, + { label: "300", value: 300 }, + { label: "600", value: 600 }, +];