Skip to content

Commit

Permalink
refactor: Rework the Plex Settings Page (#4772)
Browse files Browse the repository at this point in the history
[skip ci]
  • Loading branch information
tidusjar authored Oct 7, 2022
1 parent 9ba5098 commit dc98613
Show file tree
Hide file tree
Showing 13 changed files with 313 additions and 216 deletions.
4 changes: 2 additions & 2 deletions src/Ombi.Api.Discord/DiscordApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ public DiscordApi(IApi api)
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);

Expand Down
30 changes: 12 additions & 18 deletions src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,9 @@ public async Task Execute(IJobExecutionContext job)
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<SonarrCache>();
Expand All @@ -97,11 +95,9 @@ await strat.ExecuteAsync(async () =>
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)
Expand All @@ -111,7 +107,7 @@ await strat.ExecuteAsync(async () =>
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);

Expand Down Expand Up @@ -156,13 +152,11 @@ await strat.ExecuteAsync(async () =>
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();
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Component, EventEmitter, Input, Output } from "@angular/core";

@Component({
selector: "settings-plex-form-field",
template: `
<div class="row">
<div class="col-2 align-self-center">
{{label}}
<br>
<!-- Content Below the label -->
<ng-content></ng-content>
</div>
<div class="md-form-field col-10">
<mat-form-field appearance="outline" floatLabel=auto *ngIf="type === 'input' || type === 'password'">
<input matInput placeholder={{placeholder}} [attr.type]="type" id="{{id}}" name="{{id}}" [ngModel]="value" (ngModelChange)="change($event)" value="{{value}}">
</mat-form-field>
<mat-slide-toggle *ngIf="type === 'checkbox'" id="{{id}}" [ngModel]="value" (ngModelChange)="change($event)" [checked]="value"></mat-slide-toggle>
<ng-content select="[below]"></ng-content>
</div>
<div class="col-12">
<ng-content select="[bottom]"></ng-content>
</div>
</div>
`
})
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);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface PlexCreds {
username: string;
password: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export enum PlexSyncType {
Full = 0,
RecentlyAdded = 1,
ClearAndReSync = 2,
WatchlistImport = 3,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './PlexSyncType';
export * from './PlexCreds';
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
<div>

<div class="md-form-field">
<label for="username" class="control-label">
<h3>Plex Credentials</h3>
<small>These fields are optional to automatically fill in your Plex server settings. <br>
This will pass your username and password to the Plex.tv API to grab the servers associated with this user.
<br>
If you have 2FA enabled on your account, you need to append the 2FA code to the end of your password.</small>
</label>
</div>

<settings-plex-form-field [label]="'Username'" [id]="'username'" [(value)]="username"></settings-plex-form-field>
<settings-plex-form-field [label]="'Password'" [id]="'password'" [type]="'password'" [(value)]="password"></settings-plex-form-field>

<div class="md-form-field">
<div class="right">
<button mat-raised-button id="loadServers" (click)="loadServers.emit({username, password})"
class="mat-stroked-button">Load Servers
<i class="fas fa-key"></i>
</button>
</div>
</div>

<div class="row">
<div class="col-2 align-self-center">
Please select the server:
</div>
<div class="md-form-field col-10">
<div *ngIf="!loadedServers">
<mat-form-field appearance="outline" floatLabel=auto>
<input disabled matInput placeholder="No Servers Loaded" id="selectServer-noservers">
</mat-form-field>
</div>

<div *ngIf="loadedServers">
<mat-form-field appearance="outline">
<mat-select placeholder="Servers Loaded! Please Select">
<mat-option (click)="selectServer.emit(s)"
*ngFor="let s of loadedServers.servers.server" [value]="s.server">
{{s.name}}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>

<div class="row">
<div class="col-12 md-form-field">
<div>
<button mat-raised-button (click)="loadLibraries.emit()"
class="mat-focus-indicator mat-stroked-button mat-button-base">Load Libraries
<i class="fas fa-film"></i>
</button>
</div>
</div>

<div class="col-2 align-self-center">
Please select the libraries you want Ombi to monitor
<br>
<small>Note: if nothing is selected, we will monitor all libraries</small>
</div>
<div class="md-form-field col-10">
<div *ngIf="server.plexSelectedLibraries">
<div *ngFor="let lib of server.plexSelectedLibraries">
<div class="md-form-field">
<div class="checkbox">
<mat-slide-toggle [(ngModel)]="lib.enabled" [checked]="lib.enabled"
for="{{lib.title}}">{{lib.title}}</mat-slide-toggle>
</div>
</div>
</div>
</div>
</div>
</div>


<hr class="hr-margin">

<settings-plex-form-field [label]="'Server Name'" [id]="'name'" [(value)]="server.name"></settings-plex-form-field>
<settings-plex-form-field [label]="'Hostname or IP'" [id]="'ip'" [(value)]="server.ip"></settings-plex-form-field>
<settings-plex-form-field [label]="'Port'" [id]="'port'" [(value)]="server.port"></settings-plex-form-field>

<settings-plex-form-field [label]="'SSL'" [type]="'checkbox'" [id]="'ssl'" [(value)]="server.ssl"></settings-plex-form-field>

<settings-plex-form-field [label]="'Plex Authorization Token'" [id]="'authToken'" [(value)]="server.plexAuthToken"></settings-plex-form-field>
<settings-plex-form-field [label]="'Machine Identifier'" [id]="'MachineIdentifier'" [(value)]="server.machineIdentifier"></settings-plex-form-field>
<settings-plex-form-field
[label]="'Externally Facing Hostname'"
[placeholder]="'e.g. https://app.plex.tv'"
[id]="'hostname'"
[(value)]="server.serverHostname">

<small>This will be the external address that users will navigate to when they press the 'View On Plex' button</small>
<small below>
<span *ngIf="server.serverHostname">Current URL: "{{server.serverHostname}}/web/app#!/server/{{server.machineIdentifier}}/details?key=%2flibrary%2Fmetadata%2F53334"</span>
<span *ngIf="!server.serverHostname">Current URL: "https://app.plex.tv/web/app#!/server/{{server.machineIdentifier}}/details?key=%2flibrary%2Fmetadata%2F53334"</span>
</small>
</settings-plex-form-field>

<settings-plex-form-field
*ngIf="advancedEnabled"
[label]="'Episode Batch Size'"
[id]="'episodeBatchSize'"
[(value)]="server.episodeBatchSize">
<small>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</small>
</settings-plex-form-field>


<br>
<br>
<br>
</div>






<!-- Second section -->

<div class="row">

<br />

<div class="form-group col-12">
<button mat-raised-button id="testPlex" type="button" (click)="test.emit()"
class="mat-focus-indicator mat-stroked-button mat-button-base">
Test Connectivity
<div id="spinner"></div>
</button>
</div>
<div class="form-group col-1">
<button mat-raised-button (click)="runSync.emit(PlexSyncType.Full)" type="button" id="fullSync"
class="mat-focus-indicator mat-stroked-button mat-button-base">Full
Sync</button><br />
</div>
<div class="form-group col-1">
<button mat-raised-button (click)="runSync.emit(PlexSyncType.RecentlyAdded)" type="button" id="recentlyAddedSync"
class="mat-focus-indicator mat-stroked-button mat-button-base">Partial Sync</button>
</div>
<div class="form-group col-1">
<button mat-raised-button (click)="runSync.emit(PlexSyncType.ClearAndReSync)" type="button" id="clearData"
class="mat-focus-indicator mat-stroked-button mat-button-base">
Clear Data And Resync
</button>
</div>
<div class="form-group col-12">
<button mat-raised-button (click)="runSync.emit(PlexSyncType.WatchlistImport)" type="button" id="watchlistImport"
class="mat-focus-indicator mat-stroked-button mat-button-base">
Run Watchlist Import
</button>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.hr-margin {
margin-bottom: 2rem;
margin-top: 2rem;
}

.right {
text-align: right;
}
Original file line number Diff line number Diff line change
@@ -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<PlexCreds>();
@Output() public selectServer = new EventEmitter<IPlexServerResponse>();
@Output() public test = new EventEmitter();
@Output() public runSync = new EventEmitter<PlexSyncType>();

public username: string;
public password: string;
public PlexSyncType = PlexSyncType;
}
Loading

0 comments on commit dc98613

Please sign in to comment.