Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Rework the Plex Settings Page #4772

Merged
merged 3 commits into from
Oct 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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