Skip to content

Commit 0d8627a

Browse files
committed
feat(radarr-scanner): remove unmonitored movies from "requests"
1 parent c86ee0d commit 0d8627a

File tree

11 files changed

+72
-9
lines changed

11 files changed

+72
-9
lines changed

cypress/config/settings.cypress.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"blacklistedTagsLimit": 50,
2424
"trustProxy": false,
2525
"mediaServerType": 1,
26+
"removeUnmonitoredEnabled": false,
2627
"partialRequestsEnabled": true,
2728
"enableSpecialEpisodes": false,
2829
"locale": "en"

jellyseerr-api.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ components:
239239
partialRequestsEnabled:
240240
type: boolean
241241
example: false
242+
removeUnmonitoredEnabled:
243+
type: boolean
244+
example: false
242245
localLogin:
243246
type: boolean
244247
example: true

publish.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#/bin/sh
2+
COMMIT_TAG=`git rev-parse HEAD`
3+
docker build --build-arg COMMIT_TAG=${COMMIT_TAG} -t bonswouar/jellyseerr -f Dockerfile . && docker push bonswouar/jellyseerr

server/interfaces/api/settingsInterfaces.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export interface PublicSettingsResponse {
4040
mediaServerType: number;
4141
partialRequestsEnabled: boolean;
4242
enableSpecialEpisodes: boolean;
43+
removeUnmonitoredEnabled: boolean;
4344
cacheImages: boolean;
4445
vapidPublic: string;
4546
enablePushRegistration: boolean;

server/lib/scanners/baseScanner.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ class BaseScanner<T> {
211211

212212
/**
213213
* processShow takes a TMDB ID and an array of ProcessableSeasons, which
214-
* should include the total episodes a sesaon has + the total available
214+
* should include the total episodes a season has + the total available
215215
* episodes that each season currently has. Unlike processMovie, this method
216216
* does not take an `is4k` option. We handle both the 4k _and_ non 4k status
217217
* in one method.
@@ -639,6 +639,21 @@ class BaseScanner<T> {
639639
get protectedBundleSize(): number {
640640
return this.bundleSize;
641641
}
642+
643+
protected async processUnmonitoredMovie(tmdbId: number): Promise<void> {
644+
const mediaRepository = getRepository(Media);
645+
await this.asyncLock.dispatch(tmdbId, async () => {
646+
const existing = await this.getExisting(tmdbId, MediaType.MOVIE);
647+
if (existing && existing.status === MediaStatus.PROCESSING) {
648+
existing.status = MediaStatus.UNKNOWN;
649+
await mediaRepository.save(existing);
650+
this.log(
651+
`Movie TMDB ID ${tmdbId} unmonitored from Radarr. Media status set to UNKNOWN.`,
652+
'info'
653+
);
654+
}
655+
});
656+
}
642657
}
643658

644659
export default BaseScanner;

server/lib/scanners/radarr/index.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,13 @@ class RadarrScanner
7979
}
8080

8181
private async processRadarrMovie(radarrMovie: RadarrMovie): Promise<void> {
82-
if (!radarrMovie.monitored && !radarrMovie.hasFile) {
83-
this.log(
84-
'Title is unmonitored and has not been downloaded. Skipping item.',
85-
'debug',
86-
{
87-
title: radarrMovie.title,
88-
}
89-
);
82+
const settings = getSettings();
83+
if (
84+
settings.main.removeUnmonitoredEnabled &&
85+
!radarrMovie.monitored &&
86+
!radarrMovie.hasFile
87+
) {
88+
this.processUnmonitoredMovie(radarrMovie.tmdbId);
9089
return;
9190
}
9291

server/lib/settings/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ export interface MainSettings {
134134
mediaServerType: number;
135135
partialRequestsEnabled: boolean;
136136
enableSpecialEpisodes: boolean;
137+
removeUnmonitoredEnabled: boolean;
137138
locale: string;
138139
youtubeUrl: string;
139140
}
@@ -167,6 +168,7 @@ interface FullPublicSettings extends PublicSettings {
167168
jellyfinServerName?: string;
168169
partialRequestsEnabled: boolean;
169170
enableSpecialEpisodes: boolean;
171+
removeUnmonitoredEnabled: boolean;
170172
cacheImages: boolean;
171173
vapidPublic: string;
172174
enablePushRegistration: boolean;
@@ -369,6 +371,7 @@ class Settings {
369371
mediaServerType: MediaServerType.NOT_CONFIGURED,
370372
partialRequestsEnabled: true,
371373
enableSpecialEpisodes: false,
374+
removeUnmonitoredEnabled: false,
372375
locale: 'en',
373376
youtubeUrl: '',
374377
},
@@ -628,6 +631,7 @@ class Settings {
628631
mediaServerType: this.main.mediaServerType,
629632
partialRequestsEnabled: this.data.main.partialRequestsEnabled,
630633
enableSpecialEpisodes: this.data.main.enableSpecialEpisodes,
634+
removeUnmonitoredEnabled: this.data.main.removeUnmonitoredEnabled,
631635
cacheImages: this.data.main.cacheImages,
632636
vapidPublic: this.vapidPublic,
633637
enablePushRegistration: this.data.notifications.agents.webpush.enabled,

src/components/Settings/SettingsMain/index.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ const messages = defineMessages('components.Settings.SettingsMain', {
6464
validationApplicationUrlTrailingSlash: 'URL must not end in a trailing slash',
6565
partialRequestsEnabled: 'Allow Partial Series Requests',
6666
enableSpecialEpisodes: 'Allow Special Episodes Requests',
67+
removeUnmonitoredEnabled: 'Remove Unmonitored Media',
68+
removeUnmonitoredExplanation:
69+
'Remove Movies/Seasons from Jellyseerr that are not available and have been un-monitored since',
6770
locale: 'Display Language',
6871
youtubeUrl: 'YouTube URL',
6972
youtubeUrlTip:
@@ -175,6 +178,7 @@ const SettingsMain = () => {
175178
enableSpecialEpisodes: data?.enableSpecialEpisodes,
176179
cacheImages: data?.cacheImages,
177180
youtubeUrl: data?.youtubeUrl,
181+
removeUnmonitoredEnabled: data?.removeUnmonitoredEnabled,
178182
}}
179183
enableReinitialize
180184
validationSchema={MainSettingsSchema}
@@ -195,6 +199,7 @@ const SettingsMain = () => {
195199
enableSpecialEpisodes: values.enableSpecialEpisodes,
196200
cacheImages: values.cacheImages,
197201
youtubeUrl: values.youtubeUrl,
202+
removeUnmonitoredEnabled: values.removeUnmonitoredEnabled,
198203
});
199204
mutate('/api/v1/settings/public');
200205
mutate('/api/v1/status');
@@ -535,6 +540,35 @@ const SettingsMain = () => {
535540
/>
536541
</div>
537542
</div>
543+
<div className="form-row">
544+
<label
545+
htmlFor="removeUnmonitoredEnabled"
546+
className="checkbox-label"
547+
>
548+
<span className="mr-2">
549+
{intl.formatMessage(messages.removeUnmonitoredEnabled)}
550+
</span>
551+
<SettingsBadge badgeType="experimental" />
552+
<span className="label-tip">
553+
{intl.formatMessage(
554+
messages.removeUnmonitoredExplanation
555+
)}
556+
</span>
557+
</label>
558+
<div className="form-input-area">
559+
<Field
560+
type="checkbox"
561+
id="removeUnmonitoredEnabled"
562+
name="removeUnmonitoredEnabled"
563+
onChange={() => {
564+
setFieldValue(
565+
'removeUnmonitoredEnabled',
566+
!values.removeUnmonitoredEnabled
567+
);
568+
}}
569+
/>
570+
</div>
571+
</div>
538572
<div className="form-row">
539573
<label htmlFor="youtubeUrl" className="text-label">
540574
{intl.formatMessage(messages.youtubeUrl)}

src/context/SettingsContext.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const defaultSettings = {
2424
mediaServerType: MediaServerType.NOT_CONFIGURED,
2525
partialRequestsEnabled: true,
2626
enableSpecialEpisodes: false,
27+
removeUnmonitoredEnabled: false,
2728
cacheImages: false,
2829
vapidPublic: '',
2930
enablePushRegistration: false,

src/i18n/locale/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,7 @@
955955
"components.Settings.SettingsMain.partialRequestsEnabled": "Allow Partial Series Requests",
956956
"components.Settings.SettingsMain.streamingRegion": "Streaming Region",
957957
"components.Settings.SettingsMain.streamingRegionTip": "Show streaming sites by regional availability",
958+
"components.Settings.SettingsMain.removeUnmonitoredFromRequestsEnabled": "Remove Request for Movies/Seasons that have been un-monitored since",
958959
"components.Settings.SettingsMain.toastApiKeyFailure": "Something went wrong while generating a new API key.",
959960
"components.Settings.SettingsMain.toastApiKeySuccess": "New API key generated successfully!",
960961
"components.Settings.SettingsMain.toastSettingsFailure": "Something went wrong while saving settings.",

0 commit comments

Comments
 (0)