mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-14 01:02:57 -07:00
Added the watchlist import for movies
This commit is contained in:
parent
df59b46a78
commit
f41eea89a0
55 changed files with 1824 additions and 136 deletions
|
@ -10,6 +10,7 @@ using Ombi.Core.Authentication;
|
|||
using Ombi.Core.Engine.V2;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
using Ombi.Store.Repository.Requests;
|
||||
using Ombi.Core.Helpers;
|
||||
|
||||
namespace Ombi.Core.Tests.Engine
|
||||
{
|
||||
|
@ -25,7 +26,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
{
|
||||
MovieRepo = new Mock<IMovieRequestRepository>();
|
||||
TvRepo = new Mock<ITvRequestRepository>();
|
||||
var principle = new Mock<IPrincipal>();
|
||||
var principle = new Mock<ICurrentUser>();
|
||||
var identity = new Mock<IIdentity>();
|
||||
identity.Setup(x => x.Name).Returns("UnitTest");
|
||||
principle.Setup(x => x.Identity).Returns(identity.Object);
|
||||
|
|
|
@ -4,6 +4,7 @@ using Moq.AutoMock;
|
|||
using NUnit.Framework;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
|
@ -35,12 +36,17 @@ namespace Ombi.Core.Tests.Engine
|
|||
var identity = new Mock<IIdentity>();
|
||||
identity.Setup(x => x.Name).Returns("Test");
|
||||
principle.Setup(x => x.Identity).Returns(identity.Object);
|
||||
var currentUser = new Mock<ICurrentUser>();
|
||||
currentUser.Setup(x => x.Identity).Returns(identity.Object);
|
||||
currentUser.Setup(x => x.Username).Returns("Test");
|
||||
currentUser.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { NormalizedUserName = "TEST", Id = "a" });
|
||||
|
||||
_repoMock = new Mock<IMovieRequestRepository>();
|
||||
var requestServiceMock = new Mock<IRequestServiceMain>();
|
||||
requestServiceMock.Setup(x => x.MovieRequestService).Returns(_repoMock.Object);
|
||||
|
||||
_mocker.Use(principle.Object);
|
||||
_mocker.Use(currentUser.Object);
|
||||
_mocker.Use(userManager.Object);
|
||||
_mocker.Use(requestServiceMock);
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ using Moq.AutoMock;
|
|||
using NUnit.Framework;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models;
|
||||
using Ombi.Core.Services;
|
||||
using Ombi.Helpers;
|
||||
|
@ -36,6 +37,13 @@ namespace Ombi.Core.Tests.Engine
|
|||
var identityMock = new Mock<IIdentity>();
|
||||
identityMock.SetupGet(x => x.Name).Returns("Test");
|
||||
principleMock.SetupGet(x => x.Identity).Returns(identityMock.Object);
|
||||
|
||||
var currentUser = new Mock<ICurrentUser>();
|
||||
currentUser.Setup(x => x.Identity).Returns(identityMock.Object);
|
||||
currentUser.Setup(x => x.Username).Returns("Test");
|
||||
currentUser.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "Test", NormalizedUserName = "TEST", Id = "a" });
|
||||
|
||||
_mocker.Use(currentUser.Object);
|
||||
_mocker.Use(principleMock.Object);
|
||||
|
||||
_subject = _mocker.CreateInstance<RequestLimitService>();
|
||||
|
|
|
@ -4,6 +4,7 @@ using Moq.AutoMock;
|
|||
using NUnit.Framework;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models;
|
||||
using Ombi.Core.Services;
|
||||
using Ombi.Helpers;
|
||||
|
@ -36,7 +37,12 @@ namespace Ombi.Core.Tests.Engine
|
|||
var identityMock = new Mock<IIdentity>();
|
||||
identityMock.SetupGet(x => x.Name).Returns("Test");
|
||||
principleMock.SetupGet(x => x.Identity).Returns(identityMock.Object);
|
||||
var currentUser = new Mock<ICurrentUser>();
|
||||
currentUser.Setup(x => x.Identity).Returns(identityMock.Object);
|
||||
currentUser.Setup(x => x.Username).Returns("Test");
|
||||
currentUser.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "Test", NormalizedUserName = "TEST", Id = "a" });
|
||||
_mocker.Use(principleMock.Object);
|
||||
_mocker.Use(currentUser.Object);
|
||||
|
||||
_subject = _mocker.CreateInstance<RequestLimitService>();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ using Moq.AutoMock;
|
|||
using NUnit.Framework;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models;
|
||||
using Ombi.Core.Services;
|
||||
using Ombi.Helpers;
|
||||
|
@ -33,7 +34,12 @@ namespace Ombi.Core.Tests.Engine
|
|||
var identityMock = new Mock<IIdentity>();
|
||||
identityMock.SetupGet(x => x.Name).Returns("Test");
|
||||
principleMock.SetupGet(x => x.Identity).Returns(identityMock.Object);
|
||||
var currentUser = new Mock<ICurrentUser>();
|
||||
currentUser.Setup(x => x.Identity).Returns(identityMock.Object);
|
||||
currentUser.Setup(x => x.Username).Returns("Test");
|
||||
currentUser.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "Test", NormalizedUserName = "TEST", Id = "a" });
|
||||
_mocker.Use(principleMock.Object);
|
||||
_mocker.Use(currentUser.Object);
|
||||
|
||||
_subject = _mocker.CreateInstance<RequestLimitService>();
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ using Moq;
|
|||
using NUnit.Framework;
|
||||
using Ombi.Api.TheMovieDb;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
using Ombi.Core.Services;
|
||||
|
@ -33,7 +34,7 @@ namespace Ombi.Core.Tests.Engine.V2
|
|||
var requestService = new Mock<IRequestServiceMain>();
|
||||
_movieRequestRepository = new Mock<IMovieRequestRepository>();
|
||||
requestService.Setup(x => x.MovieRequestService).Returns(_movieRequestRepository.Object);
|
||||
var user = new Mock<IPrincipal>();
|
||||
var user = new Mock<ICurrentUser>();
|
||||
var notificationHelper = new Mock<INotificationHelper>();
|
||||
var rules = new Mock<IRuleEvaluator>();
|
||||
var movieSender = new Mock<IMovieSender>();
|
||||
|
|
|
@ -23,6 +23,7 @@ using Ombi.Store.Entities;
|
|||
using Ombi.Store.Repository;
|
||||
using Ombi.Test.Common;
|
||||
using Artist = Hqub.MusicBrainz.API.Entities.Artist;
|
||||
using Ombi.Core.Helpers;
|
||||
|
||||
namespace Ombi.Core.Tests.Engine.V2
|
||||
{
|
||||
|
@ -45,7 +46,7 @@ namespace Ombi.Core.Tests.Engine.V2
|
|||
.ForEach(b => F.Behaviors.Remove(b));
|
||||
F.Behaviors.Add(new OmitOnRecursionBehavior());
|
||||
|
||||
var principle = new Mock<IPrincipal>();
|
||||
var principle = new Mock<ICurrentUser>();
|
||||
var requestService = new Mock<IRequestServiceMain>();
|
||||
var ruleEval = new Mock<IRuleEvaluator>();
|
||||
var um = MockHelper.MockUserManager(new List<OmbiUser>());
|
||||
|
|
|
@ -9,6 +9,7 @@ using NUnit.Framework;
|
|||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Engine.Interfaces;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
using Ombi.Core.Settings;
|
||||
|
@ -32,8 +33,9 @@ namespace Ombi.Core.Tests.Engine
|
|||
TvRequestEngine = new Mock<ITvRequestEngine>();
|
||||
MovieRequestEngine = new Mock<IMovieRequestEngine>();
|
||||
MovieRequestEngine = new Mock<IMovieRequestEngine>();
|
||||
User = new Mock<IPrincipal>();
|
||||
User.Setup(x => x.Identity.Name).Returns("abc");
|
||||
User = new Mock<ICurrentUser>();
|
||||
User.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "abc", NormalizedUserName = "ABC", Id = "abc" });
|
||||
|
||||
UserManager = MockHelper.MockUserManager(new List<OmbiUser> { new OmbiUser { Id = "abc", UserName = "abc", NormalizedUserName = "ABC" } });
|
||||
Rule = new Mock<IRuleEvaluator>();
|
||||
Engine = new VoteEngine(VoteRepository.Object, User.Object, UserManager.Object, Rule.Object, VoteSettings.Object, MusicRequestEngine.Object,
|
||||
|
@ -48,7 +50,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
|
||||
public Fixture F { get; set; }
|
||||
public VoteEngine Engine { get; set; }
|
||||
public Mock<IPrincipal> User { get; set; }
|
||||
public Mock<ICurrentUser> User { get; set; }
|
||||
public Mock<OmbiUserManager> UserManager { get; set; }
|
||||
public Mock<IRuleEvaluator> Rule { get; set; }
|
||||
public Mock<IRepository<Votes>> VoteRepository { get; set; }
|
||||
|
|
|
@ -11,6 +11,7 @@ using System.Collections.Generic;
|
|||
using Ombi.Store.Entities;
|
||||
using System;
|
||||
using Ombi.Core.Services;
|
||||
using Ombi.Core.Helpers;
|
||||
|
||||
namespace Ombi.Core.Tests.Rule.Request
|
||||
{
|
||||
|
@ -27,17 +28,18 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
public void Setup()
|
||||
{
|
||||
|
||||
PrincipalMock = new Mock<IPrincipal>();
|
||||
PrincipalMock.Setup(x => x.Identity.Name).Returns("abc");
|
||||
FeatureService = new Mock<IFeatureService>();
|
||||
|
||||
PrincipalMock = new Mock<ICurrentUser>();
|
||||
PrincipalMock.Setup(x => x.Username).Returns("abc");
|
||||
PrincipalMock.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "abc", NormalizedUserName = "ABC", Id = "a" });
|
||||
|
||||
UserManager = MockHelper.MockUserManager(_users);
|
||||
Rule = new AutoApproveRule(PrincipalMock.Object, UserManager.Object, FeatureService.Object);
|
||||
}
|
||||
|
||||
|
||||
private AutoApproveRule Rule { get; set; }
|
||||
private Mock<IPrincipal> PrincipalMock { get; set; }
|
||||
private Mock<ICurrentUser> PrincipalMock { get; set; }
|
||||
private Mock<OmbiUserManager> UserManager { get; set; }
|
||||
private Mock<IFeatureService> FeatureService { get; set; }
|
||||
|
||||
|
@ -99,7 +101,8 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
[Test]
|
||||
public async Task Should_ReturnSuccess_WhenSystemUserAndRequestTV()
|
||||
{
|
||||
PrincipalMock.Setup(x => x.Identity.Name).Returns("sys");
|
||||
PrincipalMock.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "sys", NormalizedUserName = "SYS", Id = "a" });
|
||||
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.AutoApproveTv)).ReturnsAsync(false);
|
||||
var request = new BaseRequest() { RequestType = Store.Entities.RequestType.TvShow };
|
||||
var result = await Rule.Execute(request);
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.Threading.Tasks;
|
|||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Rule.Rules;
|
||||
using Ombi.Core.Rule.Rules.Request;
|
||||
using Ombi.Helpers;
|
||||
|
@ -26,8 +27,9 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
public void Setup()
|
||||
{
|
||||
|
||||
PrincipalMock = new Mock<IPrincipal>();
|
||||
PrincipalMock.Setup(x => x.Identity.Name).Returns("abc");
|
||||
PrincipalMock = new Mock<ICurrentUser>();
|
||||
PrincipalMock.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "abc", NormalizedUserName = "ABC", Id = "a" });
|
||||
|
||||
|
||||
UserManager = MockHelper.MockUserManager(_users);
|
||||
Rule = new CanRequestRule(PrincipalMock.Object, UserManager.Object);
|
||||
|
@ -35,7 +37,7 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
|
||||
|
||||
private CanRequestRule Rule { get; set; }
|
||||
private Mock<IPrincipal> PrincipalMock { get; set; }
|
||||
private Mock<ICurrentUser> PrincipalMock { get; set; }
|
||||
private Mock<OmbiUserManager> UserManager { get; set; }
|
||||
|
||||
[Test]
|
||||
|
@ -107,7 +109,8 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
[Test]
|
||||
public async Task Should_ReturnSuccess_WhenRequestingMovieWithSystemRole()
|
||||
{
|
||||
PrincipalMock.Setup(x => x.Identity.Name).Returns("sys");
|
||||
PrincipalMock.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "sys", NormalizedUserName = "SYS", Id = "a" });
|
||||
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.Admin)).ReturnsAsync(false);
|
||||
var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var result = await Rule.Execute(request);
|
||||
|
|
|
@ -118,14 +118,23 @@ namespace Ombi.Core.Authentication
|
|||
var plexAccount = await _plexApi.GetAccount(plexToken);
|
||||
|
||||
// Check for a ombi user
|
||||
if (plexAccount?.user != null)
|
||||
if (plexAccount?.user == null)
|
||||
{
|
||||
var potentialOmbiUser = await Users.FirstOrDefaultAsync(x =>
|
||||
x.ProviderUserId == plexAccount.user.id);
|
||||
return potentialOmbiUser;
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
var potentialOmbiUser = await Users.FirstOrDefaultAsync(x =>
|
||||
x.ProviderUserId == plexAccount.user.id);
|
||||
// Update ombi user with the token
|
||||
|
||||
if (potentialOmbiUser != null)
|
||||
{
|
||||
potentialOmbiUser.MediaServerToken = plexAccount.user.authentication_token;
|
||||
await UpdateAsync(potentialOmbiUser);
|
||||
}
|
||||
|
||||
return potentialOmbiUser;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -142,6 +151,10 @@ namespace Ombi.Core.Authentication
|
|||
var result = await _plexApi.SignIn(new UserRequest { password = password, login = login });
|
||||
if (result.user?.authentication_token != null)
|
||||
{
|
||||
// Update ombi user with the token
|
||||
user.MediaServerToken = result.user?.authentication_token;
|
||||
await UpdateAsync(user);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace Ombi.Core.Engine
|
|||
private Dictionary<int, MovieRequests> _dbMovies;
|
||||
private Dictionary<int, TvRequests> _dbTv;
|
||||
|
||||
protected BaseMediaEngine(IPrincipal identity, IRequestServiceMain requestService,
|
||||
protected BaseMediaEngine(ICurrentUser identity, IRequestServiceMain requestService,
|
||||
IRuleEvaluator rules, OmbiUserManager um, ICacheService cache, ISettingsService<OmbiSettings> ombiSettings, IRepository<RequestSubscription> sub) : base(identity, um, rules)
|
||||
{
|
||||
RequestService = requestService;
|
||||
|
|
|
@ -11,6 +11,7 @@ using Ombi.Api.TheMovieDb;
|
|||
using Ombi.Api.TheMovieDb.Models;
|
||||
using Ombi.Config;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Models.Search;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
|
@ -24,7 +25,7 @@ namespace Ombi.Core.Engine.Demo
|
|||
{
|
||||
public class DemoMovieSearchEngine : MovieSearchEngine, IDemoMovieSearchEngine
|
||||
{
|
||||
public DemoMovieSearchEngine(IPrincipal identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper,
|
||||
public DemoMovieSearchEngine(ICurrentUser identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper,
|
||||
ILogger<MovieSearchEngine> logger, IRuleEvaluator r, OmbiUserManager um, ICacheService mem, ISettingsService<OmbiSettings> s,
|
||||
IRepository<RequestSubscription> sub, IOptions<DemoLists> lists)
|
||||
: base(identity, service, movApi, mapper, logger, r, um, mem, s, sub)
|
||||
|
|
|
@ -4,6 +4,7 @@ using Ombi.Api.Trakt;
|
|||
using Ombi.Api.TvMaze;
|
||||
using Ombi.Config;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Models.Search;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
|
@ -24,7 +25,7 @@ namespace Ombi.Core.Engine.Demo
|
|||
public class DemoTvSearchEngine : TvSearchEngine, IDemoTvSearchEngine
|
||||
{
|
||||
|
||||
public DemoTvSearchEngine(IPrincipal identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper,
|
||||
public DemoTvSearchEngine(ICurrentUser identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper,
|
||||
ITraktApi trakt, IRuleEvaluator r, OmbiUserManager um, ICacheService memCache,
|
||||
ISettingsService<OmbiSettings> s, IRepository<RequestSubscription> sub, IOptions<DemoLists> lists, IImageService imageService,
|
||||
ISettingsService<CustomizationSettings> custom)
|
||||
|
|
|
@ -1,42 +1,35 @@
|
|||
using System;
|
||||
using Ombi.Core.Rule;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Principal;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Core.Models.Search;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
using Ombi.Store.Entities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Core.Helpers;
|
||||
|
||||
namespace Ombi.Core.Engine.Interfaces
|
||||
{
|
||||
public abstract class BaseEngine
|
||||
{
|
||||
protected BaseEngine(IPrincipal user, OmbiUserManager um, IRuleEvaluator rules)
|
||||
protected BaseEngine(ICurrentUser user, OmbiUserManager um, IRuleEvaluator rules)
|
||||
{
|
||||
UserPrinciple = user;
|
||||
CurrentUser = user;
|
||||
Rules = rules;
|
||||
UserManager = um;
|
||||
}
|
||||
|
||||
protected IPrincipal UserPrinciple { get; }
|
||||
protected ICurrentUser CurrentUser { get; }
|
||||
protected IRuleEvaluator Rules { get; }
|
||||
protected OmbiUserManager UserManager { get; }
|
||||
protected string Username => UserPrinciple.Identity.Name;
|
||||
protected string Username => CurrentUser.Username;
|
||||
protected Task<OmbiUser> GetUser() => CurrentUser.GetUser();
|
||||
|
||||
private OmbiUser _user;
|
||||
protected async Task<OmbiUser> GetUser()
|
||||
{
|
||||
if(!Username.HasValue())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var username = Username.ToUpper();
|
||||
return _user ??= await UserManager.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == username);
|
||||
}
|
||||
/// <summary>
|
||||
/// Only used for background tasks
|
||||
/// </summary>
|
||||
public void SetUser(OmbiUser user) => CurrentUser.SetUser(user);
|
||||
|
||||
protected async Task<string> UserAlias()
|
||||
{
|
||||
|
|
|
@ -25,5 +25,6 @@ namespace Ombi.Core.Engine.Interfaces
|
|||
Task UnSubscribeRequest(int requestId, RequestType type);
|
||||
Task SubscribeToRequest(int requestId, RequestType type);
|
||||
Task<RequestEngineResult> ReProcessRequest(int requestId, bool is4K, CancellationToken cancellationToken);
|
||||
void SetUser(OmbiUser user);
|
||||
}
|
||||
}
|
|
@ -23,12 +23,13 @@ using Ombi.Store.Repository;
|
|||
using Ombi.Core.Models;
|
||||
using System.Threading;
|
||||
using Ombi.Core.Services;
|
||||
using Ombi.Core.Helpers;
|
||||
|
||||
namespace Ombi.Core.Engine
|
||||
{
|
||||
public class MovieRequestEngine : BaseMediaEngine, IMovieRequestEngine
|
||||
{
|
||||
public MovieRequestEngine(IMovieDbApi movieApi, IRequestServiceMain requestService, IPrincipal user,
|
||||
public MovieRequestEngine(IMovieDbApi movieApi, IRequestServiceMain requestService, ICurrentUser user,
|
||||
INotificationHelper helper, IRuleEvaluator r, IMovieSender sender, ILogger<MovieRequestEngine> log,
|
||||
OmbiUserManager manager, IRepository<RequestLog> rl, ICacheService cache,
|
||||
ISettingsService<OmbiSettings> ombiSettings, IRepository<RequestSubscription> sub, IMediaCacheService mediaCacheService,
|
||||
|
|
|
@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging;
|
|||
using Ombi.Api.TheMovieDb;
|
||||
using Ombi.Api.TheMovieDb.Models;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Models.Search;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
|
@ -22,7 +23,7 @@ namespace Ombi.Core.Engine
|
|||
{
|
||||
public class MovieSearchEngine : BaseMediaEngine, IMovieEngine
|
||||
{
|
||||
public MovieSearchEngine(IPrincipal identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper,
|
||||
public MovieSearchEngine(ICurrentUser identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper,
|
||||
ILogger<MovieSearchEngine> logger, IRuleEvaluator r, OmbiUserManager um, ICacheService mem, ISettingsService<OmbiSettings> s, IRepository<RequestSubscription> sub)
|
||||
: base(identity, service, r, um, mem, s, sub)
|
||||
{
|
||||
|
|
|
@ -24,12 +24,13 @@ using Ombi.Settings.Settings.Models.External;
|
|||
using Ombi.Store.Entities.Requests;
|
||||
using Ombi.Store.Repository;
|
||||
using System.ComponentModel;
|
||||
using Ombi.Core.Helpers;
|
||||
|
||||
namespace Ombi.Core.Engine
|
||||
{
|
||||
public class MusicRequestEngine : BaseMediaEngine, IMusicRequestEngine
|
||||
{
|
||||
public MusicRequestEngine(IRequestServiceMain requestService, IPrincipal user,
|
||||
public MusicRequestEngine(IRequestServiceMain requestService, ICurrentUser user,
|
||||
INotificationHelper helper, IRuleEvaluator r, ILogger<MusicRequestEngine> log,
|
||||
OmbiUserManager manager, IRepository<RequestLog> rl, ICacheService cache,
|
||||
ISettingsService<OmbiSettings> ombiSettings, IRepository<RequestSubscription> sub, ILidarrApi lidarr,
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace Ombi.Core.Engine
|
|||
{
|
||||
public class MusicSearchEngine : BaseMediaEngine, IMusicSearchEngine
|
||||
{
|
||||
public MusicSearchEngine(IPrincipal identity, IRequestServiceMain service, ILidarrApi lidarrApi, IMapper mapper,
|
||||
public MusicSearchEngine(ICurrentUser identity, IRequestServiceMain service, ILidarrApi lidarrApi, IMapper mapper,
|
||||
ILogger<MusicSearchEngine> logger, IRuleEvaluator r, OmbiUserManager um, ICacheService mem, ISettingsService<OmbiSettings> s, IRepository<RequestSubscription> sub,
|
||||
ISettingsService<LidarrSettings> lidarrSettings)
|
||||
: base(identity, service, r, um, mem, s, sub)
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace Ombi.Core.Engine
|
|||
{
|
||||
public class TvRequestEngine : BaseMediaEngine, ITvRequestEngine
|
||||
{
|
||||
public TvRequestEngine(ITvMazeApi tvApi, IMovieDbApi movApi, IRequestServiceMain requestService, IPrincipal user,
|
||||
public TvRequestEngine(ITvMazeApi tvApi, IMovieDbApi movApi, IRequestServiceMain requestService, ICurrentUser user,
|
||||
INotificationHelper helper, IRuleEvaluator rule, OmbiUserManager manager, ILogger<TvRequestEngine> logger,
|
||||
ITvSender sender, IRepository<RequestLog> rl, ISettingsService<OmbiSettings> settings, ICacheService cache,
|
||||
IRepository<RequestSubscription> sub, IMediaCacheService mediaCacheService) : base(user, requestService, rule, manager, cache, settings, sub)
|
||||
|
|
|
@ -23,6 +23,7 @@ using Ombi.Api.TheMovieDb;
|
|||
using Ombi.Api.TheMovieDb.Models;
|
||||
using System.Threading;
|
||||
using TraktSharp.Entities;
|
||||
using Ombi.Core.Helpers;
|
||||
|
||||
namespace Ombi.Core.Engine
|
||||
{
|
||||
|
@ -32,7 +33,7 @@ namespace Ombi.Core.Engine
|
|||
private readonly IImageService _imageService;
|
||||
private readonly IMovieDbApi _theMovieDbApi;
|
||||
|
||||
public TvSearchEngine(IPrincipal identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper,
|
||||
public TvSearchEngine(ICurrentUser identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper,
|
||||
ITraktApi trakt, IRuleEvaluator r, OmbiUserManager um, ISettingsService<CustomizationSettings> customizationSettings,
|
||||
ICacheService memCache, ISettingsService<OmbiSettings> s, IRepository<RequestSubscription> sub, IImageService imageService,
|
||||
IMovieDbApi theMovieDbApi)
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.Security.Principal;
|
|||
using System.Threading.Tasks;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Engine.Interfaces;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models.Search.V2;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
using Ombi.Store.Entities;
|
||||
|
@ -17,7 +18,7 @@ namespace Ombi.Core.Engine.V2
|
|||
{
|
||||
public DateTime DaysAgo => DateTime.Now.AddDays(-90);
|
||||
public DateTime DaysAhead => DateTime.Now.AddDays(90);
|
||||
public CalendarEngine(IPrincipal user, OmbiUserManager um, IRuleEvaluator rules, IMovieRequestRepository movieRepo,
|
||||
public CalendarEngine(ICurrentUser user, OmbiUserManager um, IRuleEvaluator rules, IMovieRequestRepository movieRepo,
|
||||
ITvRequestRepository tvRequestRepo) : base(user, um, rules)
|
||||
{
|
||||
_movieRepo = movieRepo;
|
||||
|
|
|
@ -5,6 +5,7 @@ using Ombi.Api.TheMovieDb;
|
|||
using Ombi.Api.TheMovieDb.Models;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Engine.Interfaces;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Models.Search;
|
||||
using Ombi.Core.Models.Search.V2;
|
||||
|
@ -28,7 +29,7 @@ namespace Ombi.Core.Engine.V2
|
|||
{
|
||||
public class MovieSearchEngineV2 : BaseMediaEngine, IMovieEngineV2
|
||||
{
|
||||
public MovieSearchEngineV2(IPrincipal identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper,
|
||||
public MovieSearchEngineV2(ICurrentUser identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper,
|
||||
ILogger<MovieSearchEngineV2> logger, IRuleEvaluator r, OmbiUserManager um, ICacheService mem, ISettingsService<OmbiSettings> s, IRepository<RequestSubscription> sub,
|
||||
ISettingsService<CustomizationSettings> customizationSettings, IMovieRequestEngine movieRequestEngine, IHttpClientFactory httpClientFactory)
|
||||
: base(identity, service, r, um, mem, s, sub)
|
||||
|
|
|
@ -7,6 +7,7 @@ using Ombi.Api.MusicBrainz;
|
|||
using Ombi.Api.TheMovieDb;
|
||||
using Ombi.Api.TheMovieDb.Models;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Models.Search.V2;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
|
@ -25,7 +26,7 @@ namespace Ombi.Core.Engine.V2
|
|||
{
|
||||
public class MultiSearchEngine : BaseMediaEngine, IMultiSearchEngine
|
||||
{
|
||||
public MultiSearchEngine(IPrincipal identity, IRequestServiceMain requestService, IRuleEvaluator rules,
|
||||
public MultiSearchEngine(ICurrentUser identity, IRequestServiceMain requestService, IRuleEvaluator rules,
|
||||
OmbiUserManager um, ICacheService cache, ISettingsService<OmbiSettings> ombiSettings, IRepository<RequestSubscription> sub,
|
||||
IMovieDbApi movieDbApi, ISettingsService<LidarrSettings> lidarrSettings, IMusicBrainzApi musicApi)
|
||||
: base(identity, requestService, rules, um, cache, ombiSettings, sub)
|
||||
|
|
|
@ -11,6 +11,7 @@ using Ombi.Api.Lidarr.Models;
|
|||
using Ombi.Api.MusicBrainz;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Engine.Interfaces;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Models.Search.V2.Music;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
|
@ -31,7 +32,7 @@ namespace Ombi.Core.Engine.V2
|
|||
private readonly ISettingsService<LidarrSettings> _lidarrSettings;
|
||||
private readonly ILidarrApi _lidarrApi;
|
||||
|
||||
public MusicSearchEngineV2(IPrincipal identity, IRequestServiceMain requestService, IRuleEvaluator rules,
|
||||
public MusicSearchEngineV2(ICurrentUser identity, IRequestServiceMain requestService, IRuleEvaluator rules,
|
||||
OmbiUserManager um, ICacheService cache, ISettingsService<OmbiSettings> ombiSettings,
|
||||
IRepository<RequestSubscription> sub, IMusicBrainzApi musicBrainzApi, ISettingsService<LidarrSettings> lidarrSettings,
|
||||
ILidarrApi lidarrApi)
|
||||
|
|
|
@ -25,6 +25,7 @@ using Ombi.Api.TheMovieDb.Models;
|
|||
using System.Diagnostics;
|
||||
using Ombi.Core.Engine.Interfaces;
|
||||
using Ombi.Core.Models.UI;
|
||||
using Ombi.Core.Helpers;
|
||||
|
||||
namespace Ombi.Core.Engine.V2
|
||||
{
|
||||
|
@ -37,7 +38,7 @@ namespace Ombi.Core.Engine.V2
|
|||
private readonly ISettingsService<CustomizationSettings> _customization;
|
||||
private readonly ITvRequestEngine _requestEngine;
|
||||
|
||||
public TvSearchEngineV2(IPrincipal identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper,
|
||||
public TvSearchEngineV2(ICurrentUser identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper,
|
||||
ITraktApi trakt, IRuleEvaluator r, OmbiUserManager um, ICacheService memCache, ISettingsService<OmbiSettings> s,
|
||||
IRepository<RequestSubscription> sub, IMovieDbApi movieApi, ISettingsService<CustomizationSettings> customization, ITvRequestEngine requestEngine)
|
||||
: base(identity, service, r, um, memCache, s, sub)
|
||||
|
|
|
@ -7,6 +7,7 @@ using System.Threading.Tasks;
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Engine.Interfaces;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models;
|
||||
using Ombi.Core.Models.UI;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
|
@ -20,7 +21,7 @@ namespace Ombi.Core.Engine
|
|||
{
|
||||
public class VoteEngine : BaseEngine, IVoteEngine
|
||||
{
|
||||
public VoteEngine(IRepository<Votes> votes, IPrincipal user, OmbiUserManager um, IRuleEvaluator r, ISettingsService<VoteSettings> voteSettings,
|
||||
public VoteEngine(IRepository<Votes> votes, ICurrentUser user, OmbiUserManager um, IRuleEvaluator r, ISettingsService<VoteSettings> voteSettings,
|
||||
IMusicRequestEngine musicRequestEngine, ITvRequestEngine tvRequestEngine, IMovieRequestEngine movieRequestEngine) : base(user, um, r)
|
||||
{
|
||||
_voteRepository = votes;
|
||||
|
|
47
src/Ombi.Core/Helpers/CurrentUser.cs
Normal file
47
src/Ombi.Core/Helpers/CurrentUser.cs
Normal file
|
@ -0,0 +1,47 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Store.Entities;
|
||||
using System.Security.Principal;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ombi.Core.Helpers
|
||||
{
|
||||
public class CurrentUser : ICurrentUser
|
||||
{
|
||||
private readonly IPrincipal _principle;
|
||||
private readonly OmbiUserManager _userManager;
|
||||
private OmbiUser _user;
|
||||
public IIdentity Identity { get; set; }
|
||||
|
||||
public CurrentUser(IPrincipal principle, OmbiUserManager userManager)
|
||||
{
|
||||
_principle = principle;
|
||||
_userManager = userManager;
|
||||
Identity = _principle?.Identity;
|
||||
}
|
||||
|
||||
public void SetUser(OmbiUser user)
|
||||
{
|
||||
_user = user;
|
||||
}
|
||||
|
||||
public string Username => Identity.Name;
|
||||
public async Task<OmbiUser> GetUser()
|
||||
{
|
||||
if (!Username.HasValue() && _user == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (_user != null)
|
||||
{
|
||||
return _user;
|
||||
}
|
||||
|
||||
var username = Username.ToUpper();
|
||||
return _user ??= await _userManager.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == username);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
15
src/Ombi.Core/Helpers/ICurrentUser.cs
Normal file
15
src/Ombi.Core/Helpers/ICurrentUser.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
using Ombi.Store.Entities;
|
||||
using System.Security.Principal;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ombi.Core.Helpers
|
||||
{
|
||||
public interface ICurrentUser
|
||||
{
|
||||
string Username { get; }
|
||||
|
||||
Task<OmbiUser> GetUser();
|
||||
void SetUser(OmbiUser user);
|
||||
IIdentity Identity { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,31 +1,5 @@
|
|||
#region Copyright
|
||||
// /************************************************************************
|
||||
// Copyright (c) 2018 Jamie Rees
|
||||
// File: MovieRequestViewModel.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 Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
|
||||
namespace Ombi.Core.Models.Requests
|
||||
{
|
||||
|
@ -41,5 +15,11 @@ namespace Ombi.Core.Models.Requests
|
|||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public string RequestedByAlias { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Only set via list imports
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public RequestSource Source { get; set; } = RequestSource.Ombi;
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ using System.Security.Principal;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
using Ombi.Core.Services;
|
||||
|
@ -15,20 +16,21 @@ namespace Ombi.Core.Rule.Rules.Request
|
|||
{
|
||||
public class AutoApproveRule : BaseRequestRule, IRules<BaseRequest>
|
||||
{
|
||||
public AutoApproveRule(IPrincipal principal, OmbiUserManager um, IFeatureService featureService)
|
||||
public AutoApproveRule(ICurrentUser principal, OmbiUserManager um, IFeatureService featureService)
|
||||
{
|
||||
User = principal;
|
||||
_manager = um;
|
||||
_featureService = featureService;
|
||||
}
|
||||
|
||||
private IPrincipal User { get; }
|
||||
private ICurrentUser User { get; }
|
||||
private readonly OmbiUserManager _manager;
|
||||
private readonly IFeatureService _featureService;
|
||||
|
||||
public async Task<RuleResult> Execute(BaseRequest obj)
|
||||
{
|
||||
var username = User.Identity.Name.ToUpper();
|
||||
var currentUser = await User.GetUser();
|
||||
var username = currentUser.UserName.ToUpper();
|
||||
var user = await _manager.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == username);
|
||||
if (await _manager.IsInRoleAsync(user, OmbiRoles.Admin) || user.IsSystemUser)
|
||||
{
|
||||
|
|
|
@ -10,23 +10,25 @@ using Ombi.Core.Engine;
|
|||
using Ombi.Core.Rule.Interfaces;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
using Ombi.Core.Helpers;
|
||||
|
||||
namespace Ombi.Core.Rule.Rules.Request
|
||||
{
|
||||
public class CanRequestRule : BaseRequestRule, IRules<BaseRequest>
|
||||
{
|
||||
public CanRequestRule(IPrincipal principal, OmbiUserManager manager)
|
||||
public CanRequestRule(ICurrentUser principal, OmbiUserManager manager)
|
||||
{
|
||||
User = principal;
|
||||
_manager = manager;
|
||||
}
|
||||
|
||||
private IPrincipal User { get; }
|
||||
private ICurrentUser User { get; }
|
||||
private readonly OmbiUserManager _manager;
|
||||
|
||||
public async Task<RuleResult> Execute(BaseRequest obj)
|
||||
{
|
||||
var username = User.Identity.Name.ToUpper();
|
||||
var currentUser = await User.GetUser();
|
||||
var username = currentUser.UserName.ToUpper();
|
||||
var user = await _manager.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == username);
|
||||
if (await _manager.IsInRoleAsync(user, OmbiRoles.Admin) || user.IsSystemUser)
|
||||
return Success();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Helpers;
|
||||
using Ombi.Core.Models;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Store.Entities;
|
||||
|
@ -20,11 +21,11 @@ namespace Ombi.Core.Services
|
|||
}
|
||||
public class RequestLimitService : IRequestLimitService
|
||||
{
|
||||
private readonly IPrincipal _user;
|
||||
private readonly ICurrentUser _user;
|
||||
private readonly OmbiUserManager _userManager;
|
||||
private readonly IRepository<RequestLog> _requestLog;
|
||||
|
||||
public RequestLimitService(IPrincipal user, OmbiUserManager userManager, IRepository<RequestLog> rl)
|
||||
public RequestLimitService(ICurrentUser user, OmbiUserManager userManager, IRepository<RequestLog> rl)
|
||||
{
|
||||
_user = user;
|
||||
_userManager = userManager;
|
||||
|
@ -141,7 +142,8 @@ namespace Ombi.Core.Services
|
|||
|
||||
private async Task<OmbiUser> GetUser()
|
||||
{
|
||||
var username = _user.Identity.Name.ToUpper();
|
||||
var currentUser = await _user.GetUser();
|
||||
var username = currentUser.UserName.ToUpper();
|
||||
return await _userManager.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == username);
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ using Ombi.Api.RottenTomatoes;
|
|||
using System.Net.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ombi.Core.Services;
|
||||
using Ombi.Core.Helpers;
|
||||
|
||||
namespace Ombi.DependencyInjection
|
||||
{
|
||||
|
@ -124,6 +125,8 @@ namespace Ombi.DependencyInjection
|
|||
var runtimeVersion = AssemblyHelper.GetRuntimeVersion();
|
||||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
services.AddScoped<IPrincipal>(sp => sp.GetService<IHttpContextAccessor>().HttpContext.User);
|
||||
// HttpContext User is null for background jobs
|
||||
services.AddScoped<ICurrentUser, CurrentUser>(sp => new CurrentUser(sp.GetService<IHttpContextAccessor>()?.HttpContext?.User ?? null, sp.GetService<OmbiUserManager>()));
|
||||
services.AddHttpClient("OmbiClient", client =>
|
||||
{
|
||||
client.DefaultRequestHeaders.Add("User-Agent", $"Ombi/{runtimeVersion} (https://ombi.io/)");
|
||||
|
|
|
@ -3,18 +3,16 @@ using Moq.AutoMock;
|
|||
using NUnit.Framework;
|
||||
using Ombi.Api.Plex;
|
||||
using Ombi.Api.Plex.Models;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Engine.Interfaces;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Core.Settings.Models.External;
|
||||
using Ombi.Schedule.Jobs.Plex;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Test.Common;
|
||||
using Quartz;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
@ -42,16 +40,194 @@ namespace Ombi.Schedule.Tests
|
|||
[Test]
|
||||
public async Task TerminatesWhenPlexIsNotEnabled()
|
||||
{
|
||||
_mocker.Setup<ISettingsService<PlexSettings>, Task<PlexSettings>>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = false });
|
||||
_mocker.Setup<ISettingsService<PlexSettings>, Task<PlexSettings>>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = false, EnableWatchlistImport = true });
|
||||
await _subject.Execute(null);
|
||||
_mocker.Verify<IMovieRequestEngine>(x => x.RequestMovie(It.IsAny<MovieRequestViewModel>()), Times.Never);
|
||||
_mocker.Verify<IPlexApi>(x => x.GetWatchlist(It.IsAny<string>(), It.IsAny<CancellationToken>()), Times.Never);
|
||||
_mocker.Verify<IMovieRequestEngine>(x => x.RequestMovie(It.IsAny<MovieRequestViewModel>()), Times.Never);
|
||||
}
|
||||
[Test]
|
||||
public async Task TerminatesWhenWatchlistIsNotEnabled()
|
||||
{
|
||||
_mocker.Setup<ISettingsService<PlexSettings>, Task<PlexSettings>>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = false });
|
||||
await _subject.Execute(null);
|
||||
_mocker.Verify<IMovieRequestEngine>(x => x.RequestMovie(It.IsAny<MovieRequestViewModel>()), Times.Never);
|
||||
_mocker.Verify<IPlexApi>(x => x.GetWatchlist(It.IsAny<string>(), It.IsAny<CancellationToken>()), Times.Never);
|
||||
_mocker.Verify<IMovieRequestEngine>(x => x.RequestMovie(It.IsAny<MovieRequestViewModel>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task EmptyWatchList()
|
||||
{
|
||||
_mocker.Setup<ISettingsService<PlexSettings>, Task<PlexSettings>>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true });
|
||||
_mocker.Setup<IPlexApi, Task<PlexWatchlist>>(x => x.GetWatchlist(It.IsAny<string>(), It.IsAny<CancellationToken>())).ReturnsAsync(new PlexWatchlist());
|
||||
_mocker.Setup<ISettingsService<PlexSettings>, Task<PlexSettings>>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true });
|
||||
_mocker.Setup<IPlexApi, Task<PlexWatchlistContainer>>(x => x.GetWatchlist(It.IsAny<string>(), It.IsAny<CancellationToken>())).ReturnsAsync(new PlexWatchlistContainer());
|
||||
await _subject.Execute(_context.Object);
|
||||
_mocker.Verify<IMovieRequestEngine>(x => x.RequestMovie(It.IsAny<MovieRequestViewModel>()), Times.Never);
|
||||
_mocker.Verify<IPlexApi>(x => x.GetWatchlist(It.IsAny<string>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
_mocker.Verify<IMovieRequestEngine>(x => x.RequestMovie(It.IsAny<MovieRequestViewModel>()), Times.Never);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task NoPlexUsersWithToken()
|
||||
{
|
||||
_mocker.Setup<ISettingsService<PlexSettings>, Task<PlexSettings>>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true });
|
||||
var um = MockHelper.MockUserManager(new List<OmbiUser>
|
||||
{
|
||||
new OmbiUser { Id = "abc", UserType = UserType.EmbyUser, MediaServerToken = "abc", UserName = "abc", NormalizedUserName = "ABC" },
|
||||
new OmbiUser { Id = "abc", UserType = UserType.LocalUser, MediaServerToken = "abc", UserName = "abc", NormalizedUserName = "ABC" },
|
||||
new OmbiUser { Id = "abc", UserType = UserType.SystemUser, MediaServerToken = "abc", UserName = "abc", NormalizedUserName = "ABC" },
|
||||
new OmbiUser { Id = "abc", UserType = UserType.JellyfinUser, MediaServerToken = "abc", UserName = "abc", NormalizedUserName = "ABC" },
|
||||
new OmbiUser { Id = "abc", UserType = UserType.EmbyConnectUser, MediaServerToken = "abc", UserName = "abc", NormalizedUserName = "ABC" },
|
||||
new OmbiUser { Id = "abc", UserType = UserType.PlexUser, UserName = "abc", NormalizedUserName = "ABC" },
|
||||
});
|
||||
_mocker.Use(um);
|
||||
_subject = _mocker.CreateInstance<PlexWatchlistImport>();
|
||||
|
||||
await _subject.Execute(_context.Object);
|
||||
_mocker.Verify<IPlexApi>(x => x.GetWatchlist(It.IsAny<string>(), It.IsAny<CancellationToken>()), Times.Never);
|
||||
_mocker.Verify<IMovieRequestEngine>(x => x.RequestMovie(It.IsAny<MovieRequestViewModel>()), Times.Never);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task MovieRequestFromWatchList_NoGuid()
|
||||
{
|
||||
_mocker.Setup<ISettingsService<PlexSettings>, Task<PlexSettings>>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true });
|
||||
_mocker.Setup<IPlexApi, Task<PlexWatchlistContainer>>(x => x.GetWatchlist(It.IsAny<string>(), It.IsAny<CancellationToken>())).ReturnsAsync(new PlexWatchlistContainer
|
||||
{
|
||||
MediaContainer = new PlexWatchlist
|
||||
{
|
||||
Metadata = new List<Metadata>
|
||||
{
|
||||
new Metadata
|
||||
{
|
||||
type = "movie",
|
||||
ratingKey = "abc"
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
_mocker.Setup<IPlexApi, Task<PlexWatchlistMetadataContainer>>(x => x.GetWatchlistMetadata("abc", It.IsAny<string>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(new PlexWatchlistMetadataContainer
|
||||
{
|
||||
MediaContainer = new PlexWatchlistMetadata
|
||||
{
|
||||
Metadata = new WatchlistMetadata[]
|
||||
{
|
||||
new WatchlistMetadata
|
||||
{
|
||||
Guid = new List<PlexGuids>
|
||||
{
|
||||
new PlexGuids
|
||||
{
|
||||
Id = "tmdb://123"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
_mocker.Setup<IMovieRequestEngine, Task<RequestEngineResult>>(x => x.RequestMovie(It.IsAny<MovieRequestViewModel>()))
|
||||
.ReturnsAsync(new RequestEngineResult { RequestId = 1 });
|
||||
await _subject.Execute(_context.Object);
|
||||
_mocker.Verify<IMovieRequestEngine>(x => x.RequestMovie(It.Is<MovieRequestViewModel>(x => x.TheMovieDbId == 123)), Times.Once);
|
||||
_mocker.Verify<IPlexApi>(x => x.GetWatchlistMetadata("abc", It.IsAny<string>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
_mocker.Verify<IMovieRequestEngine>(x => x.SetUser(It.Is<OmbiUser>(x => x.Id == "abc")), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task MovieRequestFromWatchList_AlreadyRequested()
|
||||
{
|
||||
_mocker.Setup<ISettingsService<PlexSettings>, Task<PlexSettings>>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true });
|
||||
_mocker.Setup<IPlexApi, Task<PlexWatchlistContainer>>(x => x.GetWatchlist(It.IsAny<string>(), It.IsAny<CancellationToken>())).ReturnsAsync(new PlexWatchlistContainer
|
||||
{
|
||||
MediaContainer = new PlexWatchlist
|
||||
{
|
||||
Metadata = new List<Metadata>
|
||||
{
|
||||
new Metadata
|
||||
{
|
||||
type = "movie",
|
||||
ratingKey = "abc"
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
_mocker.Setup<IPlexApi, Task<PlexWatchlistMetadataContainer>>(x => x.GetWatchlistMetadata("abc", It.IsAny<string>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(new PlexWatchlistMetadataContainer
|
||||
{
|
||||
MediaContainer = new PlexWatchlistMetadata
|
||||
{
|
||||
Metadata = new WatchlistMetadata[]
|
||||
{
|
||||
new WatchlistMetadata
|
||||
{
|
||||
Guid = new List<PlexGuids>
|
||||
{
|
||||
new PlexGuids
|
||||
{
|
||||
Id = "tmdb://123"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
_mocker.Setup<IMovieRequestEngine, Task<RequestEngineResult>>(x => x.RequestMovie(It.IsAny<MovieRequestViewModel>()))
|
||||
.ReturnsAsync(new RequestEngineResult { ErrorCode = ErrorCode.AlreadyRequested, ErrorMessage = "Requested" });
|
||||
await _subject.Execute(_context.Object);
|
||||
_mocker.Verify<IMovieRequestEngine>(x => x.RequestMovie(It.Is<MovieRequestViewModel>(x => x.TheMovieDbId == 123)), Times.Once);
|
||||
_mocker.Verify<IPlexApi>(x => x.GetWatchlistMetadata("abc", It.IsAny<string>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
_mocker.Verify<IMovieRequestEngine>(x => x.SetUser(It.Is<OmbiUser>(x => x.Id == "abc")), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task MovieRequestFromWatchList_NoTmdbGuid()
|
||||
{
|
||||
_mocker.Setup<ISettingsService<PlexSettings>, Task<PlexSettings>>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true });
|
||||
_mocker.Setup<IPlexApi, Task<PlexWatchlistContainer>>(x => x.GetWatchlist(It.IsAny<string>(), It.IsAny<CancellationToken>())).ReturnsAsync(new PlexWatchlistContainer
|
||||
{
|
||||
MediaContainer = new PlexWatchlist
|
||||
{
|
||||
Metadata = new List<Metadata>
|
||||
{
|
||||
new Metadata
|
||||
{
|
||||
type = "movie",
|
||||
ratingKey = "abc"
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
_mocker.Setup<IPlexApi, Task<PlexWatchlistMetadataContainer>>(x => x.GetWatchlistMetadata("abc", It.IsAny<string>(), It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(new PlexWatchlistMetadataContainer
|
||||
{
|
||||
MediaContainer = new PlexWatchlistMetadata
|
||||
{
|
||||
Metadata = new WatchlistMetadata[]
|
||||
{
|
||||
new WatchlistMetadata
|
||||
{
|
||||
Guid = new List<PlexGuids>
|
||||
{
|
||||
new PlexGuids
|
||||
{
|
||||
Id = "imdb://123"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
_mocker.Setup<IMovieRequestEngine, Task<RequestEngineResult>>(x => x.RequestMovie(It.IsAny<MovieRequestViewModel>()))
|
||||
.ReturnsAsync(new RequestEngineResult { RequestId = 1 });
|
||||
await _subject.Execute(_context.Object);
|
||||
_mocker.Verify<IMovieRequestEngine>(x => x.RequestMovie(It.IsAny<MovieRequestViewModel>()), Times.Never);
|
||||
_mocker.Verify<IPlexApi>(x => x.GetWatchlistMetadata("abc", It.IsAny<string>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||
_mocker.Verify<IMovieRequestEngine>(x => x.SetUser(It.Is<OmbiUser>(x => x.Id == "abc")), Times.Never);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
using Ombi.Api.Plex;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ombi.Api.Plex;
|
||||
using Ombi.Api.Plex.Models;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Engine.Interfaces;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Core.Settings.Models.External;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Repository.Requests;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
using Quartz;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
@ -22,34 +22,32 @@ namespace Ombi.Schedule.Jobs.Plex
|
|||
private readonly IPlexApi _plexApi;
|
||||
private readonly ISettingsService<PlexSettings> _settings;
|
||||
private readonly OmbiUserManager _ombiUserManager;
|
||||
private readonly IMovieRequestRepository _movieRequestRepository;
|
||||
private readonly ITvRequestRepository _tvRequestRepository;
|
||||
private readonly IMovieRequestEngine _movieRequestEngine;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public PlexWatchlistImport(IPlexApi plexApi, ISettingsService<PlexSettings> settings, OmbiUserManager ombiUserManager,
|
||||
IMovieRequestRepository movieRequestRepository, ITvRequestRepository tvRequestRepository, IMovieRequestEngine movieRequestEngine)
|
||||
IMovieRequestEngine movieRequestEngine,
|
||||
ILogger<PlexWatchlistImport> logger)
|
||||
{
|
||||
_plexApi = plexApi;
|
||||
_settings = settings;
|
||||
_ombiUserManager = ombiUserManager;
|
||||
_movieRequestRepository = movieRequestRepository;
|
||||
_tvRequestRepository = tvRequestRepository;
|
||||
_movieRequestEngine = movieRequestEngine;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task Execute(IJobExecutionContext context)
|
||||
{
|
||||
|
||||
var settings = await _settings.GetSettingsAsync();
|
||||
if (!settings.Enable)
|
||||
if (!settings.Enable || !settings.EnableWatchlistImport)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var plexUsersWithTokens = _ombiUserManager.Users.Where(x => x.UserType == UserType.PlexUser && x.MediaServerToken != null).ToList();
|
||||
//foreach (var user in plexUsersWithTokens)
|
||||
//{
|
||||
var watchlist = await _plexApi.GetWatchlist(token, context?.CancellationToken ?? CancellationToken.None);
|
||||
foreach (var user in plexUsersWithTokens)
|
||||
{
|
||||
var watchlist = await _plexApi.GetWatchlist(user.MediaServerToken, context?.CancellationToken ?? CancellationToken.None);
|
||||
if (watchlist == null || !(watchlist.MediaContainer?.Metadata?.Any() ?? false))
|
||||
{
|
||||
return;
|
||||
|
@ -64,27 +62,38 @@ namespace Ombi.Schedule.Jobs.Plex
|
|||
await ProcessShow(item);
|
||||
break;
|
||||
case "movie":
|
||||
await ProcessMovie(token, item, null, context?.CancellationToken ?? CancellationToken.None);
|
||||
await ProcessMovie(user.MediaServerToken, item, user, context?.CancellationToken ?? CancellationToken.None);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ProcessMovie(string authToken, Metadata movie, PlexServers servers, CancellationToken cancellationToken)
|
||||
private async Task ProcessMovie(string authToken, Metadata movie, OmbiUser user, CancellationToken cancellationToken)
|
||||
{
|
||||
var providerIds = await GetProviderIds(authToken, movie, servers, cancellationToken);
|
||||
var providerIds = await GetProviderIds(authToken, movie, cancellationToken);
|
||||
if (!providerIds.TheMovieDb.HasValue())
|
||||
{
|
||||
// We need a MovieDbId to support this;
|
||||
return;
|
||||
}
|
||||
//_movieRequestEngine.RequestMovie(new() { TheMovieDbId = });
|
||||
_movieRequestEngine.SetUser(user);
|
||||
var response = await _movieRequestEngine.RequestMovie(new() { TheMovieDbId = int.Parse(providerIds.TheMovieDb), Source = RequestSource.PlexWatchlist});
|
||||
if (response.IsError)
|
||||
{
|
||||
if (response.ErrorCode == ErrorCode.AlreadyRequested)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_logger.LogInformation($"Error adding title from PlexWatchlist for user '{user.UserName}'. Message: '{response.ErrorMessage}'");
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogInformation($"Added title from PlexWatchlist for user '{user.UserName}'. {response.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<ProviderId> GetProviderIds(string authToken, Metadata movie, PlexServers servers, CancellationToken cancellationToken)
|
||||
private async Task<ProviderId> GetProviderIds(string authToken, Metadata movie, CancellationToken cancellationToken)
|
||||
{
|
||||
var guids = new List<string>();
|
||||
if (!movie.Guid.Any())
|
||||
|
|
|
@ -91,6 +91,7 @@ namespace Ombi.Schedule
|
|||
await OmbiQuartz.Instance.AddJob<IPlexUserImporter>(nameof(IPlexUserImporter), "Plex", JobSettingsHelper.UserImporter(s));
|
||||
await OmbiQuartz.Instance.AddJob<IPlexEpisodeSync>(nameof(IPlexEpisodeSync), "Plex", null);
|
||||
await OmbiQuartz.Instance.AddJob<IPlexAvailabilityChecker>(nameof(IPlexAvailabilityChecker), "Plex", null);
|
||||
await OmbiQuartz.Instance.AddJob<IPlexWatchlistImport>(nameof(IPlexWatchlistImport), "Plex", JobSettingsHelper.PlexWatchlistImport(s));
|
||||
}
|
||||
|
||||
private static async Task AddEmby(JobSettings s)
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace Ombi.Core.Settings.Models.External
|
|||
public sealed class PlexSettings : Ombi.Settings.Settings.Models.Settings
|
||||
{
|
||||
public bool Enable { get; set; }
|
||||
public bool EnableWatchlistImport { get; set; }
|
||||
/// <summary>
|
||||
/// This is the ClientId for OAuth
|
||||
/// </summary>
|
||||
|
|
|
@ -19,5 +19,6 @@
|
|||
public string RetryRequests { get; set; }
|
||||
public string MediaDatabaseRefresh { get; set; }
|
||||
public string AutoDeleteRequests { get; set; }
|
||||
public string PlexWatchlistImport { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,11 @@ namespace Ombi.Settings.Settings.Models
|
|||
return ValidateCron(Get(s.UserImporter, Cron.Daily()));
|
||||
}
|
||||
|
||||
public static string PlexWatchlistImport(JobSettings s)
|
||||
{
|
||||
return ValidateCron(Get(s.PlexWatchlistImport, Cron.Daily()));
|
||||
}
|
||||
|
||||
public static string Newsletter(JobSettings s)
|
||||
{
|
||||
return ValidateCron(Get(s.Newsletter, Cron.Weekly(Helpers.DayOfWeek.Friday, 12)));
|
||||
|
|
|
@ -22,6 +22,8 @@ namespace Ombi.Store.Entities.Requests
|
|||
[ForeignKey(nameof(RequestedUserId))]
|
||||
public OmbiUser RequestedUser { get; set; }
|
||||
|
||||
public RequestSource Source { get; set; } = RequestSource.Ombi;
|
||||
|
||||
|
||||
[NotMapped]
|
||||
public virtual bool CanApprove => !Approved && !Available;
|
||||
|
|
8
src/Ombi.Store/Entities/Requests/RequestSource.cs
Normal file
8
src/Ombi.Store/Entities/Requests/RequestSource.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
namespace Ombi.Store.Entities.Requests
|
||||
{
|
||||
public enum RequestSource
|
||||
{
|
||||
Ombi = 0,
|
||||
PlexWatchlist = 1
|
||||
}
|
||||
}
|
1283
src/Ombi.Store/Migrations/OmbiSqlite/20220407072656_RequestSource.Designer.cs
generated
Normal file
1283
src/Ombi.Store/Migrations/OmbiSqlite/20220407072656_RequestSource.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,48 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Ombi.Store.Migrations.OmbiSqlite
|
||||
{
|
||||
public partial class RequestSource : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Source",
|
||||
table: "MovieRequests",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Source",
|
||||
table: "ChildRequests",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "Source",
|
||||
table: "AlbumRequests",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Source",
|
||||
table: "MovieRequests");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Source",
|
||||
table: "ChildRequests");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Source",
|
||||
table: "AlbumRequests");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -469,6 +469,9 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
|||
b.Property<string>("RequestedUserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Source")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
|
@ -527,6 +530,9 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
|||
b.Property<int>("SeriesType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Source")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
|
@ -729,6 +735,9 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
|||
b.Property<int>("RootPathOverride")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Source")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Status")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
|
|
|
@ -112,6 +112,7 @@ export interface IPublicInfo {
|
|||
|
||||
export interface IPlexSettings extends ISettings {
|
||||
enable: boolean;
|
||||
enableWatchlistImport: boolean;
|
||||
servers: IPlexServer[];
|
||||
}
|
||||
|
||||
|
@ -219,6 +220,7 @@ export interface IJobSettings {
|
|||
mediaDatabaseRefresh: string;
|
||||
autoDeleteRequests: string;
|
||||
embyRecentlyAddedSync: string;
|
||||
plexWatchlistImport: string;
|
||||
}
|
||||
|
||||
export interface IIssueSettings extends ISettings {
|
||||
|
|
|
@ -27,6 +27,10 @@ export class JobService extends ServiceHelpers {
|
|||
return this.http.post<boolean>(`${this.url}plexUserImporter/`, {headers: this.headers});
|
||||
}
|
||||
|
||||
public runPlexWatchlistImport(): Observable<boolean> {
|
||||
return this.http.post<boolean>(`${this.url}plexwatchlist/`, {headers: this.headers});
|
||||
}
|
||||
|
||||
public runEmbyImporter(): Observable<boolean> {
|
||||
return this.http.post<boolean>(`${this.url}embyUserImporter/`, {headers: this.headers});
|
||||
}
|
||||
|
|
|
@ -77,6 +77,13 @@
|
|||
<small *ngIf="form.get('plexRecentlyAddedSync').hasError('required')" class="error-text">The Plex Sync is required</small></mat-form-field>
|
||||
<button mat-raised-button type="button" class="btn btn-sm btn-primary-outline cronbtn" (click)="testCron(form.get('plexRecentlyAddedSync')?.value)">Test</button>
|
||||
</div>
|
||||
<div class="form-group cronBox">
|
||||
<mat-form-field appearance="outline" floatLabel=always>
|
||||
<mat-label for="plexWatchlistImport" class="control-mat-label">Plex Watchlist Import</mat-label>
|
||||
<input type="text" matInput [ngClass]="{'form-error': form.get('plexWatchlistImport').hasError('required')}" id="plexWatchlistImport" name="plexWatchlistImport" formControlName="plexWatchlistImport">
|
||||
<small *ngIf="form.get('plexWatchlistImport').hasError('required')" class="error-text">The Plex Watchlist Import is required</small></mat-form-field>
|
||||
<button mat-raised-button type="button" class="btn btn-sm btn-primary-outline cronbtn" (click)="testCron(form.get('plexWatchlistImport')?.value)">Test</button>
|
||||
</div>
|
||||
|
||||
<div class="form-group cronBox">
|
||||
<mat-form-field appearance="outline" floatLabel=always>
|
||||
|
|
|
@ -37,6 +37,7 @@ export class JobsComponent implements OnInit {
|
|||
mediaDatabaseRefresh: [x.mediaDatabaseRefresh, Validators.required],
|
||||
autoDeleteRequests: [x.autoDeleteRequests, Validators.required],
|
||||
embyRecentlyAddedSync: [x.embyRecentlyAddedSync, Validators.required],
|
||||
plexWatchlistImport: [x.plexWatchlistImport, Validators.required],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -9,6 +9,12 @@
|
|||
<mat-slide-toggle [(ngModel)]="settings.enable" [checked]="settings.enable">Enable
|
||||
</mat-slide-toggle>
|
||||
</div>
|
||||
<div class="md-form-field">
|
||||
<mat-slide-toggle [(ngModel)]="settings.enableWatchlistImport" [checked]="settings.enableWatchlistImport">Enable User Watchlist Requests
|
||||
</mat-slide-toggle>
|
||||
<p>When a Plex User adds something to their watchlist in Plex, it will turn up in Ombi as a Request if enabled. This <b>only</b> applies to users that are logging in with their Plex Account</p>
|
||||
<p>Request limits if set are all still applied etc.</p>
|
||||
</div>
|
||||
<div class="md-form-field">
|
||||
<mat-slide-toggle [(ngModel)]="advanced">Advanced</mat-slide-toggle>
|
||||
</div>
|
||||
|
@ -183,6 +189,12 @@
|
|||
Clear Data And Resync
|
||||
</button>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button mat-raised-button (click)="runWatchlistImport()" type="button" id="watchlistImport"
|
||||
class="mat-focus-indicator mat-stroked-button mat-button-base">
|
||||
Run Watchlist Import
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-tab>
|
||||
|
|
|
@ -172,6 +172,14 @@ export class PlexComponent implements OnInit, OnDestroy {
|
|||
});
|
||||
}
|
||||
|
||||
public runWatchlistImport(): void {
|
||||
this.jobService.runPlexWatchlistImport().subscribe(x => {
|
||||
if (x) {
|
||||
this.notificationService.success("Triggered the Watchlist Import");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ngOnDestroy() {
|
||||
this.subscriptions.next();
|
||||
this.subscriptions.complete();
|
||||
|
|
|
@ -91,6 +91,17 @@ namespace Ombi.Controllers.V1
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs the Plex Watchlist Importer
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("plexwatchlist")]
|
||||
public async Task<bool> PlexWatchlistImport()
|
||||
{
|
||||
await OmbiQuartz.TriggerJob(nameof(IPlexWatchlistImport), "Plex");
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs the Emby User importer
|
||||
/// </summary>
|
||||
|
|
|
@ -626,6 +626,7 @@ namespace Ombi.Controllers.V1
|
|||
j.MediaDatabaseRefresh = j.MediaDatabaseRefresh.HasValue() ? j.MediaDatabaseRefresh : JobSettingsHelper.MediaDatabaseRefresh(j);
|
||||
j.AutoDeleteRequests = j.AutoDeleteRequests.HasValue() ? j.AutoDeleteRequests : JobSettingsHelper.AutoDeleteRequests(j);
|
||||
j.EmbyRecentlyAddedSync = j.EmbyRecentlyAddedSync.HasValue() ? j.EmbyRecentlyAddedSync : JobSettingsHelper.EmbyRecentlyAddedSync(j);
|
||||
j.PlexWatchlistImport = j.PlexWatchlistImport.HasValue() ? j.PlexWatchlistImport : JobSettingsHelper.PlexWatchlistImport(j);
|
||||
|
||||
return j;
|
||||
}
|
||||
|
|
|
@ -6,19 +6,16 @@ using System.Security.Claims;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Models;
|
||||
using Ombi.Models.External;
|
||||
using Ombi.Models.Identity;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Repository;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Settings.Settings.Models;
|
||||
using Ombi.Schedule.Jobs.Plex;
|
||||
|
||||
namespace Ombi.Controllers.V1
|
||||
{
|
||||
|
@ -27,26 +24,21 @@ namespace Ombi.Controllers.V1
|
|||
[ApiController]
|
||||
public class TokenController : ControllerBase
|
||||
{
|
||||
public TokenController(OmbiUserManager um, IOptions<TokenAuthentication> ta, ITokenRepository token,
|
||||
IPlexOAuthManager oAuthManager, ILogger<TokenController> logger, ISettingsService<AuthenticationSettings> auth,
|
||||
IPlexWatchlistImport import)
|
||||
public TokenController(OmbiUserManager um, ITokenRepository token,
|
||||
IPlexOAuthManager oAuthManager, ILogger<TokenController> logger, ISettingsService<AuthenticationSettings> auth)
|
||||
{
|
||||
_userManager = um;
|
||||
_tokenAuthenticationOptions = ta.Value;
|
||||
_token = token;
|
||||
_plexOAuthManager = oAuthManager;
|
||||
_log = logger;
|
||||
_authSettings = auth;
|
||||
_import = import;
|
||||
}
|
||||
|
||||
private readonly TokenAuthentication _tokenAuthenticationOptions;
|
||||
private readonly ITokenRepository _token;
|
||||
private readonly OmbiUserManager _userManager;
|
||||
private readonly IPlexOAuthManager _plexOAuthManager;
|
||||
private readonly ILogger<TokenController> _log;
|
||||
private readonly ISettingsService<AuthenticationSettings> _authSettings;
|
||||
private readonly IPlexWatchlistImport _import;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the token.
|
||||
|
@ -57,7 +49,6 @@ namespace Ombi.Controllers.V1
|
|||
[ProducesResponseType(401)]
|
||||
public async Task<IActionResult> GetToken([FromBody] UserAuthModel model)
|
||||
{
|
||||
await _import.Execute(null);
|
||||
if (!model.UsePlexOAuth)
|
||||
{
|
||||
var user = await _userManager.FindByNameAsync(model.Username);
|
||||
|
@ -122,6 +113,7 @@ namespace Ombi.Controllers.V1
|
|||
{
|
||||
return Unauthorized();
|
||||
}
|
||||
|
||||
return await CreateToken(true, user);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue