summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAnderson Shindy Oki <[email protected]>2024-08-27 09:00:44 +0900
committerGitHub <[email protected]>2024-08-27 09:00:44 +0900
commit0e876fcc93b1771934f6816fc5994b7e0efff8ef (patch)
treee8cd75e9e55aa9513819b378a29ed83d167e3ea5
parent855da6b1bb1cbb41d687e4593e2e9d092ed6e273 (diff)
downloadbazarr-0e876fcc93b1771934f6816fc5994b7e0efff8ef.tar.gz
bazarr-0e876fcc93b1771934f6816fc5994b7e0efff8ef.zip
Added sonarr and radarr settings tags validation (#2634)
-rw-r--r--bazarr/app/config.py10
-rw-r--r--frontend/src/pages/Settings/Radarr/index.tsx5
-rw-r--r--frontend/src/pages/Settings/Sonarr/index.tsx5
-rw-r--r--frontend/src/pages/Settings/components/forms.tsx16
4 files changed, 32 insertions, 4 deletions
diff --git a/bazarr/app/config.py b/bazarr/app/config.py
index b0a8c62ba..5e5b5ac04 100644
--- a/bazarr/app/config.py
+++ b/bazarr/app/config.py
@@ -37,6 +37,12 @@ def validate_ip_address(ip_string):
except ValueError:
return False
+def validate_tags(tags):
+ if not tags:
+ return True
+
+ return all(re.match( r'^[a-z0-9_-]+$', item) for item in tags)
+
ONE_HUNDRED_YEARS_IN_MINUTES = 52560000
ONE_HUNDRED_YEARS_IN_HOURS = 876000
@@ -178,7 +184,7 @@ validators = [
Validator('sonarr.only_monitored', must_exist=True, default=False, is_type_of=bool),
Validator('sonarr.series_sync', must_exist=True, default=60, is_type_of=int,
is_in=[15, 60, 180, 360, 720, 1440, 10080, ONE_HUNDRED_YEARS_IN_MINUTES]),
- Validator('sonarr.excluded_tags', must_exist=True, default=[], is_type_of=list),
+ Validator('sonarr.excluded_tags', must_exist=True, default=[], is_type_of=list, condition=validate_tags),
Validator('sonarr.excluded_series_types', must_exist=True, default=[], is_type_of=list),
Validator('sonarr.use_ffprobe_cache', must_exist=True, default=True, is_type_of=bool),
Validator('sonarr.exclude_season_zero', must_exist=True, default=False, is_type_of=bool),
@@ -201,7 +207,7 @@ validators = [
Validator('radarr.only_monitored', must_exist=True, default=False, is_type_of=bool),
Validator('radarr.movies_sync', must_exist=True, default=60, is_type_of=int,
is_in=[15, 60, 180, 360, 720, 1440, 10080, ONE_HUNDRED_YEARS_IN_MINUTES]),
- Validator('radarr.excluded_tags', must_exist=True, default=[], is_type_of=list),
+ Validator('radarr.excluded_tags', must_exist=True, default=[], is_type_of=list, condition=validate_tags),
Validator('radarr.use_ffprobe_cache', must_exist=True, default=True, is_type_of=bool),
Validator('radarr.defer_search_signalr', must_exist=True, default=False, is_type_of=bool),
Validator('radarr.sync_only_monitored_movies', must_exist=True, default=False, is_type_of=bool),
diff --git a/frontend/src/pages/Settings/Radarr/index.tsx b/frontend/src/pages/Settings/Radarr/index.tsx
index b2e858178..264c78924 100644
--- a/frontend/src/pages/Settings/Radarr/index.tsx
+++ b/frontend/src/pages/Settings/Radarr/index.tsx
@@ -54,6 +54,11 @@ const SettingsRadarrView: FunctionComponent = () => {
<Chips
label="Excluded Tags"
settingKey="settings-radarr-excluded_tags"
+ sanitizeFn={(values: string[] | null) =>
+ values?.map((item) =>
+ item.replace(/[^a-z0-9_-]/gi, "").toLowerCase(),
+ )
+ }
></Chips>
<Message>
Movies with those tags (case sensitive) in Radarr will be excluded
diff --git a/frontend/src/pages/Settings/Sonarr/index.tsx b/frontend/src/pages/Settings/Sonarr/index.tsx
index ed66ef679..ff4ac6ca2 100644
--- a/frontend/src/pages/Settings/Sonarr/index.tsx
+++ b/frontend/src/pages/Settings/Sonarr/index.tsx
@@ -56,6 +56,11 @@ const SettingsSonarrView: FunctionComponent = () => {
<Chips
label="Excluded Tags"
settingKey="settings-sonarr-excluded_tags"
+ sanitizeFn={(values: string[] | null) =>
+ values?.map((item) =>
+ item.replace(/[^a-z0-9_-]/gi, "").toLowerCase(),
+ )
+ }
></Chips>
<Message>
Episodes from series with those tags (case sensitive) in Sonarr will
diff --git a/frontend/src/pages/Settings/components/forms.tsx b/frontend/src/pages/Settings/components/forms.tsx
index 95134db92..1e4f744b9 100644
--- a/frontend/src/pages/Settings/components/forms.tsx
+++ b/frontend/src/pages/Settings/components/forms.tsx
@@ -160,13 +160,25 @@ export const Slider: FunctionComponent<SliderProps> = (props) => {
};
type ChipsProp = BaseInput<string[]> &
- Omit<ChipInputProps, "onChange" | "data">;
+ Omit<ChipInputProps, "onChange" | "data"> & {
+ sanitizeFn?: (values: string[] | null) => string[] | undefined;
+ };
export const Chips: FunctionComponent<ChipsProp> = (props) => {
const { value, update, rest } = useBaseInput(props);
+ const handleChange = (value: string[] | null) => {
+ const sanitizedValues = props.sanitizeFn?.(value) ?? value;
+
+ update(sanitizedValues || null);
+ };
+
return (
- <ChipInput {...rest} value={value ?? []} onChange={update}></ChipInput>
+ <ChipInput
+ {...rest}
+ value={value ?? []}
+ onChange={handleChange}
+ ></ChipInput>
);
};