From 814a7357c0c7418091e8d3e911adc403811c9dfe Mon Sep 17 00:00:00 2001 From: Fallenbagel <98979876+Fallenbagel@users.noreply.github.com> Date: Mon, 30 Dec 2024 20:14:29 +0800 Subject: [PATCH 1/2] fix: properly fetch sonarr/radarr specific override rules (#1199) * fix: properly fetch sonarr/radarr specific override rules and fix its application - This will fetch the proper sonarr/radarr specific override rule to apply. - This will skip override rules for anime TV shows unless the `overrideRule` explicitly includes the anime keyword. - Apply the most specific override rule first (e.g., rules with multiple conditions like `genre`, `language`, and `keywords`) - Debug logs to for override rules * fix(overriderules): apply overrides to "auto_approve" permission users but not "advaned_request" This decision is done because it makes no sense to give advanced request users who gets to choose what values to choose but then the minute they request, it gets overridden, rendering the whole modal completely useless. In addition, admin/manage_request permission users who modify requests, the minute they modify it will get overridden as well so it makes no sense to override their requests * fix: use default service instance for override rules --------- Co-authored-by: Gauthier --- server/entity/MediaRequest.ts | 111 +++++++++++++++++++++++++--------- 1 file changed, 81 insertions(+), 30 deletions(-) diff --git a/server/entity/MediaRequest.ts b/server/entity/MediaRequest.ts index 3c1524de4..9cabd9435 100644 --- a/server/entity/MediaRequest.ts +++ b/server/entity/MediaRequest.ts @@ -7,6 +7,7 @@ import type { import SonarrAPI from '@server/api/servarr/sonarr'; import TheMovieDb from '@server/api/themoviedb'; import { ANIME_KEYWORD_ID } from '@server/api/themoviedb/constants'; +import type { TmdbKeyword } from '@server/api/themoviedb/interfaces'; import { MediaRequestStatus, MediaStatus, @@ -207,28 +208,50 @@ export class MediaRequest { } } - // Apply overrides if the user is not an admin or has the "auto approve" permission - const useOverrides = !user.hasPermission( - [ - requestBody.is4k ? Permission.AUTO_APPROVE_4K : Permission.AUTO_APPROVE, - Permission.MANAGE_REQUESTS, - ], - { type: 'or' } - ); + // Apply overrides if the user is not an admin or has the "advanced request" permission + const useOverrides = !user.hasPermission([Permission.MANAGE_REQUESTS], { + type: 'or', + }); let rootFolder = requestBody.rootFolder; let profileId = requestBody.profileId; let tags = requestBody.tags; if (useOverrides) { + const defaultRadarrId = requestBody.is4k + ? settings.radarr.findIndex((r) => r.is4k && r.isDefault) + : settings.radarr.findIndex((r) => !r.is4k && r.isDefault); + const defaultSonarrId = requestBody.is4k + ? settings.sonarr.findIndex((s) => s.is4k && s.isDefault) + : settings.sonarr.findIndex((s) => !s.is4k && s.isDefault); + const overrideRuleRepository = getRepository(OverrideRule); const overrideRules = await overrideRuleRepository.find({ where: requestBody.mediaType === MediaType.MOVIE - ? { radarrServiceId: requestBody.serverId } - : { sonarrServiceId: requestBody.serverId }, + ? { radarrServiceId: defaultRadarrId } + : { sonarrServiceId: defaultSonarrId }, }); + const appliedOverrideRules = overrideRules.filter((rule) => { + const hasAnimeKeyword = + 'results' in tmdbMedia.keywords && + tmdbMedia.keywords.results.some( + (keyword: TmdbKeyword) => keyword.id === ANIME_KEYWORD_ID + ); + + // Skip override rules if the media is an anime TV show as anime TV + // is handled by default and override rules do not explicitly include + // the anime keyword + if ( + requestBody.mediaType === MediaType.TV && + hasAnimeKeyword && + (!rule.keywords || + !rule.keywords.split(',').map(Number).includes(ANIME_KEYWORD_ID)) + ) { + return false; + } + if ( rule.users && !rule.users @@ -257,31 +280,59 @@ export class MediaRequest { ) { return false; } + if ( + rule.keywords && + !rule.keywords.split(',').some((keywordId) => { + let keywordList: TmdbKeyword[] = []; + + if ('keywords' in tmdbMedia.keywords) { + keywordList = tmdbMedia.keywords.keywords; + } else if ('results' in tmdbMedia.keywords) { + keywordList = tmdbMedia.keywords.results; + } + + return keywordList + .map((keyword: TmdbKeyword) => keyword.id) + .includes(Number(keywordId)); + }) + ) { + return false; + } return true; }); - const overrideRootFolder = appliedOverrideRules.find( - (rule) => rule.rootFolder - )?.rootFolder; - if (overrideRootFolder) { - rootFolder = overrideRootFolder; - } + // hacky way to prioritize rules + // TODO: make this better + const prioritizedRule = appliedOverrideRules.sort((a, b) => { + const keys: (keyof OverrideRule)[] = ['genre', 'language', 'keywords']; - const overrideProfileId = appliedOverrideRules.find( - (rule) => rule.profileId - )?.profileId; - if (overrideProfileId) { - profileId = overrideProfileId; - } + const aSpecificity = keys.filter((key) => a[key] !== null).length; + const bSpecificity = keys.filter((key) => b[key] !== null).length; - const overrideTags = appliedOverrideRules.find((rule) => rule.tags)?.tags; - if (overrideTags) { - tags = [ - ...new Set([ - ...(tags || []), - ...overrideTags.split(',').map((tag) => Number(tag)), - ]), - ]; + // Take the rule with the most specific condition first + return bSpecificity - aSpecificity; + })[0]; + + if (prioritizedRule) { + if (prioritizedRule.rootFolder) { + rootFolder = prioritizedRule.rootFolder; + } + if (prioritizedRule.profileId) { + profileId = prioritizedRule.profileId; + } + if (prioritizedRule.tags) { + tags = [ + ...new Set([ + ...(tags || []), + ...prioritizedRule.tags.split(',').map((tag) => Number(tag)), + ]), + ]; + } + + logger.debug('Override rule applied.', { + label: 'Media Request', + overrides: prioritizedRule, + }); } } From 7e94ad721026a03d3ae640ee2deb60e321cabf10 Mon Sep 17 00:00:00 2001 From: Gauthier Date: Mon, 30 Dec 2024 14:45:51 +0100 Subject: [PATCH 2/2] fix(usersettings): fix the streaming region setting toggling itself (#1203) When the streaming region is set to another value than the default one, the setting starts toggling itself from the default value to the new value and vice-versa constantly fix #1200 --- src/components/Settings/SettingsMain/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Settings/SettingsMain/index.tsx b/src/components/Settings/SettingsMain/index.tsx index 07a974b56..1ad6109bd 100644 --- a/src/components/Settings/SettingsMain/index.tsx +++ b/src/components/Settings/SettingsMain/index.tsx @@ -157,7 +157,7 @@ const SettingsMain = () => { locale: data?.locale ?? 'en', discoverRegion: data?.discoverRegion, originalLanguage: data?.originalLanguage, - streamingRegion: data?.streamingRegion, + streamingRegion: data?.streamingRegion || 'US', partialRequestsEnabled: data?.partialRequestsEnabled, enableSpecialEpisodes: data?.enableSpecialEpisodes, trustProxy: data?.trustProxy, @@ -451,7 +451,7 @@ const SettingsMain = () => {