Skip to content

Commit 94313cd

Browse files
committed
refactor: concistency
1 parent 206582d commit 94313cd

File tree

12 files changed

+76
-65
lines changed

12 files changed

+76
-65
lines changed

cypress/config/settings.cypress.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"trustProxy": false,
2222
"mediaServerType": 1,
2323
"partialRequestsEnabled": true,
24-
"removeUnmonitoredFromRequestsEnabled": false,
24+
"removeUnmonitoredEnabled": false,
2525
"locale": "en"
2626
},
2727
"plex": {

overseerr-api.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ components:
174174
partialRequestsEnabled:
175175
type: boolean
176176
example: false
177-
removeUnmonitoredFromRequestsEnabled:
177+
removeUnmonitoredEnabled:
178178
type: boolean
179179
example: false
180180
localLogin:

server/interfaces/api/settingsInterfaces.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export interface PublicSettingsResponse {
3636
originalLanguage: string;
3737
mediaServerType: number;
3838
partialRequestsEnabled: boolean;
39-
removeUnmonitoredFromRequestsEnabled: boolean;
39+
removeUnmonitoredEnabled: boolean;
4040
cacheImages: boolean;
4141
vapidPublic: string;
4242
enablePushRegistration: boolean;

server/lib/scanners/baseScanner.ts

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
import type { SonarrSeason } from '@server/api/servarr/sonarr';
12
import TheMovieDb from '@server/api/themoviedb';
23
import { MediaStatus, MediaType } from '@server/constants/media';
34
import { getRepository } from '@server/datasource';
45
import Media from '@server/entity/Media';
6+
import { MediaRequest } from '@server/entity/MediaRequest';
57
import Season from '@server/entity/Season';
8+
import SeasonRequest from '@server/entity/SeasonRequest';
69
import { getSettings } from '@server/lib/settings';
710
import logger from '@server/logger';
811
import AsyncLock from '@server/utils/asyncLock';
@@ -212,7 +215,7 @@ class BaseScanner<T> {
212215

213216
/**
214217
* processShow takes a TMDB ID and an array of ProcessableSeasons, which
215-
* should include the total episodes a sesaon has + the total available
218+
* should include the total episodes a season has + the total available
216219
* episodes that each season currently has. Unlike processMovie, this method
217220
* does not take an `is4k` option. We handle both the 4k _and_ non 4k status
218221
* in one method.
@@ -279,13 +282,14 @@ class BaseScanner<T> {
279282
// force it to stay available (to avoid competing scanners)
280283
existingSeason.status =
281284
(season.totalEpisodes === season.episodes && season.episodes > 0) ||
282-
existingSeason.status === MediaStatus.AVAILABLE
285+
(existingSeason.status === MediaStatus.AVAILABLE &&
286+
season.episodes > 0)
283287
? MediaStatus.AVAILABLE
284288
: season.episodes > 0
285289
? MediaStatus.PARTIALLY_AVAILABLE
286290
: !season.is4kOverride && season.processing
287291
? MediaStatus.PROCESSING
288-
: settings.main.removeUnmonitoredFromRequestsEnabled &&
292+
: settings.main.removeUnmonitoredEnabled &&
289293
!season.monitored &&
290294
season.episodes == 0
291295
? MediaStatus.UNKNOWN
@@ -296,13 +300,14 @@ class BaseScanner<T> {
296300
(this.enable4kShow &&
297301
season.episodes4k === season.totalEpisodes &&
298302
season.episodes4k > 0) ||
299-
existingSeason.status4k === MediaStatus.AVAILABLE
303+
(existingSeason.status4k === MediaStatus.AVAILABLE &&
304+
season.episodes > 0)
300305
? MediaStatus.AVAILABLE
301306
: this.enable4kShow && season.episodes4k > 0
302307
? MediaStatus.PARTIALLY_AVAILABLE
303308
: season.is4kOverride && season.processing
304309
? MediaStatus.PROCESSING
305-
: settings.main.removeUnmonitoredFromRequestsEnabled &&
310+
: settings.main.removeUnmonitoredEnabled &&
306311
!season.monitored &&
307312
season.episodes4k == 0
308313
? MediaStatus.UNKNOWN
@@ -316,7 +321,9 @@ class BaseScanner<T> {
316321
? MediaStatus.AVAILABLE
317322
: season.episodes > 0
318323
? MediaStatus.PARTIALLY_AVAILABLE
319-
: !season.is4kOverride && season.processing
324+
: !season.is4kOverride &&
325+
season.processing &&
326+
season.monitored
320327
? MediaStatus.PROCESSING
321328
: MediaStatus.UNKNOWN,
322329
status4k:
@@ -326,7 +333,7 @@ class BaseScanner<T> {
326333
? MediaStatus.AVAILABLE
327334
: this.enable4kShow && season.episodes4k > 0
328335
? MediaStatus.PARTIALLY_AVAILABLE
329-
: season.is4kOverride && season.processing
336+
: season.is4kOverride && season.processing && season.monitored
330337
? MediaStatus.PROCESSING
331338
: MediaStatus.UNKNOWN,
332339
})
@@ -643,6 +650,41 @@ class BaseScanner<T> {
643650
}
644651
});
645652
}
653+
654+
protected async processUnmonitoredSeason(
655+
tmdbId: number,
656+
season: SonarrSeason
657+
): Promise<void> {
658+
// Remove unmonitored seasons from Requests
659+
const requestRepository = getRepository(MediaRequest);
660+
const seasonRequestRepository = getRepository(SeasonRequest);
661+
662+
const existingRequests = await requestRepository
663+
.createQueryBuilder('request')
664+
.innerJoinAndSelect('request.media', 'media')
665+
.innerJoinAndSelect('request.seasons', 'seasons')
666+
.where('media.tmdbId = :tmdbId', { tmdbId: tmdbId })
667+
.andWhere('media.mediaType = :mediaType', {
668+
mediaType: MediaType.TV,
669+
})
670+
.andWhere('seasons.seasonNumber = :seasonNumber', {
671+
seasonNumber: season.seasonNumber,
672+
})
673+
.getMany();
674+
675+
if (existingRequests && existingRequests.length > 0) {
676+
existingRequests.forEach((existingRequest) => {
677+
existingRequest.seasons.forEach(async (requestedSeason) => {
678+
if (requestedSeason.seasonNumber === season.seasonNumber) {
679+
this.log(
680+
`Removing request for Season ${season.seasonNumber} of tmdbId ${tmdbId} as it is unmonitored`
681+
);
682+
await seasonRequestRepository.remove(requestedSeason);
683+
}
684+
});
685+
});
686+
}
687+
}
646688
}
647689

648690
export default BaseScanner;

server/lib/scanners/radarr/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class RadarrScanner
8181
private async processRadarrMovie(radarrMovie: RadarrMovie): Promise<void> {
8282
const settings = getSettings();
8383
if (
84-
settings.main.removeUnmonitoredFromRequestsEnabled &&
84+
settings.main.removeUnmonitoredEnabled &&
8585
!radarrMovie.monitored &&
8686
!radarrMovie.hasFile
8787
) {

server/lib/scanners/sonarr/index.ts

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
import type { SonarrSeries } from '@server/api/servarr/sonarr';
22
import SonarrAPI from '@server/api/servarr/sonarr';
33
import type { TmdbTvDetails } from '@server/api/themoviedb/interfaces';
4-
import { MediaType } from '@server/constants/media';
54
import { getRepository } from '@server/datasource';
65
import Media from '@server/entity/Media';
7-
import { MediaRequest } from '@server/entity/MediaRequest';
8-
import SeasonRequest from '@server/entity/SeasonRequest';
96
import type {
107
ProcessableSeason,
118
RunnableScanner,
@@ -117,39 +114,11 @@ class SonarrScanner
117114
const totalAvailableEpisodes = season.statistics?.episodeFileCount ?? 0;
118115

119116
if (
120-
settings.main.removeUnmonitoredFromRequestsEnabled &&
117+
settings.main.removeUnmonitoredEnabled &&
121118
season.monitored === false &&
122119
totalAvailableEpisodes === 0
123120
) {
124-
// Remove unmonitored seasons from Requests
125-
const requestRepository = getRepository(MediaRequest);
126-
const seasonRequestRepository = getRepository(SeasonRequest);
127-
128-
const existingRequests = await requestRepository
129-
.createQueryBuilder('request')
130-
.innerJoinAndSelect('request.media', 'media')
131-
.innerJoinAndSelect('request.seasons', 'seasons')
132-
.where('media.tmdbId = :tmdbId', { tmdbId: tmdbId })
133-
.andWhere('media.mediaType = :mediaType', {
134-
mediaType: MediaType.TV,
135-
})
136-
.andWhere('seasons.seasonNumber = :seasonNumber', {
137-
seasonNumber: season.seasonNumber,
138-
})
139-
.getMany();
140-
141-
if (existingRequests && existingRequests.length > 0) {
142-
existingRequests.forEach((existingRequest) => {
143-
existingRequest.seasons.forEach(async (requestedSeason) => {
144-
if (requestedSeason.seasonNumber === season.seasonNumber) {
145-
this.log(
146-
`Removing request for Season ${season.seasonNumber} of ${sonarrSeries.title} as it is unmonitored`
147-
);
148-
await seasonRequestRepository.remove(requestedSeason);
149-
}
150-
});
151-
});
152-
}
121+
this.processUnmonitoredSeason(tmdbId, season);
153122
}
154123

155124
processableSeasons.push({

server/lib/settings/index.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ export interface MainSettings {
129129
trustProxy: boolean;
130130
mediaServerType: number;
131131
partialRequestsEnabled: boolean;
132-
removeUnmonitoredFromRequestsEnabled: boolean;
132+
removeUnmonitoredEnabled: boolean;
133133
locale: string;
134134
proxy: ProxySettings;
135135
}
@@ -152,7 +152,7 @@ interface FullPublicSettings extends PublicSettings {
152152
jellyfinForgotPasswordUrl?: string;
153153
jellyfinServerName?: string;
154154
partialRequestsEnabled: boolean;
155-
removeUnmonitoredFromRequestsEnabled: boolean;
155+
removeUnmonitoredEnabled: boolean;
156156
cacheImages: boolean;
157157
vapidPublic: string;
158158
enablePushRegistration: boolean;
@@ -338,7 +338,7 @@ class Settings {
338338
trustProxy: false,
339339
mediaServerType: MediaServerType.NOT_CONFIGURED,
340340
partialRequestsEnabled: true,
341-
removeUnmonitoredFromRequestsEnabled: false,
341+
removeUnmonitoredEnabled: false,
342342
locale: 'en',
343343
proxy: {
344344
enabled: false,
@@ -577,8 +577,7 @@ class Settings {
577577
originalLanguage: this.data.main.originalLanguage,
578578
mediaServerType: this.main.mediaServerType,
579579
partialRequestsEnabled: this.data.main.partialRequestsEnabled,
580-
removeUnmonitoredFromRequestsEnabled:
581-
this.data.main.removeUnmonitoredFromRequestsEnabled,
580+
removeUnmonitoredEnabled: this.data.main.removeUnmonitoredEnabled,
582581
cacheImages: this.data.main.cacheImages,
583582
vapidPublic: this.vapidPublic,
584583
enablePushRegistration: this.data.notifications.agents.webpush.enabled,

src/components/Settings/SettingsMain/index.tsx

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@ const messages = defineMessages('components.Settings.SettingsMain', {
5454
validationApplicationUrl: 'You must provide a valid URL',
5555
validationApplicationUrlTrailingSlash: 'URL must not end in a trailing slash',
5656
partialRequestsEnabled: 'Allow Partial Series Requests',
57-
removeUnmonitoredFromRequestsEnabled:
58-
'Remove Request for Movies/Seasons that have been un-monitored since',
57+
removeUnmonitoredEnabled: 'Remove Unmonitored Media',
58+
removeUnmonitoredExplanation:
59+
'Remove Movies/Seasons from Jellyseerr that are not available and have been un-monitored since',
5960
locale: 'Display Language',
6061
proxyEnabled: 'HTTP(S) Proxy',
6162
proxyHostname: 'Proxy Hostname',
@@ -154,8 +155,7 @@ const SettingsMain = () => {
154155
region: data?.region,
155156
originalLanguage: data?.originalLanguage,
156157
partialRequestsEnabled: data?.partialRequestsEnabled,
157-
removeUnmonitoredFromRequestsEnabled:
158-
data?.removeUnmonitoredFromRequestsEnabled,
158+
removeUnmonitoredEnabled: data?.removeUnmonitoredEnabled,
159159
trustProxy: data?.trustProxy,
160160
cacheImages: data?.cacheImages,
161161
proxyEnabled: data?.proxy?.enabled,
@@ -185,8 +185,7 @@ const SettingsMain = () => {
185185
region: values.region,
186186
originalLanguage: values.originalLanguage,
187187
partialRequestsEnabled: values.partialRequestsEnabled,
188-
removeUnmonitoredFromRequestsEnabled:
189-
values.removeUnmonitoredFromRequestsEnabled,
188+
removeUnmonitoredEnabled: values.removeUnmonitoredEnabled,
190189
trustProxy: values.trustProxy,
191190
cacheImages: values.cacheImages,
192191
proxy: {
@@ -480,24 +479,28 @@ const SettingsMain = () => {
480479
</div>
481480
<div className="form-row">
482481
<label
483-
htmlFor="removeUnmonitoredFromRequestsEnabled"
482+
htmlFor="removeUnmonitoredEnabled"
484483
className="checkbox-label"
485484
>
486485
<span className="mr-2">
486+
{intl.formatMessage(messages.removeUnmonitoredEnabled)}
487+
</span>
488+
<SettingsBadge badgeType="experimental" />
489+
<span className="label-tip">
487490
{intl.formatMessage(
488-
messages.removeUnmonitoredFromRequestsEnabled
491+
messages.removeUnmonitoredExplanation
489492
)}
490493
</span>
491494
</label>
492495
<div className="form-input-area">
493496
<Field
494497
type="checkbox"
495-
id="removeUnmonitoredFromRequestsEnabled"
496-
name="removeUnmonitoredFromRequestsEnabled"
498+
id="removeUnmonitoredEnabled"
499+
name="removeUnmonitoredEnabled"
497500
onChange={() => {
498501
setFieldValue(
499-
'removeUnmonitoredFromRequestsEnabled',
500-
!values.removeUnmonitoredFromRequestsEnabled
502+
'removeUnmonitoredEnabled',
503+
!values.removeUnmonitoredEnabled
501504
);
502505
}}
503506
/>

src/context/SettingsContext.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const defaultSettings = {
2020
originalLanguage: '',
2121
mediaServerType: MediaServerType.NOT_CONFIGURED,
2222
partialRequestsEnabled: true,
23-
removeUnmonitoredFromRequestsEnabled: false,
23+
removeUnmonitoredEnabled: false,
2424
cacheImages: false,
2525
vapidPublic: '',
2626
enablePushRegistration: false,

src/i18n/locale/en.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -885,7 +885,6 @@
885885
"components.Settings.SettingsMain.originallanguage": "Discover Language",
886886
"components.Settings.SettingsMain.originallanguageTip": "Filter content by original language",
887887
"components.Settings.SettingsMain.partialRequestsEnabled": "Allow Partial Series Requests",
888-
"components.Settings.SettingsMain.removeUnmonitoredFromRequestsEnabled": "Remove Request for Movies/Seasons that have been un-monitored since",
889888
"components.Settings.SettingsMain.region": "Discover Region",
890889
"components.Settings.SettingsMain.regionTip": "Filter content by regional availability",
891890
"components.Settings.SettingsMain.toastApiKeyFailure": "Something went wrong while generating a new API key.",

0 commit comments

Comments
 (0)