From dc98613bb4fb0cd086e29519a7ae6e0077eed7b4 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 7 Oct 2022 21:35:31 +0100 Subject: [PATCH] refactor: Rework the Plex Settings Page (#4772) [skip ci] --- src/Ombi.Api.Discord/DiscordApi.cs | 4 +- src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs | 30 +-- .../form-field/plex-form-field.component.ts | 43 ++++ .../plex/components/models/PlexCreds.ts | 4 + .../plex/components/models/PlexSyncType.ts | 6 + .../settings/plex/components/models/index.ts | 2 + .../plex-form/plex-form.component.html | 154 +++++++++++++ .../plex-form/plex-form.component.scss | 8 + .../plex-form/plex-form.component.ts | 25 ++ .../src/app/settings/plex/plex.component.html | 213 ++---------------- .../src/app/settings/plex/plex.component.scss | 4 + .../src/app/settings/plex/plex.component.ts | 32 ++- .../src/app/settings/settings.module.ts | 4 + 13 files changed, 313 insertions(+), 216 deletions(-) create mode 100644 src/Ombi/ClientApp/src/app/settings/plex/components/form-field/plex-form-field.component.ts create mode 100644 src/Ombi/ClientApp/src/app/settings/plex/components/models/PlexCreds.ts create mode 100644 src/Ombi/ClientApp/src/app/settings/plex/components/models/PlexSyncType.ts create mode 100644 src/Ombi/ClientApp/src/app/settings/plex/components/models/index.ts create mode 100644 src/Ombi/ClientApp/src/app/settings/plex/components/plex-form/plex-form.component.html create mode 100644 src/Ombi/ClientApp/src/app/settings/plex/components/plex-form/plex-form.component.scss create mode 100644 src/Ombi/ClientApp/src/app/settings/plex/components/plex-form/plex-form.component.ts diff --git a/src/Ombi.Api.Discord/DiscordApi.cs b/src/Ombi.Api.Discord/DiscordApi.cs index 122c51a87..86ecb00a0 100644 --- a/src/Ombi.Api.Discord/DiscordApi.cs +++ b/src/Ombi.Api.Discord/DiscordApi.cs @@ -14,12 +14,12 @@ namespace Ombi.Api.Discord Api = api; } - private const string BaseUrl = "https://discordapp.com/api/"; + private const string _baseUrl = "https://discordapp.com/api/"; private IApi Api { get; } public async Task SendMessage(DiscordWebhookBody body, string webhookId, string webhookToken) { - var request = new Request($"webhooks/{webhookId}/{webhookToken}", BaseUrl, HttpMethod.Post); + var request = new Request($"webhooks/{webhookId}/{webhookToken}", _baseUrl, HttpMethod.Post); request.AddJsonBody(body); diff --git a/src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs b/src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs index 0de749308..2bda53875 100644 --- a/src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs +++ b/src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs @@ -67,11 +67,9 @@ namespace Ombi.Schedule.Jobs.Sonarr var strat = _ctx.Database.CreateExecutionStrategy(); await strat.ExecuteAsync(async () => { - using (var tran = await _ctx.Database.BeginTransactionAsync()) - { - await _ctx.Database.ExecuteSqlRawAsync("DELETE FROM SonarrCache"); - tran.Commit(); - } + using var tran = await _ctx.Database.BeginTransactionAsync(); + await _ctx.Database.ExecuteSqlRawAsync("DELETE FROM SonarrCache"); + tran.Commit(); }); var sonarrCacheToSave = new HashSet(); @@ -97,11 +95,9 @@ namespace Ombi.Schedule.Jobs.Sonarr strat = _ctx.Database.CreateExecutionStrategy(); await strat.ExecuteAsync(async () => { - using (var tran = await _ctx.Database.BeginTransactionAsync()) - { - await _ctx.Database.ExecuteSqlRawAsync("DELETE FROM SonarrEpisodeCache"); - tran.Commit(); - } + using var tran = await _ctx.Database.BeginTransactionAsync(); + await _ctx.Database.ExecuteSqlRawAsync("DELETE FROM SonarrEpisodeCache"); + tran.Commit(); }); foreach (var s in ids) @@ -111,7 +107,7 @@ namespace Ombi.Schedule.Jobs.Sonarr continue; } - _log.LogDebug("Syncing series: {0}", s.Title); + _log.LogDebug($"Syncing series: {s.Title}"); var episodes = await _api.GetEpisodes(s.Id, settings.ApiKey, settings.FullUri); var monitoredEpisodes = episodes.Where(x => x.monitored || x.hasFile); @@ -156,13 +152,11 @@ namespace Ombi.Schedule.Jobs.Sonarr strat = _ctx.Database.CreateExecutionStrategy(); await strat.ExecuteAsync(async () => { - using (var tran = await _ctx.Database.BeginTransactionAsync()) - { - await _ctx.SonarrEpisodeCache.AddRangeAsync(episodesToAdd); - _log.LogDebug("Commiting the transaction"); - await _ctx.SaveChangesAsync(); - tran.Commit(); - } + using var tran = await _ctx.Database.BeginTransactionAsync(); + await _ctx.SonarrEpisodeCache.AddRangeAsync(episodesToAdd); + _log.LogDebug("Commiting the transaction"); + await _ctx.SaveChangesAsync(); + tran.Commit(); }); } diff --git a/src/Ombi/ClientApp/src/app/settings/plex/components/form-field/plex-form-field.component.ts b/src/Ombi/ClientApp/src/app/settings/plex/components/form-field/plex-form-field.component.ts new file mode 100644 index 000000000..46518b0d0 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/plex/components/form-field/plex-form-field.component.ts @@ -0,0 +1,43 @@ +import { Component, EventEmitter, Input, Output } from "@angular/core"; + +@Component({ + selector: "settings-plex-form-field", + template: ` +
+
+ {{label}} + +
+ + +
+
+ + + + + + + +
+ +
+ +
+
+ ` +}) +export class PlexFormFieldComponent { + + @Input() public label: string; + @Input() public value: any; + @Output() public valueChange = new EventEmitter(); + @Input() public id: string; + @Input() public placeholder: string; + @Input() public type: "input" | "checkbox" | "password" = "input" + + public change(newValue: string) { + this.value = newValue; + this.valueChange.emit(newValue); + } +} diff --git a/src/Ombi/ClientApp/src/app/settings/plex/components/models/PlexCreds.ts b/src/Ombi/ClientApp/src/app/settings/plex/components/models/PlexCreds.ts new file mode 100644 index 000000000..9847bc7e0 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/plex/components/models/PlexCreds.ts @@ -0,0 +1,4 @@ +export interface PlexCreds { + username: string; + password: string; +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/settings/plex/components/models/PlexSyncType.ts b/src/Ombi/ClientApp/src/app/settings/plex/components/models/PlexSyncType.ts new file mode 100644 index 000000000..2e3005d0d --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/plex/components/models/PlexSyncType.ts @@ -0,0 +1,6 @@ +export enum PlexSyncType { + Full = 0, + RecentlyAdded = 1, + ClearAndReSync = 2, + WatchlistImport = 3, +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/settings/plex/components/models/index.ts b/src/Ombi/ClientApp/src/app/settings/plex/components/models/index.ts new file mode 100644 index 000000000..1569393f8 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/plex/components/models/index.ts @@ -0,0 +1,2 @@ +export * from './PlexSyncType'; +export * from './PlexCreds'; \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/settings/plex/components/plex-form/plex-form.component.html b/src/Ombi/ClientApp/src/app/settings/plex/components/plex-form/plex-form.component.html new file mode 100644 index 000000000..9adac40f8 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/plex/components/plex-form/plex-form.component.html @@ -0,0 +1,154 @@ +
+ +
+ +
+ + + + +
+
+ +
+
+ +
+
+ Please select the server: +
+
+
+ + + +
+ +
+ + + + {{s.name}} + + +
+
+
+ +
+
+
+ +
+
+ +
+ Please select the libraries you want Ombi to monitor +
+ Note: if nothing is selected, we will monitor all libraries +
+
+
+
+
+
+ {{lib.title}} +
+
+
+
+
+
+ + +
+ + + + + + + + + + + + This will be the external address that users will navigate to when they press the 'View On Plex' button + + Current URL: "{{server.serverHostname}}/web/app#!/server/{{server.machineIdentifier}}/details?key=%2flibrary%2Fmetadata%2F53334" + Current URL: "https://app.plex.tv/web/app#!/server/{{server.machineIdentifier}}/details?key=%2flibrary%2Fmetadata%2F53334" + + + + + This is used when we cache the episodes, we cache in batches of 150 by default, you can configure how many we do at a time here + + + +
+
+
+
+ + + + + + + + +
+ +
+ +
+ +
+
+
+
+
+ +
+
+ +
+
+ +
+
\ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/settings/plex/components/plex-form/plex-form.component.scss b/src/Ombi/ClientApp/src/app/settings/plex/components/plex-form/plex-form.component.scss new file mode 100644 index 000000000..20d3aa559 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/plex/components/plex-form/plex-form.component.scss @@ -0,0 +1,8 @@ +.hr-margin { + margin-bottom: 2rem; + margin-top: 2rem; +} + +.right { + text-align: right; +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/settings/plex/components/plex-form/plex-form.component.ts b/src/Ombi/ClientApp/src/app/settings/plex/components/plex-form/plex-form.component.ts new file mode 100644 index 000000000..2f2f4317a --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/plex/components/plex-form/plex-form.component.ts @@ -0,0 +1,25 @@ +import { Component, EventEmitter, Input, Output } from "@angular/core"; +import { IPlexServer, IPlexServerResponse, IPlexServerViewModel } from "app/interfaces"; +import { PlexCreds, PlexSyncType } from "../models"; + +@Component({ + templateUrl: "./plex-form.component.html", + styleUrls: ["./plex-form.component.scss"], + selector: "settings-plex-form" +}) +export class PlexFormComponent { + + @Input() public server: IPlexServer; + @Input() public advancedEnabled: boolean = false; + @Input() public loadedServers: IPlexServerViewModel; + + @Output() public loadLibraries = new EventEmitter(); + @Output() public loadServers = new EventEmitter(); + @Output() public selectServer = new EventEmitter(); + @Output() public test = new EventEmitter(); + @Output() public runSync = new EventEmitter(); + + public username: string; + public password: string; + public PlexSyncType = PlexSyncType; +} diff --git a/src/Ombi/ClientApp/src/app/settings/plex/plex.component.html b/src/Ombi/ClientApp/src/app/settings/plex/plex.component.html index 63a6140a9..53b0eed29 100644 --- a/src/Ombi/ClientApp/src/app/settings/plex/plex.component.html +++ b/src/Ombi/ClientApp/src/app/settings/plex/plex.component.html @@ -2,206 +2,43 @@
Plex Configuration -
-
-
- Enable - -
-
- Enable User Watchlist Requests - -

When a Plex User adds something to their watchlist in Plex, it will turn up in Ombi as a Request if enabled. This only applies to users that are logging in with their Plex Account

-

Request limits if set are all still applied etc.

-
-
- Advanced -
- -
-
-
- -
- -
-
+ + + + + When a Plex User adds something to their watchlist in Plex, it will turn up in Ombi as a Request if enabled. This only applies to users that are logging in with their Plex Account +
Request limits if set are all still applied +
+
+ + + +
+
+


-
- - -
- - Server Name - - -
- -
- - Hostname or IP - - - - Port - - + + - - SSL - -
-
- - Plex Authorization Token - - - - - Machine Identifier - - -
-
- - Externally Facing Hostname - - - - Current URL: "{{server.serverHostname}}/web/app#!/server/{{server.machineIdentifier}}/details?key=%2flibrary%2Fmetadata%2F53334" - Current URL: "https://app.plex.tv/web/app#!/server/{{server.machineIdentifier}}/details?key=%2flibrary%2Fmetadata%2F53334" - -
-
-
- - Episode Batch Size - - -
-
-
- -
-
-
- - Server - - - {{s.name}} - - -
-
-
- -
- Note: if nothing is selected, we will monitor all libraries -
-
- -
-
-
-
-
-
-
- {{lib.title}} -
-
-
-
-
-
-
- -
- - Username - - -
-
- - Password - - -
-
-
-
- -
-
-
- -
-
- -
-
-
-
-
- -
-
- -
-
- -
-
-
diff --git a/src/Ombi/ClientApp/src/app/settings/plex/plex.component.scss b/src/Ombi/ClientApp/src/app/settings/plex/plex.component.scss index 4f0c2c3d1..7acdcf6f0 100644 --- a/src/Ombi/ClientApp/src/app/settings/plex/plex.component.scss +++ b/src/Ombi/ClientApp/src/app/settings/plex/plex.component.scss @@ -17,4 +17,8 @@ float: right; width:100%; text-align:right; +} + +::ng-deep div .mat-tab-body-content { + overflow: hidden; } \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/settings/plex/plex.component.ts b/src/Ombi/ClientApp/src/app/settings/plex/plex.component.ts index 086bc3d15..d026fd1dd 100644 --- a/src/Ombi/ClientApp/src/app/settings/plex/plex.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/plex/plex.component.ts @@ -8,6 +8,7 @@ import { MatTabChangeEvent, MatTabGroup } from "@angular/material/tabs"; import {UntypedFormControl} from '@angular/forms'; import { MatDialog } from "@angular/material/dialog"; import { PlexWatchlistComponent } from "./components/watchlist/plex-watchlist.component"; +import { PlexCreds, PlexSyncType } from "./components/models"; @Component({ templateUrl: "./plex.component.html", @@ -16,8 +17,6 @@ import { PlexWatchlistComponent } from "./components/watchlist/plex-watchlist.co export class PlexComponent implements OnInit, OnDestroy { public settings: IPlexSettings; public loadedServers: IPlexServerViewModel; // This comes from the api call for the user to select a server - public username: string; - public password: string; public serversButton = false; selected = new UntypedFormControl(0); @ViewChild("tabGroup", {static: false}) public tagGroup: MatTabGroup; @@ -40,8 +39,8 @@ export class PlexComponent implements OnInit, OnDestroy { }); } - public requestServers(server: IPlexServer) { - this.plexService.getServers(this.username, this.password).pipe( + public requestServers({ username, password }: PlexCreds) { + this.plexService.getServers(username, password).pipe( takeUntil(this.subscriptions), ).subscribe(x => { if (x.success) { @@ -151,7 +150,24 @@ export class PlexComponent implements OnInit, OnDestroy { }); } - public runCacher(): void { + public runSync(type: PlexSyncType) { + switch (type) { + case PlexSyncType.Full: + this.runCacher(); + return; + case PlexSyncType.RecentlyAdded: + this.runRecentlyAddedCacher(); + return; + case PlexSyncType.ClearAndReSync: + this.clearDataAndResync(); + return; + case PlexSyncType.WatchlistImport: + this.runWatchlistImport(); + return; + } + } + + private runCacher(): void { this.jobService.runPlexCacher().subscribe(x => { if (x) { this.notificationService.success("Triggered the Plex Full Sync"); @@ -159,7 +175,7 @@ export class PlexComponent implements OnInit, OnDestroy { }); } - public runRecentlyAddedCacher(): void { + private runRecentlyAddedCacher(): void { this.jobService.runPlexRecentlyAddedCacher().subscribe(x => { if (x) { this.notificationService.success("Triggered the Plex Recently Added Sync"); @@ -167,7 +183,7 @@ export class PlexComponent implements OnInit, OnDestroy { }); } - public clearDataAndResync(): void { + private clearDataAndResync(): void { this.jobService.clearMediaserverData().subscribe(x => { if (x) { this.notificationService.success("Triggered the Clear MediaServer Resync"); @@ -175,7 +191,7 @@ export class PlexComponent implements OnInit, OnDestroy { }); } - public runWatchlistImport(): void { + private runWatchlistImport(): void { this.jobService.runPlexWatchlistImport().subscribe(x => { if (x) { this.notificationService.success("Triggered the Watchlist Import"); diff --git a/src/Ombi/ClientApp/src/app/settings/settings.module.ts b/src/Ombi/ClientApp/src/app/settings/settings.module.ts index f153be982..a1b530f11 100644 --- a/src/Ombi/ClientApp/src/app/settings/settings.module.ts +++ b/src/Ombi/ClientApp/src/app/settings/settings.module.ts @@ -84,6 +84,8 @@ import { WebhookComponent } from "./notifications/webhook.component"; import { WhatsAppComponent } from "./notifications/twilio/whatsapp.component"; import { WikiComponent } from "./wiki.component"; import { PlexWatchlistComponent } from "./plex/components/watchlist/plex-watchlist.component"; +import { PlexFormComponent } from "./plex/components/plex-form/plex-form.component"; +import { PlexFormFieldComponent } from "./plex/components/form-field/plex-form-field.component"; const routes: Routes = [ { path: "Ombi", component: OmbiComponent, canActivate: [AuthGuard] }, @@ -191,6 +193,8 @@ const routes: Routes = [ CloudMobileComponent, UpdateDialogComponent, PlexWatchlistComponent, + PlexFormComponent, + PlexFormFieldComponent, ], exports: [ RouterModule,