mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-14 01:02:57 -07:00
Added the ability to specify how many episodes we should cache at a time. #1598
This commit is contained in:
parent
83d7959f5a
commit
03f7aba47e
10 changed files with 129 additions and 37 deletions
|
@ -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
|
||||||
|
|
46
src/Ombi/.vscode/launch.json
vendored
Normal file
46
src/Ombi/.vscode/launch.json
vendored
Normal file
|
@ -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}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
16
src/Ombi/.vscode/tasks.json
vendored
Normal file
16
src/Ombi/.vscode/tasks.json
vendored
Normal file
|
@ -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,29 +68,20 @@
|
||||||
</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>
|
||||||
|
@ -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…
Add table
Add a link
Reference in a new issue