From 4ed0ac6e6bd4fc4d714de222e4fc934cca8cc695 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Fri, 25 Nov 2022 16:26:23 +0000 Subject: [PATCH] think i did it --- src/Ombi.Api.Radarr/IRadarrV3Api.cs | 6 +- .../Models/V2/RadarrAddMovie.cs | 1 + src/Ombi.Api.Radarr/RadarrV3Api.cs | 14 +- src/Ombi.Core/Senders/MovieSender.cs | 31 ++- .../Models/External/RadarrSettings.cs | 2 + .../Models/External/SonarrSettings.cs | 2 +- .../card/discover-card.component.ts | 2 +- .../ClientApp/src/app/interfaces/ISettings.ts | 2 + .../movie/movie-details.component.ts | 2 +- .../tv-request-grid.component.ts | 2 +- .../services/applications/radarr.service.ts | 12 +- .../components/radarr-form.component.html | 20 ++ .../components/radarr-form.component.ts | 30 ++- .../app/settings/radarr/radarr.component.ts | 18 +- .../app/settings/sonarr/sonarr.component.html | 2 +- .../admin-request-dialog.component.html | 36 +-- .../admin-request-dialog.component.ts | 225 ++++++++++-------- .../episode-request.component.ts | 2 +- .../V1/External/RadarrController.cs | 46 +++- 19 files changed, 309 insertions(+), 146 deletions(-) diff --git a/src/Ombi.Api.Radarr/IRadarrV3Api.cs b/src/Ombi.Api.Radarr/IRadarrV3Api.cs index 072e8ef51..0b91b4925 100644 --- a/src/Ombi.Api.Radarr/IRadarrV3Api.cs +++ b/src/Ombi.Api.Radarr/IRadarrV3Api.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Threading.Tasks; using Ombi.Api.Radarr.Models; using Ombi.Api.Radarr.Models.V3; @@ -14,7 +15,8 @@ namespace Ombi.Api.Radarr Task GetMovie(int id, string apiKey, string baseUrl); Task UpdateMovie(MovieResponse movie, string apiKey, string baseUrl); Task MovieSearch(int[] movieIds, string apiKey, string baseUrl); - Task AddMovie(int tmdbId, string title, int year, int qualityId, string rootPath,string apiKey, string baseUrl, bool searchNow, string minimumAvailability); + Task AddMovie(int tmdbId, string title, int year, int qualityId, string rootPath,string apiKey, string baseUrl, bool searchNow, string minimumAvailability, List tags); Task> GetTags(string apiKey, string baseUrl); + Task CreateTag(string apiKey, string baseUrl, string tagName); } } \ No newline at end of file diff --git a/src/Ombi.Api.Radarr/Models/V2/RadarrAddMovie.cs b/src/Ombi.Api.Radarr/Models/V2/RadarrAddMovie.cs index 09e985f43..9efea8ee1 100644 --- a/src/Ombi.Api.Radarr/Models/V2/RadarrAddMovie.cs +++ b/src/Ombi.Api.Radarr/Models/V2/RadarrAddMovie.cs @@ -29,5 +29,6 @@ namespace Ombi.Api.Radarr.Models public int year { get; set; } public string minimumAvailability { get; set; } public long sizeOnDisk { get; set; } + public int[] tags { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Api.Radarr/RadarrV3Api.cs b/src/Ombi.Api.Radarr/RadarrV3Api.cs index 9e7e0f4c2..76656be65 100644 --- a/src/Ombi.Api.Radarr/RadarrV3Api.cs +++ b/src/Ombi.Api.Radarr/RadarrV3Api.cs @@ -72,7 +72,7 @@ namespace Ombi.Api.Radarr return await Api.Request(request); } - public async Task AddMovie(int tmdbId, string title, int year, int qualityId, string rootPath, string apiKey, string baseUrl, bool searchNow, string minimumAvailability) + public async Task AddMovie(int tmdbId, string title, int year, int qualityId, string rootPath, string apiKey, string baseUrl, bool searchNow, string minimumAvailability, List tags) { var request = new Request("/api/v3/movie", baseUrl, HttpMethod.Post); @@ -86,7 +86,8 @@ namespace Ombi.Api.Radarr monitored = true, year = year, minimumAvailability = minimumAvailability, - sizeOnDisk = 0 + sizeOnDisk = 0, + tags = tags.Any() ? tags.ToArray() : Enumerable.Empty().ToArray() }; if (searchNow) @@ -156,5 +157,14 @@ namespace Ombi.Api.Radarr { request.AddHeader("X-Api-Key", key); } + + public Task CreateTag(string apiKey, string baseUrl, string tagName) + { + var request = new Request($"/api/v3/tag", baseUrl, HttpMethod.Post); + request.AddHeader("X-Api-Key", apiKey); + request.AddJsonBody(new { Label = tagName }); + + return Api.Request(request); + } } } diff --git a/src/Ombi.Core/Senders/MovieSender.cs b/src/Ombi.Core/Senders/MovieSender.cs index 36d40bdad..f6907e2f5 100644 --- a/src/Ombi.Core/Senders/MovieSender.cs +++ b/src/Ombi.Core/Senders/MovieSender.cs @@ -15,6 +15,8 @@ using Ombi.Store.Entities; using Ombi.Store.Repository; using System.Collections.Generic; using Ombi.Api.Radarr.Models; +using Microsoft.Extensions.Options; +using Ombi.Api.Sonarr; namespace Ombi.Core.Senders { @@ -67,7 +69,7 @@ namespace Ombi.Core.Senders } if (radarrSettings.Enabled) { - return await SendToRadarr(model, is4K, radarrSettings); + return await SendToRadarr(model, radarrSettings); } var dogSettings = await _dogNzbSettings.GetSettingsAsync(); @@ -131,7 +133,7 @@ namespace Ombi.Core.Senders return await _dogNzbApi.AddMovie(settings.ApiKey, id); } - private async Task SendToRadarr(MovieRequests model, bool is4K, RadarrSettings settings) + private async Task SendToRadarr(MovieRequests model, RadarrSettings settings) { var qualityToUse = int.Parse(settings.DefaultQualityProfile); @@ -154,6 +156,17 @@ namespace Ombi.Core.Senders } } + var tags = new List(); + if (settings.Tag.HasValue) + { + tags.Add(settings.Tag.Value); + } + if (settings.SendUserTags) + { + var userTag = await GetOrCreateTag(model, settings); + tags.Add(userTag.id); + } + // Overrides on the request take priority if (model.QualityOverride > 0) { @@ -174,7 +187,7 @@ namespace Ombi.Core.Senders { var result = await _radarrV3Api.AddMovie(model.TheMovieDbId, model.Title, model.ReleaseDate.Year, qualityToUse, rootFolderPath, settings.ApiKey, settings.FullUri, !settings.AddOnly, - settings.MinimumAvailability); + settings.MinimumAvailability, tags); if (!string.IsNullOrEmpty(result.Error?.message)) { @@ -212,5 +225,17 @@ namespace Ombi.Core.Senders var selectedPath = paths.FirstOrDefault(x => x.id == overrideId); return selectedPath?.path ?? string.Empty; } + + private async Task GetOrCreateTag(MovieRequests model, RadarrSettings s) + { + var tagName = model.RequestedUser.UserName; + // Does tag exist? + + var allTags = await _radarrV3Api.GetTags(s.ApiKey, s.FullUri); + var existingTag = allTags.FirstOrDefault(x => x.label.Equals(tagName, StringComparison.InvariantCultureIgnoreCase)); + existingTag ??= await _radarrV3Api.CreateTag(s.ApiKey, s.FullUri, tagName); + + return existingTag; + } } } \ No newline at end of file diff --git a/src/Ombi.Settings/Settings/Models/External/RadarrSettings.cs b/src/Ombi.Settings/Settings/Models/External/RadarrSettings.cs index 1b3e0982f..1791761c5 100644 --- a/src/Ombi.Settings/Settings/Models/External/RadarrSettings.cs +++ b/src/Ombi.Settings/Settings/Models/External/RadarrSettings.cs @@ -9,6 +9,8 @@ public bool AddOnly { get; set; } public string MinimumAvailability { get; set; } public bool ScanForAvailability { get; set; } + public int? Tag { get; set; } + public bool SendUserTags { get; set; } } public class Radarr4KSettings : RadarrSettings diff --git a/src/Ombi.Settings/Settings/Models/External/SonarrSettings.cs b/src/Ombi.Settings/Settings/Models/External/SonarrSettings.cs index 8e0b37524..332d97357 100644 --- a/src/Ombi.Settings/Settings/Models/External/SonarrSettings.cs +++ b/src/Ombi.Settings/Settings/Models/External/SonarrSettings.cs @@ -19,11 +19,11 @@ public string RootPathAnime { get; set; } public int? AnimeTag { get; set; } public int? Tag { get; set; } + public bool SendUserTags { get; set; } public bool AddOnly { get; set; } public int LanguageProfile { get; set; } public int LanguageProfileAnime { get; set; } public bool ScanForAvailability { get; set; } - public bool SendUserTags { get; set; } } } \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts index c7348e91c..f524c168a 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts +++ b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts @@ -157,7 +157,7 @@ export class DiscoverCardComponent implements OnInit { AdminRequestDialogComponent, { width: "700px", - data: { type: RequestType.movie, id: this.result.id }, + data: { type: RequestType.movie, id: this.result.id, is4k: is4k }, panelClass: "modal-panel", } ); diff --git a/src/Ombi/ClientApp/src/app/interfaces/ISettings.ts b/src/Ombi/ClientApp/src/app/interfaces/ISettings.ts index cd7956fdd..759cdeb73 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/ISettings.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/ISettings.ts @@ -160,6 +160,8 @@ export interface IRadarrSettings extends IExternalSettings { addOnly: boolean; minimumAvailability: string; scanForAvailability: boolean; + tag: number | null; + sendUserTags: boolean; } export interface IRadarrCombined { diff --git a/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts b/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts index 0479858a7..5d5de3ee4 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts +++ b/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts @@ -111,7 +111,7 @@ export class MovieDetailsComponent implements OnInit{ is4K = false; } if (this.isAdmin) { - const dialog = this.dialog.open(AdminRequestDialogComponent, { width: "700px", data: { type: RequestType.movie, id: this.movie.id }, panelClass: 'modal-panel' }); + const dialog = this.dialog.open(AdminRequestDialogComponent, { width: "700px", data: { type: RequestType.movie, id: this.movie.id, is4K: is4K }, panelClass: 'modal-panel' }); dialog.afterClosed().subscribe(async (result) => { if (result) { const requestResult = await firstValueFrom(this.requestService.requestMovie({ theMovieDbId: this.theMovidDbId, diff --git a/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-request-grid/tv-request-grid.component.ts b/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-request-grid/tv-request-grid.component.ts index bac88756e..24bbbe77b 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-request-grid/tv-request-grid.component.ts +++ b/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-request-grid/tv-request-grid.component.ts @@ -62,7 +62,7 @@ export class TvRequestGridComponent { }); if (this.isAdmin) { - const dialog = this.dialog.open(AdminRequestDialogComponent, { width: "700px", data: { type: RequestType.tvShow, id: this.tv.id }, panelClass: 'modal-panel' }); + const dialog = this.dialog.open(AdminRequestDialogComponent, { width: "700px", data: { type: RequestType.tvShow, id: this.tv.id, is4k: null }, panelClass: 'modal-panel' }); dialog.afterClosed().subscribe(async (result) => { if (result) { viewModel.requestOnBehalf = result.username?.id; diff --git a/src/Ombi/ClientApp/src/app/services/applications/radarr.service.ts b/src/Ombi/ClientApp/src/app/services/applications/radarr.service.ts index 33db4f72e..711607f8e 100644 --- a/src/Ombi/ClientApp/src/app/services/applications/radarr.service.ts +++ b/src/Ombi/ClientApp/src/app/services/applications/radarr.service.ts @@ -28,15 +28,23 @@ export class RadarrService extends ServiceHelpers { return this.http.get(`${this.url}/Profiles/`, { headers: this.headers }); } + public getRootFolders4kFromSettings(): Observable { + return this.http.get(`${this.url}/RootFolders/4k`, { headers: this.headers }); + } + + public getQualityProfiles4kFromSettings(): Observable { + return this.http.get(`${this.url}/Profiles/4k`, { headers: this.headers }); + } + public isRadarrEnabled(): Observable { return this.http.get(`${this.url}/enabled/`, { headers: this.headers }); } public getTagsWithSettings(settings: IRadarrSettings): Observable { - return this.http.post(`${this.url}/enabled/`, JSON.stringify(settings), { headers: this.headers }); + return this.http.post(`${this.url}/tags/`, JSON.stringify(settings), { headers: this.headers }); } public getTags(): Observable { - return this.http.get(`${this.url}/enabled/`, { headers: this.headers }) + return this.http.get(`${this.url}/tags/`, { headers: this.headers }) } } diff --git a/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.html b/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.html index 2dbf6869d..b3264b109 100644 --- a/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.html +++ b/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.html @@ -8,6 +8,10 @@
Scan for Availability
+
+ Add the user as a tag +
This will add the username of the requesting user as a tag in Sonarr. If the tag doesn't exist, Ombi will create it.
+
Do not search for Movies @@ -79,6 +83,22 @@
+
+
+ +
+
+ + Tag + + + {{tag.label}} + + + + +
+
Default Minimum Availability diff --git a/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.ts b/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.ts index 1dbceead8..a4f12760f 100644 --- a/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.ts @@ -1,7 +1,8 @@ import { ChangeDetectionStrategy, Component, OnInit } from "@angular/core"; import { ControlContainer, UntypedFormGroup, Validators } from "@angular/forms"; +import { finalize, map } from "rxjs"; -import { IMinimumAvailability, IRadarrProfile, IRadarrRootFolder, IRadarrSettings } from "../../../interfaces"; +import { IMinimumAvailability, IRadarrProfile, IRadarrRootFolder, IRadarrSettings, ITag } from "../../../interfaces"; import { TesterService, NotificationService, RadarrService } from "../../../services"; @@ -16,8 +17,10 @@ export class RadarrFormComponent implements OnInit { public qualities: IRadarrProfile[]; public rootFolders: IRadarrRootFolder[]; public minimumAvailabilityOptions: IMinimumAvailability[]; + public tags: ITag[]; public profilesRunning: boolean; public rootFoldersRunning: boolean; + public tagsRunning: boolean; public form: UntypedFormGroup; constructor(private radarrService: RadarrService, @@ -34,6 +37,10 @@ export class RadarrFormComponent implements OnInit { this.rootFolders = []; this.rootFolders.push({ path: "Please Select", id: -1 }); + + this.tags = []; + this.tags.push({ label: "None", id: -1 }); + this.minimumAvailabilityOptions = [ { name: "Announced", value: "Announced" }, { name: "In Cinemas", value: "InCinemas" }, @@ -47,9 +54,16 @@ export class RadarrFormComponent implements OnInit { if (this.form.controls.defaultRootPath.value) { this.getRootFolders(this.form); } + + if (this.form.controls.tag.value) { + this.getTags(this.form); + } + + this.toggleValidators(); } public toggleValidators() { + debugger; const enabled = this.form.controls.enabled.value as boolean; this.form.controls.apiKey.setValidators(enabled ? [Validators.required] : null); this.form.controls.defaultQualityProfile.setValidators(enabled ? [Validators.required] : null); @@ -81,6 +95,20 @@ export class RadarrFormComponent implements OnInit { }); } + public getTags(form: UntypedFormGroup) { + this.tagsRunning = true; + this.radarrService.getTagsWithSettings(form.value).pipe( + finalize(() => { + this.tagsRunning = false; + this.tags.unshift({ label: "None", id: -1 }); + this.notificationService.success("Successfully retrieved the Tags"); + }), + map(result => { + this.tags = result; + }) + ).subscribe() + } + public test(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); diff --git a/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.ts b/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.ts index 14b1c56b2..869de4856 100644 --- a/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.ts @@ -40,6 +40,8 @@ export class RadarrComponent implements OnInit { apiKey: [x.settings.radarr.apiKey], defaultQualityProfile: [+x.settings.radarr.defaultQualityProfile], defaultRootPath: [x.settings.radarr.defaultRootPath], + tag: [x.settings.radarr.tag], + sendUserTags: [x.settings.radarr.sendUserTags], ssl: [x.settings.radarr.ssl], subDir: [x.settings.radarr.subDir], ip: [x.settings.radarr.ip], @@ -53,6 +55,8 @@ export class RadarrComponent implements OnInit { apiKey: [x.settings.radarr4K.apiKey], defaultQualityProfile: [+x.settings.radarr4K.defaultQualityProfile], defaultRootPath: [x.settings.radarr4K.defaultRootPath], + tag: [x.settings.radarr4K.tag], + sendUserTags: [x.settings.radarr4K.sendUserTags], ssl: [x.settings.radarr4K.ssl], subDir: [x.settings.radarr4K.subDir], ip: [x.settings.radarr4K.ip], @@ -71,7 +75,6 @@ export class RadarrComponent implements OnInit { })) } }); - } @@ -83,15 +86,24 @@ export class RadarrComponent implements OnInit { const radarrForm = form.controls.radarr as UntypedFormGroup; const radarr4KForm = form.controls.radarr4K as UntypedFormGroup; - if (radarrForm.controls.enabled.value && (radarrForm.controls.defaultQualityProfile.value === -1 || radarrForm.controls.defaultRootPath.value === "Please Select")) { + if (radarrForm.controls.enabled.value && (radarrForm.controls.defaultQualityProfile.value === -1 + || radarrForm.controls.defaultRootPath.value === "Please Select")) { this.notificationService.error("Please check your entered values for Radarr"); return; } - if (radarr4KForm.controls.enabled.value && (radarr4KForm.controls.defaultQualityProfile.value === -1 || radarr4KForm.controls.defaultRootPath.value === "Please Select")) { + if (radarr4KForm.controls.enabled.value && (radarr4KForm.controls.defaultQualityProfile.value === -1 + || radarr4KForm.controls.defaultRootPath.value === "Please Select")) { this.notificationService.error("Please check your entered values for Radarr 4K"); return; } + if (radarr4KForm.controls.tag.value === -1) { + radarr4KForm.controls.tag.setValue(null); + } + if (radarrForm.controls.tag.value === -1) { + radarr4KForm.controls.tag.setValue(null); + } + const settings = form.value; this.radarrFacade.updateSettings(settings).subscribe(x => { if (x) { diff --git a/src/Ombi/ClientApp/src/app/settings/sonarr/sonarr.component.html b/src/Ombi/ClientApp/src/app/settings/sonarr/sonarr.component.html index fc85de648..27d1b6053 100644 --- a/src/Ombi/ClientApp/src/app/settings/sonarr/sonarr.component.html +++ b/src/Ombi/ClientApp/src/app/settings/sonarr/sonarr.component.html @@ -138,7 +138,7 @@
- Default Tag + Tag {{tag.label}} diff --git a/src/Ombi/ClientApp/src/app/shared/admin-request-dialog/admin-request-dialog.component.html b/src/Ombi/ClientApp/src/app/shared/admin-request-dialog/admin-request-dialog.component.html index 9cc059361..93c7fc5a7 100644 --- a/src/Ombi/ClientApp/src/app/shared/admin-request-dialog/admin-request-dialog.component.html +++ b/src/Ombi/ClientApp/src/app/shared/admin-request-dialog/admin-request-dialog.component.html @@ -65,25 +65,25 @@

-
-

Radarr Overrides

- - {{'MediaDetails.QualityProfilesSelect' | translate }} - - {{profile.name}} - - +
+

Radarr Overrides

+ + {{'MediaDetails.QualityProfilesSelect' | translate }} + + {{profile.name}} + + +
+
+ + {{'MediaDetails.RootFolderSelect' | translate }} + + {{profile.path}} + + +
-
- - {{'MediaDetails.RootFolderSelect' | translate }} - - {{profile.path}} - - -
-
- +
diff --git a/src/Ombi/ClientApp/src/app/shared/admin-request-dialog/admin-request-dialog.component.ts b/src/Ombi/ClientApp/src/app/shared/admin-request-dialog/admin-request-dialog.component.ts index 0256fbe77..b93fe66f7 100644 --- a/src/Ombi/ClientApp/src/app/shared/admin-request-dialog/admin-request-dialog.component.ts +++ b/src/Ombi/ClientApp/src/app/shared/admin-request-dialog/admin-request-dialog.component.ts @@ -1,124 +1,143 @@ -import { Component, Inject, OnInit } from "@angular/core"; -import { UntypedFormBuilder, UntypedFormGroup } from "@angular/forms"; -import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material/dialog"; -import { SonarrFacade } from "app/state/sonarr"; -import { firstValueFrom, Observable } from "rxjs"; -import { startWith, map } from "rxjs/operators"; -import { ILanguageProfiles, IRadarrProfile, IRadarrRootFolder, ISonarrProfile, ISonarrRootFolder, IUserDropdown, RequestType } from "../../interfaces"; -import { IdentityService, RadarrService, SonarrService } from "../../services"; +import { Component, Inject, OnInit } from '@angular/core'; +import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; +import { RadarrFacade } from 'app/state/radarr'; +import { SonarrFacade } from 'app/state/sonarr'; +import { firstValueFrom, Observable } from 'rxjs'; +import { startWith, map } from 'rxjs/operators'; +import { + ILanguageProfiles, + IRadarrProfile, + IRadarrRootFolder, + ISonarrProfile, + ISonarrRootFolder, + IUserDropdown, + RequestType, +} from '../../interfaces'; +import { IdentityService, RadarrService, SonarrService } from '../../services'; export interface IAdminRequestDialogData { - type: RequestType, - id: number + type: RequestType; + id: number; + is4k: boolean | null; } @Component({ - selector: "admin-request-dialog", - templateUrl: "admin-request-dialog.component.html", - styleUrls: [ "admin-request-dialog.component.scss" ] + selector: 'admin-request-dialog', + templateUrl: 'admin-request-dialog.component.html', + styleUrls: ['admin-request-dialog.component.scss'], }) export class AdminRequestDialogComponent implements OnInit { - constructor( - public dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) public data: IAdminRequestDialogData, - private identityService: IdentityService, - private sonarrService: SonarrService, - private radarrService: RadarrService, - private fb: UntypedFormBuilder, - private sonarrFacade: SonarrFacade - ) {} + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: IAdminRequestDialogData, + private identityService: IdentityService, + private sonarrService: SonarrService, + private radarrService: RadarrService, + private fb: UntypedFormBuilder, + private sonarrFacade: SonarrFacade, + private radarrFacade: RadarrFacade, + ) {} - public form: UntypedFormGroup; - public RequestType = RequestType; + public form: UntypedFormGroup; + public RequestType = RequestType; - public options: IUserDropdown[]; - public filteredOptions: Observable; - public userId: string; + public options: IUserDropdown[]; + public filteredOptions: Observable; + public userId: string; - public radarrEnabled: boolean; - public sonarrEnabled: boolean; + public radarrEnabled: boolean; + public radarr4kEnabled: boolean; + public sonarrEnabled: boolean; - public sonarrProfiles: ISonarrProfile[]; - public sonarrRootFolders: ISonarrRootFolder[]; - public sonarrLanguageProfiles: ILanguageProfiles[]; - public radarrProfiles: IRadarrProfile[]; - public radarrRootFolders: IRadarrRootFolder[]; + public sonarrProfiles: ISonarrProfile[]; + public sonarrRootFolders: ISonarrRootFolder[]; + public sonarrLanguageProfiles: ILanguageProfiles[]; + public radarrProfiles: IRadarrProfile[]; + public radarrRootFolders: IRadarrRootFolder[]; - public async ngOnInit() { + public async ngOnInit() { + this.form = this.fb.group({ + username: [null], + sonarrPathId: [null], + sonarrFolderId: [null], + sonarrLanguageId: [null], + radarrPathId: [null], + radarrFolderId: [null], + }); - this.form = this.fb.group({ - username: [null], - sonarrPathId: [null], - sonarrFolderId: [null], - sonarrLanguageId: [null], - radarrPathId: [null], - radarrFolderId: [null] - }) + this.options = await firstValueFrom(this.identityService.getUsersDropdown()); - this.options = await firstValueFrom(this.identityService.getUsersDropdown()); + this.filteredOptions = this.form.controls['username'].valueChanges.pipe( + startWith(''), + map((value) => this._filter(value)), + ); - this.filteredOptions = this.form.controls['username'].valueChanges.pipe( - startWith(""), - map((value) => this._filter(value)) - ); + if (this.data.type === RequestType.tvShow) { + this.sonarrEnabled = this.sonarrFacade.isEnabled(); + if (this.sonarrEnabled) { + console.log(this.sonarrFacade.version()); + if (this.sonarrFacade.version()[0] === '3') { + this.sonarrService.getV3LanguageProfilesWithoutSettings().subscribe((profiles: ILanguageProfiles[]) => { + this.sonarrLanguageProfiles = profiles; + }); + } + this.sonarrService.getQualityProfilesWithoutSettings().subscribe((c) => { + this.sonarrProfiles = c; + }); + this.sonarrService.getRootFoldersWithoutSettings().subscribe((c) => { + this.sonarrRootFolders = c; + }); + } + } + if (this.data.type === RequestType.movie) { + this.radarrEnabled = this.radarrFacade.isEnabled(); + this.radarr4kEnabled = this.radarrFacade.is4KEnabled(); - if (this.data.type === RequestType.tvShow) { - this.sonarrEnabled = this.sonarrFacade.isEnabled(); - if (this.sonarrEnabled) { - console.log(this.sonarrFacade.version()); - if (this.sonarrFacade.version()[0] === "3") { - this.sonarrService.getV3LanguageProfilesWithoutSettings().subscribe((profiles: ILanguageProfiles[]) => { - this.sonarrLanguageProfiles = profiles; - }) - } - this.sonarrService.getQualityProfilesWithoutSettings().subscribe(c => { - this.sonarrProfiles = c; - }); - this.sonarrService.getRootFoldersWithoutSettings().subscribe(c => { - this.sonarrRootFolders = c; - }); - } - } - if (this.data.type === RequestType.movie) { - this.radarrEnabled = await firstValueFrom(this.radarrService.isRadarrEnabled()); - if (this.radarrEnabled) { - this.radarrService.getQualityProfilesFromSettings().subscribe(c => { - this.radarrProfiles = c; - }); - this.radarrService.getRootFoldersFromSettings().subscribe(c => { - this.radarrRootFolders = c; - }); - } - } - } + if (this.data.is4k ?? false) { + if (this.radarr4kEnabled) { + this.radarrService.getQualityProfiles4kFromSettings().subscribe((c) => { + this.radarrProfiles = c; + }); + this.radarrService.getRootFolders4kFromSettings().subscribe((c) => { + this.radarrRootFolders = c; + }); + } + } else { + if (this.radarrEnabled) { + this.radarrService.getQualityProfilesFromSettings().subscribe((c) => { + this.radarrProfiles = c; + }); + this.radarrService.getRootFoldersFromSettings().subscribe((c) => { + this.radarrRootFolders = c; + }); + } + } + } + } - public displayFn(user: IUserDropdown): string { - const username = user?.username ? user.username : ""; - const email = user?.email ? `(${user.email})` : ""; - if (username || email) { - return `${username} ${email}`; - } - return ''; - } + public displayFn(user: IUserDropdown): string { + const username = user?.username ? user.username : ''; + const email = user?.email ? `(${user.email})` : ''; + if (username || email) { + return `${username} ${email}`; + } + return ''; + } - private _filter(value: string | IUserDropdown): IUserDropdown[] { - const filterValue = - typeof value === "string" - ? value.toLowerCase() - : value.username.toLowerCase(); + private _filter(value: string | IUserDropdown): IUserDropdown[] { + const filterValue = typeof value === 'string' ? value.toLowerCase() : value.username.toLowerCase(); - return this.options.filter((option) => - option.username.toLowerCase().includes(filterValue) - ); - } + return this.options.filter((option) => option.username.toLowerCase().includes(filterValue)); + } - public async submitRequest() { - const model = this.form.value; - model.radarrQualityOverrideTitle = this.radarrProfiles?.filter(x => x.id == model.radarrPathId)[0]?.name; - model.radarrRootFolderTitle = this.radarrRootFolders?.filter(x => x.id == model.radarrFolderId)[0]?.path; - model.sonarrRootFolderTitle = this.sonarrRootFolders?.filter(x => x.id == model.sonarrFolderId)[0]?.path; - model.sonarrQualityOverrideTitle = this.sonarrProfiles?.filter(x => x.id == model.sonarrPathId)[0]?.name; - model.sonarrLanguageProfileTitle = this.sonarrLanguageProfiles?.filter(x => x.id == model.sonarrLanguageId)[0]?.name; - this.dialogRef.close(model); - } + public async submitRequest() { + const model = this.form.value; + model.radarrQualityOverrideTitle = this.radarrProfiles?.filter((x) => x.id == model.radarrPathId)[0]?.name; + model.radarrRootFolderTitle = this.radarrRootFolders?.filter((x) => x.id == model.radarrFolderId)[0]?.path; + model.sonarrRootFolderTitle = this.sonarrRootFolders?.filter((x) => x.id == model.sonarrFolderId)[0]?.path; + model.sonarrQualityOverrideTitle = this.sonarrProfiles?.filter((x) => x.id == model.sonarrPathId)[0]?.name; + model.sonarrLanguageProfileTitle = this.sonarrLanguageProfiles?.filter((x) => x.id == model.sonarrLanguageId)[0]?.name; + this.dialogRef.close(model); + } } diff --git a/src/Ombi/ClientApp/src/app/shared/episode-request/episode-request.component.ts b/src/Ombi/ClientApp/src/app/shared/episode-request/episode-request.component.ts index 7da0fc238..3f4cb56fe 100644 --- a/src/Ombi/ClientApp/src/app/shared/episode-request/episode-request.component.ts +++ b/src/Ombi/ClientApp/src/app/shared/episode-request/episode-request.component.ts @@ -62,7 +62,7 @@ export class EpisodeRequestComponent { }); if (this.data.isAdmin) { - const dialog = this.dialog.open(AdminRequestDialogComponent, { width: "700px", data: { type: RequestType.tvShow, id: this.data.series.id }, panelClass: 'modal-panel' }); + const dialog = this.dialog.open(AdminRequestDialogComponent, { width: "700px", data: { type: RequestType.tvShow, id: this.data.series.id, is4k: null }, panelClass: 'modal-panel' }); dialog.afterClosed().subscribe(async (result) => { if (result) { viewModel.requestOnBehalf = result.username?.id; diff --git a/src/Ombi/Controllers/V1/External/RadarrController.cs b/src/Ombi/Controllers/V1/External/RadarrController.cs index 6c50b7df4..8c5979647 100644 --- a/src/Ombi/Controllers/V1/External/RadarrController.cs +++ b/src/Ombi/Controllers/V1/External/RadarrController.cs @@ -18,18 +18,18 @@ namespace Ombi.Controllers.V1.External public class RadarrController : ControllerBase { - public RadarrController(IRadarrApi radarr, ISettingsService settings, - ICacheService mem, IRadarrV3Api radarrV3Api) + public RadarrController( + ISettingsService settings, + ISettingsService radarr4kSettings, + IRadarrV3Api radarrV3Api) { - _radarrApi = radarr; _radarrSettings = settings; - _cache = mem; + _radarr4KSettings = radarr4kSettings; _radarrV3Api = radarrV3Api; } - private readonly IRadarrApi _radarrApi; private readonly ISettingsService _radarrSettings; - private readonly ICacheService _cache; + private readonly ISettingsService _radarr4KSettings; private readonly IRadarrV3Api _radarrV3Api; /// /// Gets the Radarr profiles. @@ -80,6 +80,23 @@ namespace Ombi.Controllers.V1.External return null; } + /// + /// Gets the Radarr 4K profiles using the saved settings + /// The data is cached for an hour + /// + /// + [HttpGet("Profiles/4k")] + [PowerUser] + public async Task GetProfiles4K() + { + var settings = await _radarr4KSettings.GetSettingsAsync(); + if (settings.Enabled) + { + return Ok(await _radarrV3Api.GetProfiles(settings.ApiKey, settings.FullUri)); + } + return null; + } + /// /// Gets the Radarr root folders using the saved settings. /// The data is cached for an hour @@ -97,6 +114,23 @@ namespace Ombi.Controllers.V1.External return null; } + /// + /// Gets the Radarr 4K root folders using the saved settings. + /// The data is cached for an hour + /// + /// + [HttpGet("RootFolders/4k")] + [PowerUser] + public async Task> GetRootFolders4K() + { + var settings = await _radarr4KSettings.GetSettingsAsync(); + if (settings.Enabled) + { + return await _radarrV3Api.GetRootFolders(settings.ApiKey, settings.FullUri); + } + return null; + } + /// /// Gets the Radarr tags ///