mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-19 04:49:33 -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();
|
StartTheCache(plexSettings).Wait();
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e)
|
||||||
|
{
|
||||||
Logger.LogWarning(LoggingEvents.CacherException, e, "Exception thrown when attempting to cache the Plex Content");
|
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)
|
private async Task StartTheCache(PlexSettings plexSettings)
|
||||||
{
|
{
|
||||||
var allContent = GetAllContent(plexSettings);
|
foreach (var servers in plexSettings.Servers ?? new List<PlexServers>())
|
||||||
|
|
||||||
// Let's now process this.
|
|
||||||
|
|
||||||
var contentToAdd = new List<PlexContent>();
|
|
||||||
foreach (var content in allContent)
|
|
||||||
{
|
{
|
||||||
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
|
if (content.viewGroup.Equals(PlexMediaType.Show.ToString(), StringComparison.CurrentCultureIgnoreCase))
|
||||||
foreach (var metadata in content.Metadata)
|
|
||||||
{
|
{
|
||||||
var seasonList = await PlexApi.GetSeasons(plexSettings.PlexAuthToken, plexSettings.FullUri,
|
// Process Shows
|
||||||
metadata.ratingKey);
|
foreach (var metadata in content.Metadata)
|
||||||
var seasonsContent = new List<SeasonsContent>();
|
|
||||||
foreach (var season in seasonList.MediaContainer.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),
|
seasonsContent.Add(new SeasonsContent
|
||||||
SeasonKey = int.Parse(season.ratingKey),
|
{
|
||||||
SeasonNumber = season.index
|
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;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
// Do we already have this item?
|
||||||
|
var existingContent = await Repo.GetByKey(metadata.key);
|
||||||
|
if (existingContent != null)
|
||||||
{
|
{
|
||||||
// No changes, no need to do anything
|
// Ok so we have it, let's check if there are any new seasons
|
||||||
continue;
|
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())
|
if (contentToAdd.Any())
|
||||||
{
|
{
|
||||||
await Repo.AddRange(contentToAdd);
|
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 sections = PlexApi.GetLibrarySections(plexSettings.PlexAuthToken, plexSettings.FullUri).Result;
|
||||||
|
|
||||||
var libs = new List<Mediacontainer>();
|
var libs = new List<Mediacontainer>();
|
||||||
if (sections != null)
|
if (sections != null)
|
||||||
{
|
{
|
||||||
|
@ -232,9 +238,12 @@ namespace Ombi.Schedule.Jobs
|
||||||
{
|
{
|
||||||
if (plex.Enable)
|
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;
|
return plex.Enable;
|
||||||
|
|
|
@ -2,18 +2,23 @@
|
||||||
|
|
||||||
namespace Ombi.Core.Settings.Models.External
|
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 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 bool EnableEpisodeSearching { get; set; }
|
||||||
|
|
||||||
public string PlexAuthToken { get; set; }
|
public string PlexAuthToken { get; set; }
|
||||||
public string MachineIdentifier { get; set; }
|
public string MachineIdentifier { get; set; }
|
||||||
|
|
||||||
public List<PlexSelectedLibraries> PlexSelectedLibraries { get; set; }
|
public List<PlexSelectedLibraries> PlexSelectedLibraries { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PlexSelectedLibraries
|
public class PlexSelectedLibraries
|
||||||
{
|
{
|
||||||
public int Key { get; set; }
|
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 System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
@ -28,29 +30,42 @@ namespace Ombi.Controllers.External
|
||||||
{
|
{
|
||||||
// Do we already have settings?
|
// Do we already have settings?
|
||||||
var settings = await PlexSettings.GetSettingsAsync();
|
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);
|
var result = await PlexApi.SignIn(request);
|
||||||
if (!string.IsNullOrEmpty(result.user?.authentication_token))
|
if (!string.IsNullOrEmpty(result.user?.authentication_token))
|
||||||
{
|
{
|
||||||
var server = await PlexApi.GetServer(result.user.authentication_token);
|
var server = await PlexApi.GetServer(result.user.authentication_token);
|
||||||
var firstServer = server.Server.FirstOrDefault();
|
var servers = server.Server;
|
||||||
await PlexSettings.SaveSettingsAsync(new PlexSettings
|
|
||||||
|
settings.Servers = new List<PlexServers>();
|
||||||
|
var serverNumber = 0;
|
||||||
|
foreach (var s in servers)
|
||||||
{
|
{
|
||||||
Enable = true,
|
if (string.IsNullOrEmpty(s.LocalAddresses) || string.IsNullOrEmpty(s.Port))
|
||||||
PlexAuthToken = result.user.authentication_token,
|
{
|
||||||
Ip = firstServer.LocalAddresses,
|
continue;
|
||||||
MachineIdentifier = firstServer.MachineIdentifier,
|
}
|
||||||
Port = int.Parse(firstServer.Port),
|
settings.Servers.Add(new PlexServers
|
||||||
Ssl = firstServer.Scheme != "http",
|
{
|
||||||
});
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("Libraries")]
|
[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);
|
var libs = await PlexApi.GetLibrarySections(settings.PlexAuthToken, settings.FullUri);
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ var paths = {
|
||||||
'@angular/forms',
|
'@angular/forms',
|
||||||
'@angular/platform-browser/animations',
|
'@angular/platform-browser/animations',
|
||||||
'@angular/material',
|
'@angular/material',
|
||||||
|
'@ng-bootstrap/ng-bootstrap',
|
||||||
'ngx-infinite-scroll'
|
'ngx-infinite-scroll'
|
||||||
],
|
],
|
||||||
dest: './lib'
|
dest: './lib'
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
"@angular/platform-browser-dynamic": "^4.1.0",
|
"@angular/platform-browser-dynamic": "^4.1.0",
|
||||||
"@angular/platform-server": "^4.1.0",
|
"@angular/platform-server": "^4.1.0",
|
||||||
"@angular/router": "^4.1.0",
|
"@angular/router": "^4.1.0",
|
||||||
|
"@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.25",
|
||||||
"@types/jquery": "^2.0.33",
|
"@types/jquery": "^2.0.33",
|
||||||
"@types/systemjs": "^0.20.2",
|
"@types/systemjs": "^0.20.2",
|
||||||
"angular2-jwt": "^0.2.0",
|
"angular2-jwt": "^0.2.0",
|
||||||
|
@ -27,7 +28,7 @@
|
||||||
"gulp-clean-css": "^3.0.4",
|
"gulp-clean-css": "^3.0.4",
|
||||||
"gulp-filter": "^5.0.0",
|
"gulp-filter": "^5.0.0",
|
||||||
"gulp-if": "^2.0.2",
|
"gulp-if": "^2.0.2",
|
||||||
"gulp-rename": "^1.2.2",
|
"gulp-rename": "^1.2.2",
|
||||||
"gulp-run": "^1.7.1",
|
"gulp-run": "^1.7.1",
|
||||||
"gulp-sass": "^2.3.2",
|
"gulp-sass": "^2.3.2",
|
||||||
"gulp-sourcemaps": "^1.9.0",
|
"gulp-sourcemaps": "^1.9.0",
|
||||||
|
|
|
@ -2,7 +2,8 @@ import { NgModule } from '@angular/core';
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { FormsModule } from '@angular/forms';
|
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';
|
import { AppComponent } from './app.component';
|
||||||
|
|
||||||
|
@ -75,7 +76,8 @@ const routes: Routes = [
|
||||||
AuthModule,
|
AuthModule,
|
||||||
WizardModule,
|
WizardModule,
|
||||||
DialogModule,
|
DialogModule,
|
||||||
MdButtonModule
|
MdButtonModule,
|
||||||
|
NgbModule.forRoot(),
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
export interface IExternalSettings extends ISettings {
|
export interface IExternalSettings extends ISettings {
|
||||||
ssl: boolean,
|
ssl: boolean,
|
||||||
enable:boolean,
|
|
||||||
subDir: string,
|
subDir: string,
|
||||||
ip: string,
|
ip: string,
|
||||||
port:number,
|
port:number,
|
||||||
|
@ -20,15 +19,23 @@ export interface IOmbiSettings extends ISettings {
|
||||||
|
|
||||||
export interface IEmbySettings extends IExternalSettings {
|
export interface IEmbySettings extends IExternalSettings {
|
||||||
apiKey: string,
|
apiKey: string,
|
||||||
|
enable: boolean,
|
||||||
administratorId: string,
|
administratorId: string,
|
||||||
enableEpisodeSearching:boolean,
|
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,
|
enableEpisodeSearching: boolean,
|
||||||
plexAuthToken: string,
|
plexAuthToken: string,
|
||||||
machineIdentifier: string,
|
machineIdentifier: string,
|
||||||
plexSelectedLibraries : IPlexLibraries[],
|
plexSelectedLibraries: IPlexLibraries[],
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPlexLibraries {
|
export interface IPlexLibraries {
|
||||||
|
@ -39,6 +46,7 @@ export interface IPlexLibraries {
|
||||||
|
|
||||||
export interface ISonarrSettings extends IExternalSettings {
|
export interface ISonarrSettings extends IExternalSettings {
|
||||||
apiKey: string,
|
apiKey: string,
|
||||||
|
enable: boolean,
|
||||||
qualityProfile: string,
|
qualityProfile: string,
|
||||||
seasonFolders: boolean,
|
seasonFolders: boolean,
|
||||||
rootPath: string,
|
rootPath: string,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<h1>Login</h1>
|
<h1>Login</h1>
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<form method="POST" id="loginForm">
|
<form method="POST" id="loginForm">
|
||||||
|
|
|
@ -10,100 +10,130 @@
|
||||||
<label for="enable">Enable</label>
|
<label for="enable">Enable</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="float: right;">
|
||||||
|
<button type="submit" (click)="addTab()" class="btn btn-success-outline">Add Server</button>
|
||||||
<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>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<ngb-tabset>
|
||||||
<label for="portNumber" class="control-label">Port</label>
|
|
||||||
<div>
|
<div *ngFor="let server of settings.servers">
|
||||||
<input type="text" [(ngModel)]="settings.port" class="form-control form-control-custom " id="portNumber" name="Port" placeholder="Port Number" value="{{settings.port}}">
|
<ngb-tab [id]="server.id" [title]="server.name">
|
||||||
</div>
|
<ng-template ngbTabContent>
|
||||||
</div>
|
<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="form-group">
|
||||||
<div class="checkbox">
|
<label for="name" class="control-label">Server name</label>
|
||||||
<input type="checkbox" id="ssl" [(ngModel)]="settings.ssl" ng-checked="settings.ssl">
|
<div>
|
||||||
<label for="ssl">SSL</label>
|
<input type="text" class="form-control form-control-custom " id="name" name="name" placeholder="Server" [(ngModel)]="server.name" value="{{server.name}}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="checkbox">
|
<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">
|
<input type="checkbox" id="EnableTvEpisodeSearching" [(ngModel)]="server.enableEpisodeSearching" ng-checked="server.enableEpisodeSearching">
|
||||||
<label for="EnableTvEpisodeSearching">Enable Episode Searching</label>
|
<label for="EnableTvEpisodeSearching">Enable Episode Searching</label>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<small>
|
<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).
|
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).
|
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>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="authToken" class="control-label">Plex Authorization Token</label>
|
<label for="authToken" class="control-label">Plex Authorization Token</label>
|
||||||
<div class="">
|
<div class="">
|
||||||
<input type="text" class="form-control-custom form-control" id="authToken" [(ngModel)]="settings.plexAuthToken" placeholder="Plex Auth Token" value="{{settings.plexAuthToken}}">
|
<input type="text" class="form-control-custom form-control" id="authToken" [(ngModel)]="server.plexAuthToken" placeholder="Plex Auth Token" value="{{server.plexAuthToken}}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="MachineIdentifier" class="control-label">Machine Identifier</label>
|
<label for="MachineIdentifier" class="control-label">Machine Identifier</label>
|
||||||
<div class="">
|
<div class="">
|
||||||
<input type="text" class="form-control-custom form-control" id="MachineIdentifier" name="MachineIdentifier" [(ngModel)]="settings.machineIdentifier" value="{{settings.machineIdentifier}}">
|
<input type="text" class="form-control-custom form-control" id="MachineIdentifier" name="MachineIdentifier" [(ngModel)]="server.machineIdentifier" value="{{server.machineIdentifier}}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="username" class="control-label">Username and Password</label>
|
<label for="username" class="control-label">Username and Password</label>
|
||||||
<div>
|
<div>
|
||||||
<input type="text" class="form-control form-control-custom" id="username" [(ngModel)]="username" placeholder="username">
|
<input type="text" class="form-control form-control-custom" id="username" [(ngModel)]="username" placeholder="username">
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br/>
|
||||||
<div>
|
<div>
|
||||||
<input type="password" class="form-control form-control-custom" id="password" [(ngModel)]="password" placeholder="Password">
|
<input type="password" class="form-control form-control-custom" id="password" [(ngModel)]="password" placeholder="Password">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="">
|
<div class="">
|
||||||
<button id="requestToken" (click)="requestToken()" class="btn btn-primary-outline">Request Token <i class="fa fa-key"></i></button>
|
<button id="requestToken" (click)="requestToken()" class="btn btn-primary-outline">Request Token <i class="fa fa-key"></i></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label>Please select the libraries you want Ombi to look in for content</label>
|
<label>Please select the libraries you want Ombi to look in for content</label>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div>
|
<div>
|
||||||
<button (click)="loadLibraries()" class="btn btn-primary-outline">Load Libraries <i class="fa fa-film"></i></button>
|
<button (click)="loadLibraries()" class="btn btn-primary-outline">Load Libraries <i class="fa fa-film"></i></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="settings.plexSelectedLibraries">
|
<div *ngIf="server.plexSelectedLibraries">
|
||||||
<div *ngFor="let lib of settings.plexSelectedLibraries">
|
<div *ngFor="let lib of server.plexSelectedLibraries">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<input type="checkbox" id="{{lib.title}}" [(ngModel)]="lib.enabled" ng-checked="lib.enabled">
|
<input type="checkbox" id="{{lib.title}}" [(ngModel)]="lib.enabled" ng-checked="lib.enabled">
|
||||||
<label for="{{lib.title}}">{{lib.title}}</label>
|
<label for="{{lib.title}}">{{lib.title}}</label>
|
||||||
</div>
|
</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>
|
</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 class="form-group">
|
||||||
<div>
|
<div>
|
||||||
<button (click)="save()" type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
<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 { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
import { IPlexSettings, IPlexLibraries } from '../../interfaces/ISettings'
|
import { IPlexSettings, IPlexLibraries, IPlexServer } from '../../interfaces/ISettings'
|
||||||
|
|
||||||
|
|
||||||
import { SettingsService } from '../../services/settings.service';
|
import { SettingsService } from '../../services/settings.service';
|
||||||
|
@ -21,7 +21,10 @@ export class PlexComponent implements OnInit {
|
||||||
password: string;
|
password: string;
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.settingsService.getPlex().subscribe(x => this.settings = x);
|
this.settingsService.getPlex().subscribe(x => {
|
||||||
|
this.settings = x;
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
requestToken() {
|
requestToken() {
|
||||||
|
@ -32,23 +35,40 @@ export class PlexComponent implements OnInit {
|
||||||
// TODO Plex Service
|
// 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.plexService.getLibraries(this.settings).subscribe(x => {
|
||||||
|
|
||||||
this.settings.plexSelectedLibraries = [];
|
server.plexSelectedLibraries = [];
|
||||||
x.mediaContainer.directory.forEach((item, index) => {
|
x.mediaContainer.directory.forEach((item, index) => {
|
||||||
var lib: IPlexLibraries = {
|
var lib: IPlexLibraries = {
|
||||||
key: item.key,
|
key: item.key,
|
||||||
title: item.title,
|
title: item.title,
|
||||||
enabled: false
|
enabled: false
|
||||||
};
|
};
|
||||||
this.settings.plexSelectedLibraries.push(lib);
|
server.plexSelectedLibraries.push(lib);
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
save() {
|
save() {
|
||||||
|
var filtered = this.settings.servers.filter(x => x.name !== "");
|
||||||
|
this.settings.servers = filtered;
|
||||||
this.settingsService.savePlex(this.settings).subscribe(x => {
|
this.settingsService.savePlex(this.settings).subscribe(x => {
|
||||||
if (x) {
|
if (x) {
|
||||||
this.notificationService.success("Settings Saved", "Successfully saved Plex settings");
|
this.notificationService.success("Settings Saved", "Successfully saved Plex settings");
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
|
||||||
import { AuthService } from '../auth/auth.service';
|
import { AuthService } from '../auth/auth.service';
|
||||||
import { AuthGuard } from '../auth/auth.guard';
|
import { AuthGuard } from '../auth/auth.guard';
|
||||||
|
@ -34,7 +35,8 @@ const routes: Routes = [
|
||||||
MenuModule,
|
MenuModule,
|
||||||
InputSwitchModule,
|
InputSwitchModule,
|
||||||
InputTextModule,
|
InputTextModule,
|
||||||
AuthModule
|
AuthModule,
|
||||||
|
NgbModule
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
SettingsMenuComponent,
|
SettingsMenuComponent,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue