mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-12 08:16:05 -07:00
Rules changes and rework
This commit is contained in:
parent
d5ec429893
commit
9f4a8902f9
32 changed files with 2804 additions and 35 deletions
22
src/Ombi.Core.Tests/DbHelper.cs
Normal file
22
src/Ombi.Core.Tests/DbHelper.cs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Moq;
|
||||||
|
|
||||||
|
namespace Ombi.Core.Tests
|
||||||
|
{
|
||||||
|
public static class DbHelper
|
||||||
|
{
|
||||||
|
public static DbSet<T> GetQueryableMockDbSet<T>(params T[] sourceList) where T : class
|
||||||
|
{
|
||||||
|
var queryable = sourceList.AsQueryable();
|
||||||
|
|
||||||
|
var dbSet = new Mock<DbSet<T>>();
|
||||||
|
dbSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(queryable.Provider);
|
||||||
|
dbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(queryable.Expression);
|
||||||
|
dbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
|
||||||
|
dbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(queryable.GetEnumerator());
|
||||||
|
|
||||||
|
return dbSet.Object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
56
src/Ombi.Core.Tests/Rule/Search/RadarrCacheRuleTests.cs
Normal file
56
src/Ombi.Core.Tests/Rule/Search/RadarrCacheRuleTests.cs
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
using Moq;
|
||||||
|
using Ombi.Core.Models.Search;
|
||||||
|
using Ombi.Core.Rule.Rules.Search;
|
||||||
|
using Ombi.Store.Context;
|
||||||
|
using Ombi.Store.Entities;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Ombi.Core.Tests.Rule.Search
|
||||||
|
{
|
||||||
|
public class RadarrCacheRuleTests
|
||||||
|
{
|
||||||
|
public RadarrCacheRuleTests()
|
||||||
|
{
|
||||||
|
ContextMock = new Mock<IOmbiContext>();
|
||||||
|
Rule = new RadarrCacheRule(ContextMock.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RadarrCacheRule Rule { get; }
|
||||||
|
private Mock<IOmbiContext> ContextMock { get; }
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Should_ReturnApproved_WhenMovieIsInRadarr()
|
||||||
|
{
|
||||||
|
var list = DbHelper.GetQueryableMockDbSet(new RadarrCache
|
||||||
|
{
|
||||||
|
TheMovieDbId = 123
|
||||||
|
});
|
||||||
|
|
||||||
|
ContextMock.Setup(x => x.RadarrCache).Returns(list);
|
||||||
|
|
||||||
|
var request = new SearchMovieViewModel { Id = 123 };
|
||||||
|
var result = Rule.Execute(request);
|
||||||
|
|
||||||
|
Assert.Equal(result.Success, true);
|
||||||
|
Assert.Equal(request.Approved, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Should_ReturnNotApproved_WhenMovieIsNotInRadarr()
|
||||||
|
{
|
||||||
|
var list = DbHelper.GetQueryableMockDbSet(new RadarrCache
|
||||||
|
{
|
||||||
|
TheMovieDbId = 000012
|
||||||
|
});
|
||||||
|
|
||||||
|
ContextMock.Setup(x => x.RadarrCache).Returns(list);
|
||||||
|
|
||||||
|
var request = new SearchMovieViewModel { Id = 123 };
|
||||||
|
var result = Rule.Execute(request);
|
||||||
|
|
||||||
|
Assert.Equal(result.Success, true);
|
||||||
|
Assert.Equal(request.Approved, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ using Ombi.Store.Entities;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
|
using Ombi.Core.Models.Search;
|
||||||
|
|
||||||
namespace Ombi.Core.Engine.Interfaces
|
namespace Ombi.Core.Engine.Interfaces
|
||||||
{
|
{
|
||||||
|
@ -57,10 +58,16 @@ namespace Ombi.Core.Engine.Interfaces
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<RuleResult> RunRules(BaseRequestModel model)
|
public IEnumerable<RuleResult> RunRequestRules(BaseRequestModel model)
|
||||||
{
|
{
|
||||||
var ruleResults = Rules.StartRequestRules(model).ToList();
|
var ruleResults = Rules.StartRequestRules(model).ToList();
|
||||||
return ruleResults;
|
return ruleResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<RuleResult> RunSearchRules(SearchViewModel model)
|
||||||
|
{
|
||||||
|
var ruleResults = Rules.StartSearchRules(model).ToList();
|
||||||
|
return ruleResults;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -97,7 +97,7 @@ namespace Ombi.Core.Engine
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var ruleResults = RunRules(requestModel).ToList();
|
var ruleResults = RunRequestRules(requestModel).ToList();
|
||||||
if (ruleResults.Any(x => !x.Success))
|
if (ruleResults.Any(x => !x.Success))
|
||||||
return new RequestEngineResult
|
return new RequestEngineResult
|
||||||
{
|
{
|
||||||
|
|
|
@ -135,6 +135,7 @@ namespace Ombi.Core.Engine
|
||||||
Dictionary<int, MovieRequestModel> existingRequests, PlexSettings plexSettings, EmbySettings embySettings)
|
Dictionary<int, MovieRequestModel> existingRequests, PlexSettings plexSettings, EmbySettings embySettings)
|
||||||
{
|
{
|
||||||
var showInfo = await MovieApi.GetMovieInformation(viewMovie.Id);
|
var showInfo = await MovieApi.GetMovieInformation(viewMovie.Id);
|
||||||
|
viewMovie.Id = showInfo.Id; // TheMovieDbId
|
||||||
if (plexSettings.Enable)
|
if (plexSettings.Enable)
|
||||||
{
|
{
|
||||||
var item = await PlexContentRepo.Get(showInfo.ImdbId);
|
var item = await PlexContentRepo.Get(showInfo.ImdbId);
|
||||||
|
@ -178,6 +179,8 @@ namespace Ombi.Core.Engine
|
||||||
viewMovie.Available = requestedMovie.Available;
|
viewMovie.Available = requestedMovie.Available;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RunSearchRules(viewMovie);
|
||||||
|
|
||||||
return viewMovie;
|
return viewMovie;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,30 +97,45 @@ namespace Ombi.Core.Engine
|
||||||
{
|
{
|
||||||
var latest = showInfo.Season.OrderBy(x => x.SeasonNumber).FirstOrDefault();
|
var latest = showInfo.Season.OrderBy(x => x.SeasonNumber).FirstOrDefault();
|
||||||
foreach (var modelSeasonRequest in childRequest.SeasonRequests)
|
foreach (var modelSeasonRequest in childRequest.SeasonRequests)
|
||||||
|
{
|
||||||
if (modelSeasonRequest.SeasonNumber == latest.SeasonNumber)
|
if (modelSeasonRequest.SeasonNumber == latest.SeasonNumber)
|
||||||
|
{
|
||||||
foreach (var episodesRequested in modelSeasonRequest.Episodes)
|
foreach (var episodesRequested in modelSeasonRequest.Episodes)
|
||||||
|
{
|
||||||
episodesRequested.Requested = true;
|
episodesRequested.Requested = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (tv.FirstSeason)
|
if (tv.FirstSeason)
|
||||||
{
|
{
|
||||||
var first = showInfo.Season.OrderByDescending(x => x.SeasonNumber).FirstOrDefault();
|
var first = showInfo.Season.OrderByDescending(x => x.SeasonNumber).FirstOrDefault();
|
||||||
foreach (var modelSeasonRequest in childRequest.SeasonRequests)
|
foreach (var modelSeasonRequest in childRequest.SeasonRequests)
|
||||||
|
{
|
||||||
if (modelSeasonRequest.SeasonNumber == first.SeasonNumber)
|
if (modelSeasonRequest.SeasonNumber == first.SeasonNumber)
|
||||||
|
{
|
||||||
foreach (var episodesRequested in modelSeasonRequest.Episodes)
|
foreach (var episodesRequested in modelSeasonRequest.Episodes)
|
||||||
|
{
|
||||||
episodesRequested.Requested = true;
|
episodesRequested.Requested = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var ruleResults = RunRules(model).ToList();
|
var ruleResults = RunRequestRules(model).ToList();
|
||||||
if (ruleResults.Any(x => !x.Success))
|
if (ruleResults.Any(x => !x.Success))
|
||||||
|
{
|
||||||
return new RequestEngineResult
|
return new RequestEngineResult
|
||||||
{
|
{
|
||||||
ErrorMessage = ruleResults.FirstOrDefault(x => !string.IsNullOrEmpty(x.Message)).Message
|
ErrorMessage = ruleResults.FirstOrDefault(x => !string.IsNullOrEmpty(x.Message)).Message
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
var existingRequest = await TvRequestService.CheckRequestAsync(model.Id);
|
var existingRequest = await TvRequestService.CheckRequestAsync(model.Id);
|
||||||
if (existingRequest != null)
|
if (existingRequest != null)
|
||||||
|
{
|
||||||
return await AddExistingRequest(model, existingRequest);
|
return await AddExistingRequest(model, existingRequest);
|
||||||
|
}
|
||||||
// This is a new request
|
// This is a new request
|
||||||
return await AddRequest(model);
|
return await AddRequest(model);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ namespace Ombi.Core.Models.Search
|
||||||
public bool Adult { get; set; }
|
public bool Adult { get; set; }
|
||||||
public string BackdropPath { get; set; }
|
public string BackdropPath { get; set; }
|
||||||
public List<int> GenreIds { get; set; }
|
public List<int> GenreIds { get; set; }
|
||||||
public int Id { get; set; }
|
|
||||||
public string OriginalLanguage { get; set; }
|
public string OriginalLanguage { get; set; }
|
||||||
public string OriginalTitle { get; set; }
|
public string OriginalTitle { get; set; }
|
||||||
public string Overview { get; set; }
|
public string Overview { get; set; }
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
{
|
{
|
||||||
public class SearchViewModel
|
public class SearchViewModel
|
||||||
{
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
public bool Approved { get; set; }
|
public bool Approved { get; set; }
|
||||||
public bool Requested { get; set; }
|
public bool Requested { get; set; }
|
||||||
public bool Available { get; set; }
|
public bool Available { get; set; }
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
<ProjectReference Include="..\Ombi.Api.TvMaze\Ombi.Api.TvMaze.csproj" />
|
<ProjectReference Include="..\Ombi.Api.TvMaze\Ombi.Api.TvMaze.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Helpers\Ombi.Helpers.csproj" />
|
<ProjectReference Include="..\Ombi.Helpers\Ombi.Helpers.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Notifications\Ombi.Notifications.csproj" />
|
<ProjectReference Include="..\Ombi.Notifications\Ombi.Notifications.csproj" />
|
||||||
|
<ProjectReference Include="..\Ombi.Schedule\Ombi.Schedule.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Settings\Ombi.Settings.csproj" />
|
<ProjectReference Include="..\Ombi.Settings\Ombi.Settings.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Store\Ombi.Store.csproj" />
|
<ProjectReference Include="..\Ombi.Store\Ombi.Store.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.TheMovieDbApi\Ombi.Api.TheMovieDb.csproj" />
|
<ProjectReference Include="..\Ombi.TheMovieDbApi\Ombi.Api.TheMovieDb.csproj" />
|
||||||
|
|
15
src/Ombi.Core/Rule/BaseRequestRule.cs
Normal file
15
src/Ombi.Core/Rule/BaseRequestRule.cs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
namespace Ombi.Core.Rule
|
||||||
|
{
|
||||||
|
public abstract class BaseRequestRule
|
||||||
|
{
|
||||||
|
public RuleResult Success()
|
||||||
|
{
|
||||||
|
return new RuleResult {Success = true};
|
||||||
|
}
|
||||||
|
|
||||||
|
public RuleResult Fail(string message)
|
||||||
|
{
|
||||||
|
return new RuleResult {Message = message};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
namespace Ombi.Core.Rule
|
namespace Ombi.Core.Rule
|
||||||
{
|
{
|
||||||
public abstract class BaseRule
|
public abstract class BaseSearchRule
|
||||||
{
|
{
|
||||||
public RuleResult Success()
|
public RuleResult Success()
|
||||||
{
|
{
|
|
@ -1,9 +1,8 @@
|
||||||
using Ombi.Core.Models.Requests;
|
using Ombi.Core.Models.Requests;
|
||||||
using Ombi.Core.Rule;
|
|
||||||
|
|
||||||
namespace Ombi.Core.Rules
|
namespace Ombi.Core.Rule.Interfaces
|
||||||
{
|
{
|
||||||
public interface IRequestRules<T> where T : BaseRequestModel
|
public interface IRequestRules<T> where T : new()
|
||||||
{
|
{
|
||||||
RuleResult Execute(T obj);
|
RuleResult Execute(T obj);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
using Ombi.Core.Models.Requests;
|
using Ombi.Core.Models.Requests;
|
||||||
using Ombi.Core.Rule;
|
using Ombi.Core.Rule;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Ombi.Core.Models.Search;
|
||||||
|
|
||||||
namespace Ombi.Core.Rules
|
namespace Ombi.Core.Rules
|
||||||
{
|
{
|
||||||
public interface IRuleEvaluator
|
public interface IRuleEvaluator
|
||||||
{
|
{
|
||||||
IEnumerable<RuleResult> StartRequestRules(BaseRequestModel obj);
|
IEnumerable<RuleResult> StartRequestRules(BaseRequestModel obj);
|
||||||
|
IEnumerable<RuleResult> StartSearchRules(SearchViewModel obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,6 +4,8 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using Ombi.Core.Models.Search;
|
||||||
|
using Ombi.Core.Rule.Interfaces;
|
||||||
|
|
||||||
namespace Ombi.Core.Rule
|
namespace Ombi.Core.Rule
|
||||||
{
|
{
|
||||||
|
@ -12,12 +14,15 @@ namespace Ombi.Core.Rule
|
||||||
public RuleEvaluator(IServiceProvider provider)
|
public RuleEvaluator(IServiceProvider provider)
|
||||||
{
|
{
|
||||||
RequestRules = new List<IRequestRules<BaseRequestModel>>();
|
RequestRules = new List<IRequestRules<BaseRequestModel>>();
|
||||||
var baseType = typeof(BaseRule).FullName;
|
SearchRules = new List<IRequestRules<SearchViewModel>>();
|
||||||
|
var baseSearchType = typeof(BaseSearchRule).FullName;
|
||||||
|
var baseRequestType = typeof(BaseRequestRule).FullName;
|
||||||
|
|
||||||
var ass = typeof(RuleEvaluator).GetTypeInfo().Assembly;
|
var ass = typeof(RuleEvaluator).GetTypeInfo().Assembly;
|
||||||
|
|
||||||
foreach (var ti in ass.DefinedTypes)
|
foreach (var ti in ass.DefinedTypes)
|
||||||
if (ti?.BaseType?.FullName == baseType)
|
{
|
||||||
|
if (ti?.BaseType?.FullName == baseSearchType)
|
||||||
{
|
{
|
||||||
var type = ti?.AsType();
|
var type = ti?.AsType();
|
||||||
var ctors = type.GetConstructors();
|
var ctors = type.GetConstructors();
|
||||||
|
@ -25,14 +30,37 @@ namespace Ombi.Core.Rule
|
||||||
|
|
||||||
var services = new List<object>();
|
var services = new List<object>();
|
||||||
foreach (var param in ctor.GetParameters())
|
foreach (var param in ctor.GetParameters())
|
||||||
|
{
|
||||||
services.Add(provider.GetService(param.ParameterType));
|
services.Add(provider.GetService(param.ParameterType));
|
||||||
|
}
|
||||||
|
|
||||||
var item = Activator.CreateInstance(type, services.ToArray()); // ti.GetType is wrong
|
var item = Activator.CreateInstance(type, services.ToArray());
|
||||||
RequestRules.Add((IRequestRules<BaseRequestModel>) item);
|
RequestRules.Add((IRequestRules<BaseRequestModel>) item);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var ti in ass.DefinedTypes)
|
||||||
|
{
|
||||||
|
if (ti?.BaseType?.FullName == baseRequestType)
|
||||||
|
{
|
||||||
|
var type = ti?.AsType();
|
||||||
|
var ctors = type.GetConstructors();
|
||||||
|
var ctor = ctors.FirstOrDefault();
|
||||||
|
|
||||||
|
var services = new List<object>();
|
||||||
|
foreach (var param in ctor.GetParameters())
|
||||||
|
{
|
||||||
|
services.Add(provider.GetService(param.ParameterType));
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = Activator.CreateInstance(type, services.ToArray());
|
||||||
|
SearchRules.Add((IRequestRules<SearchViewModel>) item);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<IRequestRules<BaseRequestModel>> RequestRules { get; }
|
private List<IRequestRules<BaseRequestModel>> RequestRules { get; }
|
||||||
|
private List<IRequestRules<SearchViewModel>> SearchRules { get; }
|
||||||
|
|
||||||
public IEnumerable<RuleResult> StartRequestRules(BaseRequestModel obj)
|
public IEnumerable<RuleResult> StartRequestRules(BaseRequestModel obj)
|
||||||
{
|
{
|
||||||
|
@ -45,5 +73,17 @@ namespace Ombi.Core.Rule
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<RuleResult> StartSearchRules(SearchViewModel obj)
|
||||||
|
{
|
||||||
|
var results = new List<RuleResult>();
|
||||||
|
foreach (var rule in SearchRules)
|
||||||
|
{
|
||||||
|
var result = rule.Execute(obj);
|
||||||
|
results.Add(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,10 +3,11 @@ using Ombi.Core.Models.Requests;
|
||||||
using Ombi.Core.Rules;
|
using Ombi.Core.Rules;
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Store.Entities;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
|
using Ombi.Core.Rule.Interfaces;
|
||||||
|
|
||||||
namespace Ombi.Core.Rule.Rules
|
namespace Ombi.Core.Rule.Rules
|
||||||
{
|
{
|
||||||
public class AutoApproveRule : BaseRule, IRequestRules<BaseRequestModel>
|
public class AutoApproveRule : BaseRequestRule, IRequestRules<BaseRequestModel>
|
||||||
{
|
{
|
||||||
public AutoApproveRule(IPrincipal principal)
|
public AutoApproveRule(IPrincipal principal)
|
||||||
{
|
{
|
|
@ -3,10 +3,11 @@ using Ombi.Core.Models.Requests;
|
||||||
using Ombi.Core.Rules;
|
using Ombi.Core.Rules;
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Store.Entities;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
|
using Ombi.Core.Rule.Interfaces;
|
||||||
|
|
||||||
namespace Ombi.Core.Rule.Rules
|
namespace Ombi.Core.Rule.Rules
|
||||||
{
|
{
|
||||||
public class CanRequestRule : BaseRule, IRequestRules<BaseRequestModel>
|
public class CanRequestRule : BaseRequestRule, IRequestRules<BaseRequestModel>
|
||||||
{
|
{
|
||||||
public CanRequestRule(IPrincipal principal)
|
public CanRequestRule(IPrincipal principal)
|
||||||
{
|
{
|
31
src/Ombi.Core/Rule/Rules/Search/RadarrCacheRule.cs
Normal file
31
src/Ombi.Core/Rule/Rules/Search/RadarrCacheRule.cs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
using System.Linq;
|
||||||
|
using Ombi.Core.Models.Requests;
|
||||||
|
using Ombi.Core.Models.Search;
|
||||||
|
using Ombi.Core.Rule.Interfaces;
|
||||||
|
using Ombi.Store.Context;
|
||||||
|
|
||||||
|
namespace Ombi.Core.Rule.Rules.Search
|
||||||
|
{
|
||||||
|
public class RadarrCacheRule : BaseSearchRule, IRequestRules<SearchViewModel>
|
||||||
|
{
|
||||||
|
public RadarrCacheRule(IOmbiContext ctx)
|
||||||
|
{
|
||||||
|
_ctx = ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly IOmbiContext _ctx;
|
||||||
|
|
||||||
|
public RuleResult Execute(SearchViewModel obj)
|
||||||
|
{
|
||||||
|
// Check if it's in Radarr
|
||||||
|
|
||||||
|
var result = _ctx.RadarrCache.FirstOrDefault(x => x.TheMovieDbId == obj.Id);
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
obj.Approved = true; // It's in radarr so it's approved... Maybe have a new property called "Processing" or something?
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,6 +24,7 @@ using Ombi.Settings.Settings;
|
||||||
using Ombi.Store.Context;
|
using Ombi.Store.Context;
|
||||||
using Ombi.Store.Repository;
|
using Ombi.Store.Repository;
|
||||||
using Ombi.Core.Rules;
|
using Ombi.Core.Rules;
|
||||||
|
using Ombi.Schedule.Jobs.Radarr;
|
||||||
|
|
||||||
namespace Ombi.DependencyInjection
|
namespace Ombi.DependencyInjection
|
||||||
{
|
{
|
||||||
|
@ -83,6 +84,7 @@ namespace Ombi.DependencyInjection
|
||||||
{
|
{
|
||||||
services.AddTransient<IPlexContentCacher, PlexContentCacher>();
|
services.AddTransient<IPlexContentCacher, PlexContentCacher>();
|
||||||
services.AddTransient<IJobSetup, JobSetup>();
|
services.AddTransient<IJobSetup, JobSetup>();
|
||||||
|
services.AddTransient<IRadarrCacher, RadarrCacher>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RegisterIdentity(this IServiceCollection services)
|
public static void RegisterIdentity(this IServiceCollection services)
|
||||||
|
|
|
@ -1,20 +1,24 @@
|
||||||
using System;
|
using Hangfire;
|
||||||
using Hangfire;
|
|
||||||
using Ombi.Schedule.Jobs;
|
using Ombi.Schedule.Jobs;
|
||||||
|
using Ombi.Schedule.Jobs.Radarr;
|
||||||
|
|
||||||
namespace Ombi.Schedule
|
namespace Ombi.Schedule
|
||||||
{
|
{
|
||||||
public class JobSetup : IJobSetup
|
public class JobSetup : IJobSetup
|
||||||
{
|
{
|
||||||
public JobSetup(IPlexContentCacher cacher)
|
public JobSetup(IPlexContentCacher cacher, IRadarrCacher radarrCacher)
|
||||||
{
|
{
|
||||||
Cacher = cacher;
|
Cacher = cacher;
|
||||||
|
RadarrCacher = radarrCacher;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IPlexContentCacher Cacher { get; }
|
private IPlexContentCacher Cacher { get; }
|
||||||
|
private IRadarrCacher RadarrCacher { get; }
|
||||||
|
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
RecurringJob.AddOrUpdate(() => Cacher.CacheContent(), Cron.Hourly);
|
RecurringJob.AddOrUpdate(() => Cacher.CacheContent(), Cron.Hourly);
|
||||||
|
RecurringJob.AddOrUpdate(() => RadarrCacher.CacheContent(), Cron.Hourly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
namespace Ombi.Schedule.Jobs
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Ombi.Schedule.Jobs
|
||||||
{
|
{
|
||||||
public interface IPlexContentCacher
|
public interface IPlexContentCacher
|
||||||
{
|
{
|
||||||
void CacheContent();
|
Task CacheContent();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -55,7 +55,7 @@ namespace Ombi.Schedule.Jobs
|
||||||
private ILogger<PlexContentCacher> Logger { get; }
|
private ILogger<PlexContentCacher> Logger { get; }
|
||||||
private IPlexContentRepository Repo { get; }
|
private IPlexContentRepository Repo { get; }
|
||||||
|
|
||||||
public void CacheContent()
|
public async Task CacheContent()
|
||||||
{
|
{
|
||||||
var plexSettings = Plex.GetSettings();
|
var plexSettings = Plex.GetSettings();
|
||||||
if (!plexSettings.Enable)
|
if (!plexSettings.Enable)
|
||||||
|
@ -70,8 +70,7 @@ namespace Ombi.Schedule.Jobs
|
||||||
Logger.LogInformation("Starting Plex Content Cacher");
|
Logger.LogInformation("Starting Plex Content Cacher");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
await StartTheCache(plexSettings);
|
||||||
StartTheCache(plexSettings).Wait();
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
12
src/Ombi.Schedule/Jobs/Radarr/IRadarrCacher.cs
Normal file
12
src/Ombi.Schedule/Jobs/Radarr/IRadarrCacher.cs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Ombi.Store.Entities;
|
||||||
|
|
||||||
|
namespace Ombi.Schedule.Jobs.Radarr
|
||||||
|
{
|
||||||
|
public interface IRadarrCacher
|
||||||
|
{
|
||||||
|
Task CacheContent();
|
||||||
|
Task<IEnumerable<RadarrCache>> GetCachedContent();
|
||||||
|
}
|
||||||
|
}
|
72
src/Ombi.Schedule/Jobs/Radarr/RadarrCacher.cs
Normal file
72
src/Ombi.Schedule/Jobs/Radarr/RadarrCacher.cs
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Ombi.Api.Radarr;
|
||||||
|
using Ombi.Core.Settings;
|
||||||
|
using Ombi.Helpers;
|
||||||
|
using Ombi.Settings.Settings.Models.External;
|
||||||
|
using Ombi.Store.Context;
|
||||||
|
using Ombi.Store.Entities;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
|
namespace Ombi.Schedule.Jobs.Radarr
|
||||||
|
{
|
||||||
|
public class RadarrCacher : IRadarrCacher
|
||||||
|
{
|
||||||
|
public RadarrCacher(ISettingsService<RadarrSettings> radarr, IRadarrApi radarrApi, ILogger<RadarrCacher> log, IOmbiContext ctx)
|
||||||
|
{
|
||||||
|
RadarrSettings = radarr;
|
||||||
|
RadarrApi = radarrApi;
|
||||||
|
Logger = log;
|
||||||
|
_ctx = ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ISettingsService<RadarrSettings> RadarrSettings { get; }
|
||||||
|
private IRadarrApi RadarrApi { get; }
|
||||||
|
private ILogger<RadarrCacher> Logger { get; }
|
||||||
|
private readonly IOmbiContext _ctx;
|
||||||
|
|
||||||
|
public async Task CacheContent()
|
||||||
|
{
|
||||||
|
var settings = RadarrSettings.GetSettings();
|
||||||
|
if (settings.Enabled)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var movies = await RadarrApi.GetMovies(settings.ApiKey, settings.FullUri);
|
||||||
|
if (movies != null)
|
||||||
|
{
|
||||||
|
// Let's remove the old cached data
|
||||||
|
await _ctx.Database.ExecuteSqlCommandAsync("TRUNCATE TABLE RadarrCache");
|
||||||
|
|
||||||
|
var movieIds = new List<RadarrCache>();
|
||||||
|
foreach (var m in movies)
|
||||||
|
{
|
||||||
|
if (m.tmdbId > 0)
|
||||||
|
{
|
||||||
|
movieIds.Add(new RadarrCache{TheMovieDbId = m.tmdbId});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Error("TMDBId is not > 0 for movie {0}", m.title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await _ctx.RadarrCache.AddRangeAsync(movieIds);
|
||||||
|
|
||||||
|
await _ctx.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (System.Exception ex)
|
||||||
|
{
|
||||||
|
Logger.LogError(LoggingEvents.CacherException, ex, "Failed caching queued items from Radarr");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IEnumerable<RadarrCache>> GetCachedContent()
|
||||||
|
{
|
||||||
|
return await _ctx.RadarrCache.ToListAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Ombi.Api.Plex\Ombi.Api.Plex.csproj" />
|
<ProjectReference Include="..\Ombi.Api.Plex\Ombi.Api.Plex.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Core\Ombi.Core.csproj" />
|
<ProjectReference Include="..\Ombi.Api.Radarr\Ombi.Api.Radarr.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Settings\Ombi.Settings.csproj" />
|
<ProjectReference Include="..\Ombi.Settings\Ombi.Settings.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Store.Entities;
|
||||||
|
|
||||||
namespace Ombi.Store.Context
|
namespace Ombi.Store.Context
|
||||||
|
@ -14,6 +15,8 @@ namespace Ombi.Store.Context
|
||||||
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<PlexContent> PlexContent { get; set; }
|
||||||
|
DbSet<RadarrCache> RadarrCache { get; set; }
|
||||||
|
DatabaseFacade Database { get; }
|
||||||
DbSet<User> Users { get; set; }
|
DbSet<User> Users { get; set; }
|
||||||
EntityEntry<T> Entry<T>(T entry) where T : class;
|
EntityEntry<T> Entry<T>(T entry) where T : class;
|
||||||
EntityEntry<TEntity> Attach<TEntity>(TEntity entity) where TEntity : class;
|
EntityEntry<TEntity> Attach<TEntity>(TEntity entity) where TEntity : class;
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
using System;
|
using System.IO;
|
||||||
using System.IO;
|
|
||||||
using System.Resources;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Store.Entities;
|
||||||
|
|
||||||
namespace Ombi.Store.Context
|
namespace Ombi.Store.Context
|
||||||
|
@ -35,12 +32,7 @@ namespace Ombi.Store.Context
|
||||||
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 DbSet<PlexContent> PlexContent { get; set; }
|
||||||
|
public DbSet<RadarrCache> RadarrCache { get; set; }
|
||||||
|
|
||||||
public EntityEntry<T> Entry<T>(T entry) where T : class
|
|
||||||
{
|
|
||||||
return base.Entry(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||||
{
|
{
|
||||||
|
|
10
src/Ombi.Store/Entities/RadarrCache.cs
Normal file
10
src/Ombi.Store/Entities/RadarrCache.cs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace Ombi.Store.Entities
|
||||||
|
{
|
||||||
|
[Table("RadarrCache")]
|
||||||
|
public class RadarrCache : Entity
|
||||||
|
{
|
||||||
|
public int TheMovieDbId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,12 @@ CREATE TABLE IF NOT EXISTS PlexContent
|
||||||
ReleaseYear varchar(100) NOT NULL
|
ReleaseYear varchar(100) NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS RadarrCache
|
||||||
|
(
|
||||||
|
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
TheMovieDbId INTEGER NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS SeasonsContent
|
CREATE TABLE IF NOT EXISTS SeasonsContent
|
||||||
(
|
(
|
||||||
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
|
|
@ -12,14 +12,14 @@ namespace Ombi.Api.TheMovieDb
|
||||||
{
|
{
|
||||||
public TheMovieDbApi(IMapper mapper)
|
public TheMovieDbApi(IMapper mapper)
|
||||||
{
|
{
|
||||||
Api = new Ombi.Api.Api();
|
Api = new Api();
|
||||||
Mapper = mapper;
|
Mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IMapper Mapper { get; }
|
private IMapper Mapper { get; }
|
||||||
private readonly string ApiToken = "b8eabaf5608b88d0298aa189dd90bf00";
|
private readonly string ApiToken = "b8eabaf5608b88d0298aa189dd90bf00";
|
||||||
private static readonly string BaseUri ="http://api.themoviedb.org/3/";
|
private static readonly string BaseUri ="http://api.themoviedb.org/3/";
|
||||||
private Ombi.Api.Api Api { get; }
|
private Api Api { get; }
|
||||||
|
|
||||||
public async Task<MovieResponseDto> GetMovieInformation(int movieId)
|
public async Task<MovieResponseDto> GetMovieInformation(int movieId)
|
||||||
{
|
{
|
||||||
|
|
2474
src/Ombi/package-lock.json
generated
Normal file
2474
src/Ombi/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue