mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-30 19:40:05 -07:00
#865 Added support for multiple plex servers
This commit is contained in:
parent
a278917dcd
commit
3879fc04de
11 changed files with 270 additions and 177 deletions
|
@ -73,7 +73,8 @@ namespace Ombi.Schedule.Jobs
|
|||
|
||||
StartTheCache(plexSettings).Wait();
|
||||
}
|
||||
catch (Exception e) {
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogWarning(LoggingEvents.CacherException, e, "Exception thrown when attempting to cache the Plex Content");
|
||||
}
|
||||
}
|
||||
|
@ -119,87 +120,92 @@ namespace Ombi.Schedule.Jobs
|
|||
|
||||
private async Task StartTheCache(PlexSettings plexSettings)
|
||||
{
|
||||
var allContent = GetAllContent(plexSettings);
|
||||
|
||||
// Let's now process this.
|
||||
|
||||
var contentToAdd = new List<PlexContent>();
|
||||
foreach (var content in allContent)
|
||||
foreach (var servers in plexSettings.Servers ?? new List<PlexServers>())
|
||||
{
|
||||
if (content.viewGroup.Equals(PlexMediaType.Show.ToString(), StringComparison.CurrentCultureIgnoreCase))
|
||||
|
||||
var allContent = GetAllContent(servers);
|
||||
|
||||
// Let's now process this.
|
||||
|
||||
var contentToAdd = new List<PlexContent>();
|
||||
foreach (var content in allContent)
|
||||
{
|
||||
// Process Shows
|
||||
foreach (var metadata in content.Metadata)
|
||||
if (content.viewGroup.Equals(PlexMediaType.Show.ToString(), StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
var seasonList = await PlexApi.GetSeasons(plexSettings.PlexAuthToken, plexSettings.FullUri,
|
||||
metadata.ratingKey);
|
||||
var seasonsContent = new List<SeasonsContent>();
|
||||
foreach (var season in seasonList.MediaContainer.Metadata)
|
||||
// Process Shows
|
||||
foreach (var metadata in content.Metadata)
|
||||
{
|
||||
seasonsContent.Add(new SeasonsContent
|
||||
var seasonList = await PlexApi.GetSeasons(servers.PlexAuthToken, servers.FullUri,
|
||||
metadata.ratingKey);
|
||||
var seasonsContent = new List<SeasonsContent>();
|
||||
foreach (var season in seasonList.MediaContainer.Metadata)
|
||||
{
|
||||
ParentKey = int.Parse(season.parentRatingKey),
|
||||
SeasonKey = int.Parse(season.ratingKey),
|
||||
SeasonNumber = season.index
|
||||
});
|
||||
}
|
||||
|
||||
// Do we already have this item?
|
||||
var existingContent = await Repo.GetByKey(metadata.key);
|
||||
if (existingContent != null)
|
||||
{
|
||||
// Ok so we have it, let's check if there are any new seasons
|
||||
var seasonDifference = seasonsContent.Except(existingContent.Seasons).ToList();
|
||||
if (seasonDifference.Any())
|
||||
{
|
||||
// We have new seasons on Plex, let's add them back into the entity
|
||||
existingContent.Seasons.AddRange(seasonDifference);
|
||||
await Repo.Update(existingContent);
|
||||
continue;
|
||||
seasonsContent.Add(new SeasonsContent
|
||||
{
|
||||
ParentKey = int.Parse(season.parentRatingKey),
|
||||
SeasonKey = int.Parse(season.ratingKey),
|
||||
SeasonNumber = season.index
|
||||
});
|
||||
}
|
||||
else
|
||||
|
||||
// Do we already have this item?
|
||||
var existingContent = await Repo.GetByKey(metadata.key);
|
||||
if (existingContent != null)
|
||||
{
|
||||
// No changes, no need to do anything
|
||||
continue;
|
||||
// Ok so we have it, let's check if there are any new seasons
|
||||
var seasonDifference = seasonsContent.Except(existingContent.Seasons).ToList();
|
||||
if (seasonDifference.Any())
|
||||
{
|
||||
// We have new seasons on Plex, let's add them back into the entity
|
||||
existingContent.Seasons.AddRange(seasonDifference);
|
||||
await Repo.Update(existingContent);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No changes, no need to do anything
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the show metadata... This sucks since the `metadata` var contains all information about the show
|
||||
// But it does not contain the `guid` property that we need to pull out thetvdb id...
|
||||
var showMetadata = await PlexApi.GetMetadata(servers.PlexAuthToken, servers.FullUri,
|
||||
metadata.ratingKey);
|
||||
var item = new PlexContent
|
||||
{
|
||||
AddedAt = DateTime.Now,
|
||||
Key = metadata.ratingKey,
|
||||
ProviderId = PlexHelper.GetProviderIdFromPlexGuid(showMetadata.MediaContainer.Metadata
|
||||
.FirstOrDefault()
|
||||
.guid),
|
||||
ReleaseYear = metadata.year.ToString(),
|
||||
Type = PlexMediaTypeEntity.Show,
|
||||
Title = metadata.title,
|
||||
Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, metadata.ratingKey),
|
||||
Seasons = new List<SeasonsContent>()
|
||||
};
|
||||
|
||||
|
||||
item.Seasons.AddRange(seasonsContent);
|
||||
|
||||
contentToAdd.Add(item);
|
||||
}
|
||||
|
||||
// Get the show metadata... This sucks since the `metadata` var contains all information about the show
|
||||
// But it does not contain the `guid` property that we need to pull out thetvdb id...
|
||||
var showMetadata = await PlexApi.GetMetadata(plexSettings.PlexAuthToken, plexSettings.FullUri,
|
||||
metadata.ratingKey);
|
||||
var item = new PlexContent
|
||||
{
|
||||
AddedAt = DateTime.Now,
|
||||
Key = metadata.ratingKey,
|
||||
ProviderId = PlexHelper.GetProviderIdFromPlexGuid(showMetadata.MediaContainer.Metadata
|
||||
.FirstOrDefault()
|
||||
.guid),
|
||||
ReleaseYear = metadata.year.ToString(),
|
||||
Type = PlexMediaTypeEntity.Show,
|
||||
Title = metadata.title,
|
||||
Url = PlexHelper.GetPlexMediaUrl(plexSettings.MachineIdentifier, metadata.ratingKey),
|
||||
Seasons = new List<SeasonsContent>()
|
||||
};
|
||||
|
||||
|
||||
item.Seasons.AddRange(seasonsContent);
|
||||
|
||||
contentToAdd.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (contentToAdd.Any())
|
||||
{
|
||||
await Repo.AddRange(contentToAdd);
|
||||
if (contentToAdd.Any())
|
||||
{
|
||||
await Repo.AddRange(contentToAdd);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private List<Mediacontainer> GetAllContent(PlexSettings plexSettings)
|
||||
private List<Mediacontainer> GetAllContent(PlexServers plexSettings)
|
||||
{
|
||||
var sections = PlexApi.GetLibrarySections(plexSettings.PlexAuthToken, plexSettings.FullUri).Result;
|
||||
|
||||
|
||||
var libs = new List<Mediacontainer>();
|
||||
if (sections != null)
|
||||
{
|
||||
|
@ -232,9 +238,12 @@ namespace Ombi.Schedule.Jobs
|
|||
{
|
||||
if (plex.Enable)
|
||||
{
|
||||
if (string.IsNullOrEmpty(plex?.Ip) || string.IsNullOrEmpty(plex?.PlexAuthToken))
|
||||
foreach (var server in plex.Servers ?? new List<PlexServers>())
|
||||
{
|
||||
return false;
|
||||
if (string.IsNullOrEmpty(server?.Ip) || string.IsNullOrEmpty(server?.PlexAuthToken))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return plex.Enable;
|
||||
|
|
|
@ -2,18 +2,23 @@
|
|||
|
||||
namespace Ombi.Core.Settings.Models.External
|
||||
{
|
||||
public sealed class PlexSettings : ExternalSettings
|
||||
public sealed class PlexSettings : Ombi.Settings.Settings.Models.Settings
|
||||
{
|
||||
|
||||
public bool Enable { get; set; }
|
||||
public List<PlexServers> Servers { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class PlexServers : ExternalSettings
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public bool EnableEpisodeSearching { get; set; }
|
||||
|
||||
public string PlexAuthToken { get; set; }
|
||||
public string MachineIdentifier { get; set; }
|
||||
|
||||
public List<PlexSelectedLibraries> PlexSelectedLibraries { get; set; }
|
||||
public List<PlexSelectedLibraries> PlexSelectedLibraries { get; set; }
|
||||
}
|
||||
|
||||
public class PlexSelectedLibraries
|
||||
{
|
||||
public int Key { get; set; }
|
||||
|
|
39
Ombi/Ombi/Controllers/External/PlexController.cs
vendored
39
Ombi/Ombi/Controllers/External/PlexController.cs
vendored
|
@ -1,4 +1,6 @@
|
|||
using System.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
@ -28,29 +30,42 @@ namespace Ombi.Controllers.External
|
|||
{
|
||||
// Do we already have settings?
|
||||
var settings = await PlexSettings.GetSettingsAsync();
|
||||
if (!string.IsNullOrEmpty(settings?.PlexAuthToken)) return null;
|
||||
if (!settings.Servers?.Any() ?? false) return null;
|
||||
|
||||
var result = await PlexApi.SignIn(request);
|
||||
if (!string.IsNullOrEmpty(result.user?.authentication_token))
|
||||
{
|
||||
var server = await PlexApi.GetServer(result.user.authentication_token);
|
||||
var firstServer = server.Server.FirstOrDefault();
|
||||
await PlexSettings.SaveSettingsAsync(new PlexSettings
|
||||
var servers = server.Server;
|
||||
|
||||
settings.Servers = new List<PlexServers>();
|
||||
var serverNumber = 0;
|
||||
foreach (var s in servers)
|
||||
{
|
||||
Enable = true,
|
||||
PlexAuthToken = result.user.authentication_token,
|
||||
Ip = firstServer.LocalAddresses,
|
||||
MachineIdentifier = firstServer.MachineIdentifier,
|
||||
Port = int.Parse(firstServer.Port),
|
||||
Ssl = firstServer.Scheme != "http",
|
||||
});
|
||||
if (string.IsNullOrEmpty(s.LocalAddresses) || string.IsNullOrEmpty(s.Port))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
settings.Servers.Add(new PlexServers
|
||||
{
|
||||
PlexAuthToken = result.user.authentication_token,
|
||||
Id = new Random().Next(),
|
||||
Ip = s.LocalAddresses.Split(new []{','}, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault(),
|
||||
MachineIdentifier = s.MachineIdentifier,
|
||||
Port = int.Parse(s.Port),
|
||||
Ssl = s.Scheme != "http",
|
||||
Name = $"Server{serverNumber++}"
|
||||
});
|
||||
}
|
||||
|
||||
await PlexSettings.SaveSettingsAsync(settings);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[HttpPost("Libraries")]
|
||||
public async Task<PlexLibraries> GetPlexLibraries([FromBody] PlexSettings settings)
|
||||
public async Task<PlexLibraries> GetPlexLibraries([FromBody] PlexServers settings)
|
||||
{
|
||||
var libs = await PlexApi.GetLibrarySections(settings.PlexAuthToken, settings.FullUri);
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ var paths = {
|
|||
'@angular/forms',
|
||||
'@angular/platform-browser/animations',
|
||||
'@angular/material',
|
||||
'@ng-bootstrap/ng-bootstrap',
|
||||
'ngx-infinite-scroll'
|
||||
],
|
||||
dest: './lib'
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
"@angular/platform-browser-dynamic": "^4.1.0",
|
||||
"@angular/platform-server": "^4.1.0",
|
||||
"@angular/router": "^4.1.0",
|
||||
"@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.25",
|
||||
"@types/jquery": "^2.0.33",
|
||||
"@types/systemjs": "^0.20.2",
|
||||
"angular2-jwt": "^0.2.0",
|
||||
|
@ -27,7 +28,7 @@
|
|||
"gulp-clean-css": "^3.0.4",
|
||||
"gulp-filter": "^5.0.0",
|
||||
"gulp-if": "^2.0.2",
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp-run": "^1.7.1",
|
||||
"gulp-sass": "^2.3.2",
|
||||
"gulp-sourcemaps": "^1.9.0",
|
||||
|
|
|
@ -2,7 +2,8 @@ import { NgModule } from '@angular/core';
|
|||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MdButtonModule} from '@angular/material';
|
||||
import { MdButtonModule } from '@angular/material';
|
||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
|
@ -75,7 +76,8 @@ const routes: Routes = [
|
|||
AuthModule,
|
||||
WizardModule,
|
||||
DialogModule,
|
||||
MdButtonModule
|
||||
MdButtonModule,
|
||||
NgbModule.forRoot(),
|
||||
],
|
||||
declarations: [
|
||||
AppComponent,
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
export interface IExternalSettings extends ISettings {
|
||||
ssl: boolean,
|
||||
enable:boolean,
|
||||
subDir: string,
|
||||
ip: string,
|
||||
port:number,
|
||||
|
@ -20,15 +19,23 @@ export interface IOmbiSettings extends ISettings {
|
|||
|
||||
export interface IEmbySettings extends IExternalSettings {
|
||||
apiKey: string,
|
||||
enable: boolean,
|
||||
administratorId: string,
|
||||
enableEpisodeSearching:boolean,
|
||||
}
|
||||
|
||||
export interface IPlexSettings extends IExternalSettings {
|
||||
export interface IPlexSettings extends ISettings {
|
||||
|
||||
enable: boolean,
|
||||
servers : IPlexServer[]
|
||||
}
|
||||
|
||||
export interface IPlexServer extends IExternalSettings {
|
||||
name:string,
|
||||
enableEpisodeSearching: boolean,
|
||||
plexAuthToken: string,
|
||||
machineIdentifier: string,
|
||||
plexSelectedLibraries : IPlexLibraries[],
|
||||
plexSelectedLibraries: IPlexLibraries[],
|
||||
}
|
||||
|
||||
export interface IPlexLibraries {
|
||||
|
@ -39,6 +46,7 @@ export interface IPlexLibraries {
|
|||
|
||||
export interface ISonarrSettings extends IExternalSettings {
|
||||
apiKey: string,
|
||||
enable: boolean,
|
||||
qualityProfile: string,
|
||||
seasonFolders: boolean,
|
||||
rootPath: string,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<h1>Login</h1>
|
||||
<div>
|
||||
<p>
|
||||
@UI.UserLogin_Paragraph <span title="@UI.UserLogin_Paragraph_SpanHover"><i class="fa fa-question-circle"></i></span>
|
||||
Hey! Welcome, login with your credentails below!
|
||||
</p>
|
||||
</div>
|
||||
<form method="POST" id="loginForm">
|
||||
|
|
|
@ -10,100 +10,130 @@
|
|||
<label for="enable">Enable</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label for="Ip" class="control-label">Hostname or IP</label>
|
||||
<div>
|
||||
<input type="text" class="form-control form-control-custom " id="Ip" name="Ip" placeholder="localhost" [(ngModel)]="settings.ip" value="{{settings.ip}}">
|
||||
</div>
|
||||
<div style="float: right;">
|
||||
<button type="submit" (click)="addTab()" class="btn btn-success-outline">Add Server</button>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="portNumber" class="control-label">Port</label>
|
||||
<div>
|
||||
<input type="text" [(ngModel)]="settings.port" class="form-control form-control-custom " id="portNumber" name="Port" placeholder="Port Number" value="{{settings.port}}">
|
||||
</div>
|
||||
</div>
|
||||
<ngb-tabset>
|
||||
|
||||
<div *ngFor="let server of settings.servers">
|
||||
<ngb-tab [id]="server.id" [title]="server.name">
|
||||
<ng-template ngbTabContent>
|
||||
<br/>
|
||||
<br/>
|
||||
<div style="float: right;">
|
||||
<button type="submit" (click)="removeServer(server)" class="btn btn-danger-outline">Remove Server</button>
|
||||
</div>
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" id="ssl" [(ngModel)]="settings.ssl" ng-checked="settings.ssl">
|
||||
<label for="ssl">SSL</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="name" class="control-label">Server name</label>
|
||||
<div>
|
||||
<input type="text" class="form-control form-control-custom " id="name" name="name" placeholder="Server" [(ngModel)]="server.name" value="{{server.name}}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<div class="form-group">
|
||||
<label for="Ip" class="control-label">Hostname or IP</label>
|
||||
<div>
|
||||
<input type="text" class="form-control form-control-custom " id="Ip" name="Ip" placeholder="localhost" [(ngModel)]="server.ip" value="{{server.ip}}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="portNumber" class="control-label">Port</label>
|
||||
<div>
|
||||
<input type="text" [(ngModel)]="settings.port" class="form-control form-control-custom " id="portNumber" name="Port" placeholder="Port Number" value="{{server.port}}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" id="ssl" [(ngModel)]="server.ssl" ng-checked="server.ssl">
|
||||
<label for="ssl">SSL</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
|
||||
|
||||
<input type="checkbox" id="EnableTvEpisodeSearching" [(ngModel)]="settings.enableEpisodeSearching" ng-checked="settings.enableEpisodeSearching">
|
||||
<label for="EnableTvEpisodeSearching">Enable Episode Searching</label>
|
||||
<input type="checkbox" id="EnableTvEpisodeSearching" [(ngModel)]="server.enableEpisodeSearching" ng-checked="server.enableEpisodeSearching">
|
||||
<label for="EnableTvEpisodeSearching">Enable Episode Searching</label>
|
||||
|
||||
</div>
|
||||
<small>
|
||||
If enabled then we will lookup all episodes on your Plex server and store them in the local database. This will stop episode requests that already exist on Plex (that might not be in Sonarr).
|
||||
Please be aware that this is a very resource intensive process and while the Plex Episode Cacher job is running the application may appear slow (Depending on the size of your Plex library).
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
<small>
|
||||
If enabled then we will lookup all episodes on your Plex server and store them in the local database. This will stop episode requests that already exist on Plex (that might not be in Sonarr).
|
||||
Please be aware that this is a very resource intensive process and while the Plex Episode Cacher job is running the application may appear slow (Depending on the size of your Plex library).
|
||||
</small>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<label for="authToken" class="control-label">Plex Authorization Token</label>
|
||||
<div class="">
|
||||
<input type="text" class="form-control-custom form-control" id="authToken" [(ngModel)]="settings.plexAuthToken" placeholder="Plex Auth Token" value="{{settings.plexAuthToken}}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="authToken" class="control-label">Plex Authorization Token</label>
|
||||
<div class="">
|
||||
<input type="text" class="form-control-custom form-control" id="authToken" [(ngModel)]="server.plexAuthToken" placeholder="Plex Auth Token" value="{{server.plexAuthToken}}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="MachineIdentifier" class="control-label">Machine Identifier</label>
|
||||
<div class="">
|
||||
<input type="text" class="form-control-custom form-control" id="MachineIdentifier" name="MachineIdentifier" [(ngModel)]="settings.machineIdentifier" value="{{settings.machineIdentifier}}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="MachineIdentifier" class="control-label">Machine Identifier</label>
|
||||
<div class="">
|
||||
<input type="text" class="form-control-custom form-control" id="MachineIdentifier" name="MachineIdentifier" [(ngModel)]="server.machineIdentifier" value="{{server.machineIdentifier}}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="username" class="control-label">Username and Password</label>
|
||||
<div>
|
||||
<input type="text" class="form-control form-control-custom" id="username" [(ngModel)]="username" placeholder="username">
|
||||
</div>
|
||||
<br />
|
||||
<div>
|
||||
<input type="password" class="form-control form-control-custom" id="password" [(ngModel)]="password" placeholder="Password">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="">
|
||||
<button id="requestToken" (click)="requestToken()" class="btn btn-primary-outline">Request Token <i class="fa fa-key"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label>Please select the libraries you want Ombi to look in for content</label>
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button (click)="loadLibraries()" class="btn btn-primary-outline">Load Libraries <i class="fa fa-film"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="settings.plexSelectedLibraries">
|
||||
<div *ngFor="let lib of settings.plexSelectedLibraries">
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" id="{{lib.title}}" [(ngModel)]="lib.enabled" ng-checked="lib.enabled">
|
||||
<label for="{{lib.title}}">{{lib.title}}</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="username" class="control-label">Username and Password</label>
|
||||
<div>
|
||||
<input type="text" class="form-control form-control-custom" id="username" [(ngModel)]="username" placeholder="username">
|
||||
</div>
|
||||
<br/>
|
||||
<div>
|
||||
<input type="password" class="form-control form-control-custom" id="password" [(ngModel)]="password" placeholder="Password">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="">
|
||||
<button id="requestToken" (click)="requestToken()" class="btn btn-primary-outline">Request Token <i class="fa fa-key"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label>Please select the libraries you want Ombi to look in for content</label>
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button (click)="loadLibraries()" class="btn btn-primary-outline">Load Libraries <i class="fa fa-film"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="server.plexSelectedLibraries">
|
||||
<div *ngFor="let lib of server.plexSelectedLibraries">
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" id="{{lib.title}}" [(ngModel)]="lib.enabled" ng-checked="lib.enabled">
|
||||
<label for="{{lib.title}}">{{lib.title}}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button id="testPlex" type="submit" (click)="testPlex()" class="btn btn-primary-outline">
|
||||
Test Connectivity
|
||||
<div id="spinner"></div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</ngb-tab>
|
||||
</div>
|
||||
</ngb-tabset>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button id="testPlex" type="submit" (click)="testPlex()" class="btn btn-primary-outline">Test Connectivity <div id="spinner"></div></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button (click)="save()" type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { IPlexSettings, IPlexLibraries } from '../../interfaces/ISettings'
|
||||
import { IPlexSettings, IPlexLibraries, IPlexServer } from '../../interfaces/ISettings'
|
||||
|
||||
|
||||
import { SettingsService } from '../../services/settings.service';
|
||||
|
@ -21,7 +21,10 @@ export class PlexComponent implements OnInit {
|
|||
password: string;
|
||||
|
||||
ngOnInit(): void {
|
||||
this.settingsService.getPlex().subscribe(x => this.settings = x);
|
||||
this.settingsService.getPlex().subscribe(x => {
|
||||
this.settings = x;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
requestToken() {
|
||||
|
@ -32,23 +35,40 @@ export class PlexComponent implements OnInit {
|
|||
// TODO Plex Service
|
||||
}
|
||||
|
||||
loadLibraries() {
|
||||
addTab() {
|
||||
//this.settings.servers.push(<IPlexServer>{ name: "New*", id: Math.floor(Math.random() * (99999 - 0 + 1) + 1) });
|
||||
|
||||
this.notificationService.warning("Disabled", "This feature is currently disabled");
|
||||
}
|
||||
|
||||
removeServer(server: IPlexServer) {
|
||||
|
||||
this.notificationService.warning("Disabled", "This feature is currently disabled");
|
||||
//var index = this.settings.servers.indexOf(server, 0);
|
||||
//if (index > -1) {
|
||||
// this.settings.servers.splice(index, 1);
|
||||
//}
|
||||
}
|
||||
|
||||
loadLibraries(server:IPlexServer) {
|
||||
this.plexService.getLibraries(this.settings).subscribe(x => {
|
||||
|
||||
this.settings.plexSelectedLibraries = [];
|
||||
server.plexSelectedLibraries = [];
|
||||
x.mediaContainer.directory.forEach((item, index) => {
|
||||
var lib: IPlexLibraries = {
|
||||
key: item.key,
|
||||
title: item.title,
|
||||
enabled: false
|
||||
};
|
||||
this.settings.plexSelectedLibraries.push(lib);
|
||||
server.plexSelectedLibraries.push(lib);
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
save() {
|
||||
var filtered = this.settings.servers.filter(x => x.name !== "");
|
||||
this.settings.servers = filtered;
|
||||
this.settingsService.savePlex(this.settings).subscribe(x => {
|
||||
if (x) {
|
||||
this.notificationService.success("Settings Saved", "Successfully saved Plex settings");
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||
|
||||
import { AuthService } from '../auth/auth.service';
|
||||
import { AuthGuard } from '../auth/auth.guard';
|
||||
|
@ -34,7 +35,8 @@ const routes: Routes = [
|
|||
MenuModule,
|
||||
InputSwitchModule,
|
||||
InputTextModule,
|
||||
AuthModule
|
||||
AuthModule,
|
||||
NgbModule
|
||||
],
|
||||
declarations: [
|
||||
SettingsMenuComponent,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue