Added the ability to specify how many episodes we should cache at a time. #1598

pull/1614/head
tidusjar 7 years ago
parent 83d7959f5a
commit 03f7aba47e

@ -3,17 +3,14 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Hangfire; using Hangfire;
using Hangfire.Common;
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.Api.Plex.Models.Server;
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.Helpers;
using Ombi.Store.Entities; using Ombi.Store.Entities;
using Ombi.Store.Repository; using Ombi.Store.Repository;
using Serilog;
namespace Ombi.Schedule.Jobs.Plex namespace Ombi.Schedule.Jobs.Plex
{ {
@ -98,26 +95,26 @@ namespace Ombi.Schedule.Jobs.Plex
private async Task GetEpisodes(PlexServers settings, Directory section) private async Task GetEpisodes(PlexServers settings, Directory section)
{ {
// Get the first 50
var currentPosition = 0; var currentPosition = 0;
var ResultCount = 50; var resultCount = settings.EpisodeBatchSize == 0 ? 50 : settings.EpisodeBatchSize;
var episodes = await _api.GetAllEpisodes(settings.PlexAuthToken, settings.FullUri, section.key, currentPosition, ResultCount); var episodes = await _api.GetAllEpisodes(settings.PlexAuthToken, settings.FullUri, section.key, currentPosition, resultCount);
var currentData = _repo.GetAllEpisodes(); var currentData = _repo.GetAllEpisodes();
_log.LogInformation(LoggingEvents.PlexEpisodeCacher, $"Total Epsiodes found for {episodes.MediaContainer.librarySectionTitle} = {episodes.MediaContainer.totalSize}"); _log.LogInformation(LoggingEvents.PlexEpisodeCacher, $"Total Epsiodes found for {episodes.MediaContainer.librarySectionTitle} = {episodes.MediaContainer.totalSize}");
await ProcessEpsiodes(episodes, currentData); await ProcessEpsiodes(episodes, currentData);
currentPosition += ResultCount; currentPosition += resultCount;
while (currentPosition < episodes.MediaContainer.totalSize) while (currentPosition < episodes.MediaContainer.totalSize)
{ {
var ep = await _api.GetAllEpisodes(settings.PlexAuthToken, settings.FullUri, section.key, currentPosition, var ep = await _api.GetAllEpisodes(settings.PlexAuthToken, settings.FullUri, section.key, currentPosition,
ResultCount); resultCount);
await ProcessEpsiodes(ep, currentData); await ProcessEpsiodes(ep, currentData);
_log.LogInformation(LoggingEvents.PlexEpisodeCacher, $"Processed {ResultCount} more episodes. Total Remaining {currentPosition - episodes.MediaContainer.totalSize}"); _log.LogInformation(LoggingEvents.PlexEpisodeCacher, $"Processed {resultCount} more episodes. Total Remaining {episodes.MediaContainer.totalSize - currentPosition}");
currentPosition += ResultCount; currentPosition += resultCount;
} }
// we have now finished.
await _repo.SaveChangesAsync();
} }
private async Task ProcessEpsiodes(PlexContainer episodes, IQueryable<PlexEpisode> currentEpisodes) private async Task ProcessEpsiodes(PlexContainer episodes, IQueryable<PlexEpisode> currentEpisodes)

@ -18,6 +18,8 @@ namespace Ombi.Core.Settings.Models.External
public string PlexAuthToken { get; set; } public string PlexAuthToken { get; set; }
public string MachineIdentifier { get; set; } public string MachineIdentifier { get; set; }
public int EpisodeBatchSize { get; set; }
public List<PlexSelectedLibraries> PlexSelectedLibraries { get; set; } = new List<PlexSelectedLibraries>(); public List<PlexSelectedLibraries> PlexSelectedLibraries { get; set; } = new List<PlexSelectedLibraries>();
} }
public class PlexSelectedLibraries public class PlexSelectedLibraries

@ -16,6 +16,7 @@ namespace Ombi.Store.Repository
Task AddRange(IEnumerable<T> content); Task AddRange(IEnumerable<T> content);
Task DeleteRange(IEnumerable<T> req); Task DeleteRange(IEnumerable<T> req);
Task Delete(T request); Task Delete(T request);
Task<int> SaveChangesAsync();
IIncludableQueryable<TEntity, TProperty> Include<TEntity, TProperty>( IIncludableQueryable<TEntity, TProperty> Include<TEntity, TProperty>(
IQueryable<TEntity> source, Expression<Func<TEntity, TProperty>> navigationPropertyPath) IQueryable<TEntity> source, Expression<Func<TEntity, TProperty>> navigationPropertyPath)

@ -60,6 +60,11 @@ namespace Ombi.Store.Repository
await _ctx.SaveChangesAsync(); await _ctx.SaveChangesAsync();
} }
public async Task<int> SaveChangesAsync()
{
return await _ctx.SaveChangesAsync();
}
public IIncludableQueryable<TEntity, TProperty> Include<TEntity, TProperty>( public IIncludableQueryable<TEntity, TProperty> Include<TEntity, TProperty>(
IQueryable<TEntity> source, Expression<Func<TEntity, TProperty>> navigationPropertyPath) IQueryable<TEntity> source, Expression<Func<TEntity, TProperty>> navigationPropertyPath)
where TEntity : class where TEntity : class

@ -0,0 +1,46 @@
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceRoot}/bin/Debug/netcoreapp2.0/Ombi.dll",
"args": [],
"cwd": "${workspaceRoot}",
"stopAtEntry": false,
"internalConsoleOptions": "openOnSessionStart",
"launchBrowser": {
"enabled": true,
"args": "${auto-detect-url}",
"windows": {
"command": "cmd.exe",
"args": "/C start ${auto-detect-url}"
},
"osx": {
"command": "open"
},
"linux": {
"command": "xdg-open"
}
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceRoot}/Views"
}
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
}

@ -0,0 +1,16 @@
{
"version": "0.1.0",
"command": "dotnet",
"isShellCommand": true,
"args": [],
"tasks": [
{
"taskName": "build",
"args": [
"${workspaceRoot}/Ombi.csproj"
],
"isBuildCommand": true,
"problemMatcher": "$msCompile"
}
]
}

@ -32,7 +32,14 @@ export interface IDirectory {
export interface IPlexServerViewModel { export interface IPlexServerViewModel {
success: boolean; success: boolean;
message: string; message: string;
servers: IPlexServerResponse; servers: IPlexServerResult;
}
export interface IPlexServerResult {
friendlyName: string;
machineIdentifier: string;
identifier: string;
server: IPlexServerResponse[];
} }
export interface IPlexServerResponse { export interface IPlexServerResponse {

@ -45,6 +45,7 @@ export interface IPlexServer extends IExternalSettings {
enableEpisodeSearching: boolean; enableEpisodeSearching: boolean;
plexAuthToken: string; plexAuthToken: string;
machineIdentifier: string; machineIdentifier: string;
episodeBatchSize: number;
plexSelectedLibraries: IPlexLibrariesSettings[]; plexSelectedLibraries: IPlexLibrariesSettings[];
} }

@ -1,4 +1,10 @@
<settings-menu></settings-menu> <settings-menu></settings-menu>
<div class="row">
<div class="col-md-2 col-md-push-10">
<span style="vertical-align: top;">Advanced</span>
<p-inputSwitch id="customInputSwitch" [(ngModel)]="advanced"></p-inputSwitch>
</div>
</div>
<div *ngIf="settings"> <div *ngIf="settings">
<fieldset> <fieldset>
<legend>Plex Configuration</legend> <legend>Plex Configuration</legend>
@ -34,21 +40,24 @@
<div class="form-group"> <div class="form-group">
<label for="name" class="control-label">Server name</label> <label for="name" class="control-label">Server name</label>
<div> <div>
<input type="text" class="form-control form-control-custom " id="name" name="name" placeholder="Server" [(ngModel)]="server.name" value="{{server.name}}"> <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">
<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)]="server.ip" value="{{server.ip}}"> <input type="text" class="form-control form-control-custom " id="Ip" name="Ip" placeholder="localhost" [(ngModel)]="server.ip"
value="{{server.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)]="server.port" class="form-control form-control-custom " id="portNumber" name="Port" placeholder="Port Number" value="{{server.port}}"> <input type="text" [(ngModel)]="server.port" class="form-control form-control-custom " id="portNumber" name="Port" placeholder="Port Number"
value="{{server.port}}">
</div> </div>
</div> </div>
@ -59,33 +68,24 @@
</div> </div>
</div> </div>
<!--<div class="form-group">
<div class="checkbox">
<input type="checkbox" id="EnableTvEpisodeSearching" [(ngModel)]="server.enableEpisodeSearching" [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 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)]="server.plexAuthToken" placeholder="Plex Auth Token" value="{{server.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)]="server.machineIdentifier" value="{{server.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> </div>
<div class="col-md-6"> <div class="col-md-6">
<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>
@ -100,16 +100,20 @@
<div class="form-group"> <div class="form-group">
<div> <div>
<button id="requestToken" (click)="requestServers(server)" class="btn btn-primary-outline">Load Servers <i class="fa fa-key"></i></button> <button id="requestToken" (click)="requestServers(server)" class="btn btn-primary-outline">Load Servers
<i class="fa fa-key"></i>
</button>
</div> </div>
</div> </div>
<br /> <br />
<br /> <br />
<div class="form-group" *ngIf="loadedServers"> <div class="form-group" *ngIf="loadedServers">
<label for="username" class="control-label">Please select the server</label><br /> <label for="username" class="control-label">Please select the server</label>
<br />
<div class="btn-group"> <div class="btn-group">
<div class="btn-group"> <div class="btn-group">
<a [attr.disabled]="!serversButton ? true : null" href="#" class="btn btn-info-outline dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> <a [attr.disabled]="!serversButton ? true : null" href="#" class="btn btn-info-outline dropdown-toggle" data-toggle="dropdown"
aria-expanded="false">
Servers Servers
<span class="caret"></span> <span class="caret"></span>
</a> </a>
@ -128,7 +132,9 @@
<small>Note: if nothing is selected, we will monitor all libraries</small> <small>Note: if nothing is selected, we will monitor all libraries</small>
<div class="form-group"> <div class="form-group">
<div> <div>
<button (click)="loadLibraries(server)" class="btn btn-primary-outline">Load Libraries <i class="fa fa-film"></i></button> <button (click)="loadLibraries(server)" class="btn btn-primary-outline">Load Libraries
<i class="fa fa-film"></i>
</button>
</div> </div>
</div> </div>
<div *ngIf="server.plexSelectedLibraries"> <div *ngIf="server.plexSelectedLibraries">
@ -142,6 +148,14 @@
</div> </div>
</div> </div>
<div class="form-group" *ngIf="advanced">
<label for="episodeBatchSize" class="control-label">Episode Batch Size</label>
<div>
<input type="number" class="form-control-custom form-small form-control" id="episodeBatchSize" name="episodeBatchSize" [(ngModel)]="server.episodeBatchSize"
value="{{server.episodeBatchSize}}" tooltipPosition="top" pTooltip="This is used when we cache the episodes, we cache in batches of 50 by default, you can configure how many we do at a time here">
</div>
</div>
<div class="form-group"> <div class="form-group">
<div> <div>
<button id="testPlex" type="submit" (click)="testPlex(server)" class="btn btn-primary-outline"> <button id="testPlex" type="submit" (click)="testPlex(server)" class="btn btn-primary-outline">
@ -158,11 +172,11 @@
</div> </div>
</ngb-tabset> </ngb-tabset>
<div class="col-md-3"> <div class="col-md-3">
<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>
</div>
</div> </div>
</div> </div>
</div>
</fieldset> </fieldset>
</div> </div>

@ -22,6 +22,8 @@ export class PlexComponent implements OnInit, OnDestroy {
private subscriptions = new Subject<void>(); private subscriptions = new Subject<void>();
public advanced = false;
constructor(private settingsService: SettingsService, constructor(private settingsService: SettingsService,
private notificationService: NotificationService, private notificationService: NotificationService,
private plexService: PlexService, private plexService: PlexService,
@ -38,6 +40,7 @@ export class PlexComponent implements OnInit, OnDestroy {
.takeUntil(this.subscriptions) .takeUntil(this.subscriptions)
.subscribe(x => { .subscribe(x => {
if (x.success) { if (x.success) {
debugger;
this.loadedServers = x; this.loadedServers = x;
this.serversButton = true; this.serversButton = true;
this.notificationService.success("Loaded", "Found the servers! Please select one!"); this.notificationService.success("Loaded", "Found the servers! Please select one!");

Loading…
Cancel
Save