Lots of backend work

This commit is contained in:
tidusjar 2017-05-05 01:48:48 +01:00
parent c360b79f87
commit 9dbe334562
22 changed files with 395 additions and 53 deletions

View file

@ -18,7 +18,7 @@ namespace Ombi.Api.Plex.Models
public string art { get; set; } public string art { get; set; }
public string banner { get; set; } public string banner { get; set; }
public string theme { get; set; } public string theme { get; set; }
public int duration { get; set; } public string duration { get; set; }
public string originallyAvailableAt { get; set; } public string originallyAvailableAt { get; set; }
public int leafCount { get; set; } public int leafCount { get; set; }
public int viewedLeafCount { get; set; } public int viewedLeafCount { get; set; }

View file

@ -4,9 +4,9 @@
{ {
public int id { get; set; } public int id { get; set; }
public string key { get; set; } public string key { get; set; }
public int duration { get; set; } public string duration { get; set; }
public string file { get; set; } public string file { get; set; }
public int size { get; set; } public string size { get; set; }
public string audioProfile { get; set; } public string audioProfile { get; set; }
public string container { get; set; } public string container { get; set; }
public string videoProfile { get; set; } public string videoProfile { get; set; }

View file

@ -64,14 +64,14 @@ namespace Ombi.Api.Plex
public async Task<PlexLibraries> GetLibrarySections(string authToken, string plexFullHost) public async Task<PlexLibraries> GetLibrarySections(string authToken, string plexFullHost)
{ {
var request = new Request(plexFullHost, "library/sections", HttpMethod.Get); var request = new Request("library/sections", plexFullHost, HttpMethod.Get);
AddHeaders(request, authToken); AddHeaders(request, authToken);
return await Api.Request<PlexLibraries>(request); return await Api.Request<PlexLibraries>(request);
} }
public async Task<PlexLibraries> GetLibrary(string authToken, string plexFullHost, string libraryId) public async Task<PlexLibraries> GetLibrary(string authToken, string plexFullHost, string libraryId)
{ {
var request = new Request(plexFullHost, $"library/sections/{libraryId}/all", HttpMethod.Get); var request = new Request($"library/sections/{libraryId}/all", plexFullHost, HttpMethod.Get);
AddHeaders(request, authToken); AddHeaders(request, authToken);
return await Api.Request<PlexLibraries>(request); return await Api.Request<PlexLibraries>(request);
} }
@ -89,21 +89,21 @@ namespace Ombi.Api.Plex
/// <returns></returns> /// <returns></returns>
public async Task<PlexMetadata> GetEpisodeMetaData(string authToken, string plexFullHost, string ratingKey) public async Task<PlexMetadata> GetEpisodeMetaData(string authToken, string plexFullHost, string ratingKey)
{ {
var request = new Request(plexFullHost, $"/library/metadata/{ratingKey}", HttpMethod.Get); var request = new Request($"/library/metadata/{ratingKey}", plexFullHost, HttpMethod.Get);
AddHeaders(request, authToken); AddHeaders(request, authToken);
return await Api.Request<PlexMetadata>(request); return await Api.Request<PlexMetadata>(request);
} }
public async Task<PlexMetadata> GetMetadata(string authToken, string plexFullHost, string itemId) public async Task<PlexMetadata> GetMetadata(string authToken, string plexFullHost, string itemId)
{ {
var request = new Request(plexFullHost, $"library/metadata/{itemId}", HttpMethod.Get); var request = new Request($"library/metadata/{itemId}", plexFullHost, HttpMethod.Get);
AddHeaders(request, authToken); AddHeaders(request, authToken);
return await Api.Request<PlexMetadata>(request); return await Api.Request<PlexMetadata>(request);
} }
public async Task<PlexMetadata> GetSeasons(string authToken, string plexFullHost, string ratingKey) public async Task<PlexMetadata> GetSeasons(string authToken, string plexFullHost, string ratingKey)
{ {
var request = new Request(plexFullHost, $"library/metadata/{ratingKey}/children", HttpMethod.Get); var request = new Request($"library/metadata/{ratingKey}/children", plexFullHost, HttpMethod.Get);
AddHeaders(request, authToken); AddHeaders(request, authToken);
return await Api.Request<PlexMetadata>(request); return await Api.Request<PlexMetadata>(request);
} }

View file

@ -70,6 +70,7 @@ namespace Ombi.DependencyInjection
services.AddTransient<ISettingsRepository, SettingsJsonRepository>(); services.AddTransient<ISettingsRepository, SettingsJsonRepository>();
services.AddTransient<IUserRepository, UserRepository>(); services.AddTransient<IUserRepository, UserRepository>();
services.AddTransient<ISettingsResolver, SettingsResolver>(); services.AddTransient<ISettingsResolver, SettingsResolver>();
services.AddTransient<IPlexContentRepository, PlexContentRepository>();
services.AddTransient(typeof(ISettingsService<>), typeof(SettingsServiceV2<>)); services.AddTransient(typeof(ISettingsService<>), typeof(SettingsServiceV2<>));
return services; return services;
} }

View file

@ -28,26 +28,32 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Ombi.Api.Plex; using Ombi.Api.Plex;
using Ombi.Api.Plex.Models; using Ombi.Api.Plex.Models;
using Ombi.Core.Settings; using Ombi.Core.Settings;
using Ombi.Core.Settings.Models.External; using Ombi.Core.Settings.Models.External;
using Ombi.Helpers;
using Ombi.Store.Entities;
using Ombi.Store.Repository;
namespace Ombi.Schedule.Jobs namespace Ombi.Schedule.Jobs
{ {
public partial class PlexContentCacher : IPlexContentCacher public partial class PlexContentCacher : IPlexContentCacher
{ {
public PlexContentCacher(ISettingsService<PlexSettings> plex, IPlexApi plexApi, ILogger<PlexContentCacher> logger) public PlexContentCacher(ISettingsService<PlexSettings> plex, IPlexApi plexApi, ILogger<PlexContentCacher> logger, IPlexContentRepository repo)
{ {
Plex = plex; Plex = plex;
PlexApi = plexApi; PlexApi = plexApi;
Logger = logger; Logger = logger;
Repo = repo;
} }
private ISettingsService<PlexSettings> Plex { get; } private ISettingsService<PlexSettings> Plex { get; }
private IPlexApi PlexApi { get; } private IPlexApi PlexApi { get; }
private ILogger<PlexContentCacher> Logger { get; } private ILogger<PlexContentCacher> Logger { get; }
private IPlexContentRepository Repo { get; }
public void CacheContent() public void CacheContent()
{ {
@ -63,7 +69,7 @@ namespace Ombi.Schedule.Jobs
Logger.LogInformation("Starting Plex Content Cacher"); Logger.LogInformation("Starting Plex Content Cacher");
//TODO //TODO
//var libraries = CachedLibraries(plexSettings); StartTheCache(plexSettings).Wait();
//if (libraries == null || !libraries.Any()) //if (libraries == null || !libraries.Any())
//{ //{
@ -95,7 +101,7 @@ namespace Ombi.Schedule.Jobs
// t1.seasons.AddRange(filtered); // t1.seasons.AddRange(filtered);
// } // }
// var providerId = PlexHelper.GetProviderIdFromPlexGuid(metaData.MediaContainer.); // var providerId = PlexHelper.GetProviderIdFromPlexGuid(metaData.MediaContainer);
// t1.providerId = providerId; // t1.providerId = providerId;
// } // }
// foreach (Video t1 in t.Video) // foreach (Video t1 in t.Video)
@ -110,19 +116,103 @@ namespace Ombi.Schedule.Jobs
//} //}
private List<PlexLibraries> GetLibraries(PlexSettings plexSettings) private async Task StartTheCache(PlexSettings plexSettings)
{
var allContent = GetAllContent(plexSettings);
// Let's now process this.
foreach (var content in allContent)
{
var contentToAdd = new List<PlexContent>();
if (content.viewGroup.Equals(PlexMediaType.Show.ToString(), StringComparison.CurrentCultureIgnoreCase))
{
// Process Shows
foreach (var metadata in content.Metadata)
{
var seasonList = await PlexApi.GetSeasons(plexSettings.PlexAuthToken, plexSettings.FullUri,
metadata.ratingKey);
var seasonsContent = new List<SeasonsContent>();
foreach (var season in seasonList.MediaContainer.Metadata)
{
seasonsContent.Add(new SeasonsContent
{
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
{
// 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(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);
}
}
}
}
private List<Mediacontainer> GetAllContent(PlexSettings plexSettings)
{ {
var sections = PlexApi.GetLibrarySections(plexSettings.PlexAuthToken, plexSettings.FullUri).Result; var sections = PlexApi.GetLibrarySections(plexSettings.PlexAuthToken, plexSettings.FullUri).Result;
var libs = new List<PlexLibraries>(); var libs = new List<Mediacontainer>();
if (sections != null) if (sections != null)
{ {
foreach (var dir in sections.MediaContainer.Directory ?? new List<Directory>()) foreach (var dir in sections.MediaContainer.Directory ?? new List<Directory>())
{ {
if (plexSettings.PlexSelectedLibraries.Any())
{
// Only get the enabled libs
var keys = plexSettings.PlexSelectedLibraries.Where(x => x.Enabled).Select(x => x.Key.ToString()).ToList();
if (!keys.Contains(dir.key))
{
// We are not monitoring this lib
continue;
}
}
var lib = PlexApi.GetLibrary(plexSettings.PlexAuthToken, plexSettings.FullUri, dir.key).Result; var lib = PlexApi.GetLibrary(plexSettings.PlexAuthToken, plexSettings.FullUri, dir.key).Result;
if (lib != null) if (lib != null)
{ {
libs.Add(lib); libs.Add(lib.MediaContainer);
} }
} }
} }

View file

@ -32,9 +32,8 @@ namespace Ombi.Schedule.Jobs
{ {
public enum PlexMediaType public enum PlexMediaType
{ {
Movie, Movie = 0,
Show, Show = 1
Artist
} }
} }
} }

View file

@ -1,4 +1,6 @@
namespace Ombi.Core.Settings.Models.External using System.Collections.Generic;
namespace Ombi.Core.Settings.Models.External
{ {
public sealed class PlexSettings : ExternalSettings public sealed class PlexSettings : ExternalSettings
{ {
@ -8,5 +10,14 @@
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 class PlexSelectedLibraries
{
public int Key { get; set; }
public string Title { get; set; } // Name is for display purposes
public bool Enabled { get; set; }
} }
} }

View file

@ -13,6 +13,7 @@ namespace Ombi.Store.Context
Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken)); Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken));
DbSet<RequestBlobs> Requests { get; set; } DbSet<RequestBlobs> Requests { get; set; }
DbSet<GlobalSettings> Settings { get; set; } DbSet<GlobalSettings> Settings { get; set; }
DbSet<PlexContent> PlexContent { get; set; }
DbSet<User> Users { get; set; } DbSet<User> Users { get; set; }
EntityEntry<GlobalSettings> Entry(GlobalSettings settings); EntityEntry<GlobalSettings> Entry(GlobalSettings settings);
EntityEntry<TEntity> Attach<TEntity>(TEntity entity) where TEntity : class; EntityEntry<TEntity> Attach<TEntity>(TEntity entity) where TEntity : class;

View file

@ -17,9 +17,13 @@ namespace Ombi.Store.Context
} }
public DbSet<RequestBlobs> Requests { get; set; } public DbSet<RequestBlobs> Requests { get; set; }
public DbSet<GlobalSettings> Settings { get; set; } public DbSet<GlobalSettings> Settings { get; set; }
public DbSet<User> Users { get; set; } public DbSet<User> Users { get; set; }
public DbSet<PlexContent> PlexContent { get; set; }
public EntityEntry<GlobalSettings> Entry(GlobalSettings settings) public EntityEntry<GlobalSettings> Entry(GlobalSettings settings)
{ {
return Entry(settings); return Entry(settings);

View file

@ -0,0 +1,68 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2017 Jamie Rees
// File: PlexContent.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace Ombi.Store.Entities
{
[Table("PlexContent")]
public class PlexContent : Entity
{
public string Title { get; set; }
public string ReleaseYear { get; set; }
public string ProviderId { get; set; }
public PlexMediaTypeEntity Type { get; set; }
public string Url { get; set; }
/// <summary>
/// Only used for TV Shows
/// </summary>
public List<SeasonsContent> Seasons { get; set; }
/// <summary>
/// Plex's internal ID for this item
/// </summary>
public string Key { get; set; }
public DateTime AddedAt { get; set; }
}
public class SeasonsContent : Entity
{
public int SeasonNumber { get; set; }
public int SeasonKey { get; set; }
public int ParentKey { get; set; }
}
public enum PlexMediaTypeEntity
{
Movie = 0,
Show = 1
}
}

View file

@ -2,11 +2,11 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework> <TargetFramework>netstandard1.6</TargetFramework>
<!--<NetStandardImplicitPackageVersion>1.6.1</NetStandardImplicitPackageVersion>-->
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="1.1.1" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="1.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="1.1.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="1.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="1.1.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="1.1.1" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="10.0.2" />

View file

@ -0,0 +1,16 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Ombi.Store.Entities;
namespace Ombi.Store.Repository
{
public interface IPlexContentRepository
{
Task<PlexContent> Add(PlexContent content);
Task<bool> ContentExists(string providerId);
Task<IEnumerable<PlexContent>> GetAll();
Task<PlexContent> Get(string providerId);
Task<PlexContent> GetByKey(string key);
Task Update(PlexContent existingContent);
}
}

View file

@ -0,0 +1,79 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2017 Jamie Rees
// File: PlexContentRepository.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Ombi.Store.Context;
using Ombi.Store.Entities;
namespace Ombi.Store.Repository
{
public class PlexContentRepository : IPlexContentRepository
{
public PlexContentRepository(IOmbiContext db)
{
Db = db;
}
private IOmbiContext Db { get; }
public async Task<IEnumerable<PlexContent>> GetAll()
{
return await Db.PlexContent.ToListAsync();
}
public async Task<bool> ContentExists(string providerId)
{
return await Db.PlexContent.AnyAsync(x => x.ProviderId == providerId);
}
public async Task<PlexContent> Add(PlexContent content)
{
await Db.PlexContent.AddAsync(content);
await Db.SaveChangesAsync();
return content;
}
public async Task<PlexContent> Get(string providerId)
{
return await Db.PlexContent.FirstOrDefaultAsync(x => x.ProviderId == providerId);
}
public async Task<PlexContent> GetByKey(string key)
{
return await Db.PlexContent.FirstOrDefaultAsync(x => x.Key == key);
}
public async Task Update(PlexContent existingContent)
{
Db.PlexContent.Update(existingContent);
await Db.SaveChangesAsync();
}
}
}

View file

@ -18,3 +18,4 @@ npm-debug.log
testem.log testem.log
#/typings #/typings
/systemjs.config.js* /systemjs.config.js*
/Logs/**

View file

@ -49,6 +49,14 @@ namespace Ombi.Controllers.External
return result; return result;
} }
[HttpPost("Libraries")]
public async Task<PlexLibraries> GetPlexLibraries([FromBody] PlexSettings settings)
{
var libs = await PlexApi.GetLibrarySections(settings.PlexAuthToken, settings.FullUri);
return libs;
}
} }
} }

View file

@ -21,7 +21,7 @@
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.1" /> <PackageReference Include="Microsoft.AspNetCore" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="1.1.1" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" /> <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="1.1.0" /> <PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.1" /> <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="1.1.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="1.1.1" />

View file

@ -59,10 +59,10 @@ namespace Ombi
// Add framework services. // Add framework services.
services.AddMvc(); services.AddMvc();
services.AddOmbiMappingProfile(); services.AddOmbiMappingProfile();
//services.AddAutoMapper(expression => services.AddAutoMapper(expression =>
//{ {
// expression.AddCollectionMappers(); expression.AddCollectionMappers();
//}); });
services.RegisterDependencies(); // Ioc and EF services.RegisterDependencies(); // Ioc and EF
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

View file

@ -10,3 +10,16 @@ export interface IPlexUser {
title: string, title: string,
authentication_token: string, authentication_token: string,
} }
export interface IPlexLibraries {
mediaContainer:IMediaContainer;
}
export interface IMediaContainer {
directory:IDirectory[];
}
export interface IDirectory {
key: string,
title: string,
}

View file

@ -7,7 +7,7 @@ export interface IExternalSettings extends ISettings {
enable:boolean, enable:boolean,
subDir: string, subDir: string,
ip: string, ip: string,
port:number port:number,
} }
export interface IOmbiSettings extends ISettings { export interface IOmbiSettings extends ISettings {
@ -21,13 +21,20 @@ export interface IOmbiSettings extends ISettings {
export interface IEmbySettings extends IExternalSettings { export interface IEmbySettings extends IExternalSettings {
apiKey: string, apiKey: string,
administratorId: string, administratorId: string,
enableEpisodeSearching:boolean enableEpisodeSearching:boolean,
} }
export interface IPlexSettings extends IExternalSettings { export interface IPlexSettings extends IExternalSettings {
enableEpisodeSearching: boolean, enableEpisodeSearching: boolean,
plexAuthToken: string, plexAuthToken: string,
machineIdentifier: string machineIdentifier: string,
plexSelectedLibraries : IPlexLibraries[],
}
export interface IPlexLibraries {
key: string,
title: string,
enabled:boolean,
} }
export interface ISonarrSettings extends IExternalSettings { export interface ISonarrSettings extends IExternalSettings {
@ -35,7 +42,7 @@ export interface ISonarrSettings extends IExternalSettings {
qualityProfile: string, qualityProfile: string,
seasonFolders: boolean, seasonFolders: boolean,
rootPath: string, rootPath: string,
fullRootPath:string fullRootPath:string,
} }
export interface ILandingPageSettings extends ISettings { export interface ILandingPageSettings extends ISettings {
@ -52,5 +59,5 @@ export interface ILandingPageSettings extends ISettings {
export interface ICustomizationSettings extends ISettings { export interface ICustomizationSettings extends ISettings {
applicationName: string, applicationName: string,
logo:string logo:string,
} }

View file

@ -1,20 +1,27 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Http } from '@angular/http'; import { Http } from '@angular/http'
import { AuthHttp } from 'angular2-jwt';;
import { Observable } from 'rxjs/Rx'; import { Observable } from 'rxjs/Rx';
import { ServiceHelpers } from '../service.helpers'; import { ServiceAuthHelpers } from '../service.helpers';
import { IPlexAuthentication } from '../../interfaces/IPlex' import { IPlexAuthentication, IPlexLibraries} from '../../interfaces/IPlex';
import { IPlexSettings } from '../../interfaces/ISettings';
@Injectable() @Injectable()
export class PlexService extends ServiceHelpers { export class PlexService extends ServiceAuthHelpers {
constructor(http: Http) { constructor(http: AuthHttp, private regularHttp: Http) {
super(http, '/api/v1/Plex/'); super(http, '/api/v1/Plex/');
} }
logIn(login: string, password: string): Observable<IPlexAuthentication> { logIn(login: string, password: string): Observable<IPlexAuthentication> {
return this.http.post(`${this.url}/`, JSON.stringify({ login: login, password:password}), { headers: this.headers }).map(this.extractData); return this.regularHttp.post(`${this.url}`, JSON.stringify({ login: login, password:password}), { headers: this.headers }).map(this.extractData);
}
getLibraries(plexSettings: IPlexSettings): Observable<IPlexLibraries> {
return this.http.post(`${this.url}Libraries`, JSON.stringify(plexSettings), { headers: this.headers }).map(this.extractData);
} }
} }

View file

@ -3,36 +3,36 @@
<div *ngIf="settings"> <div *ngIf="settings">
<fieldset> <fieldset>
<legend>Plex Configuration</legend> <legend>Plex Configuration</legend>
<div class="form-group"> <div class="form-group">
<div class="checkbox"> <div class="checkbox">
<input type="checkbox" [(ngModel)]="settings.enable" ng-checked="settings.enable"> <input type="checkbox" [(ngModel)]="settings.enable" ng-checked="settings.enable">
<label for="enable">Enable</label> <label for="enable">Enable</label>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="Ip" class="control-label">Hostname or IP</label> <label for="Ip" class="control-label">Hostname or IP</label>
<div> <div>
<input type="text" class="form-control form-control-custom " id="Ip" name="Ip" placeholder="localhost" [(ngModel)]="settings.ip" value="{{settings.ip}}"> <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>
<div class="form-group"> <div class="form-group">
<label for="portNumber" class="control-label">Port</label> <label for="portNumber" class="control-label">Port</label>
<div> <div>
<input type="text" [(ngModel)]="settings.port" class="form-control form-control-custom " id="portNumber" name="Port" placeholder="Port Number" value="{{settings.port}}"> <input type="text" [(ngModel)]="settings.port" class="form-control form-control-custom " id="portNumber" name="Port" placeholder="Port Number" value="{{settings.port}}">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="checkbox"> <div class="checkbox">
<input type="checkbox" id="ssl" [(ngModel)]="settings.ssl" ng-checked="settings.ssl"> <input type="checkbox" id="ssl" [(ngModel)]="settings.ssl" ng-checked="settings.ssl">
<label for="ssl">SSL</label> <label for="ssl">SSL</label>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="checkbox"> <div class="checkbox">
@ -46,22 +46,22 @@
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)]="settings.plexAuthToken" placeholder="Plex Auth Token" value="{{settings.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)]="settings.machineIdentifier" value="{{settings.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>
@ -69,7 +69,7 @@
</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">
@ -77,6 +77,24 @@
<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>
<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>
</div>
</div>
<div class="form-group"> <div class="form-group">
<div> <div>
@ -84,7 +102,7 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div> <div>

View file

@ -1,7 +1,10 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { IPlexSettings } from '../../interfaces/ISettings' import { IPlexSettings, IPlexLibraries } from '../../interfaces/ISettings'
import { SettingsService } from '../../services/settings.service'; import { SettingsService } from '../../services/settings.service';
import { PlexService } from '../../services/applications/plex.service';
import { NotificationService } from "../../services/notification.service"; import { NotificationService } from "../../services/notification.service";
@Component({ @Component({
@ -11,11 +14,11 @@ import { NotificationService } from "../../services/notification.service";
}) })
export class PlexComponent implements OnInit { export class PlexComponent implements OnInit {
constructor(private settingsService: SettingsService, private notificationService: NotificationService) { } constructor(private settingsService: SettingsService, private notificationService: NotificationService, private plexService: PlexService) { }
settings: IPlexSettings; settings: IPlexSettings;
username: string; username: string;
password:string; password: string;
ngOnInit(): void { ngOnInit(): void {
this.settingsService.getPlex().subscribe(x => this.settings = x); this.settingsService.getPlex().subscribe(x => this.settings = x);
@ -29,6 +32,22 @@ export class PlexComponent implements OnInit {
// TODO Plex Service // TODO Plex Service
} }
loadLibraries() {
this.plexService.getLibraries(this.settings).subscribe(x => {
this.settings.plexSelectedLibraries = [];
x.mediaContainer.directory.forEach((item, index) => {
var lib: IPlexLibraries = {
key: item.key,
title: item.title,
enabled: false
};
this.settings.plexSelectedLibraries.push(lib);
});
});
}
save() { save() {
this.settingsService.savePlex(this.settings).subscribe(x => { this.settingsService.savePlex(this.settings).subscribe(x => {
if (x) { if (x) {