mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-22 14:13:36 -07:00
feat(discover): ✨ Added a new API to query recently requested content
This commit is contained in:
parent
acc66fad49
commit
7d3be883d6
7 changed files with 326 additions and 1 deletions
170
src/Ombi.Core.Tests/Services/RecentlyRequestedServiceTests.cs
Normal file
170
src/Ombi.Core.Tests/Services/RecentlyRequestedServiceTests.cs
Normal file
|
@ -0,0 +1,170 @@
|
|||
using AutoFixture;
|
||||
using MockQueryable.Moq;
|
||||
using Moq;
|
||||
using Moq.AutoMock;
|
||||
using NUnit.Framework;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Services;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Settings.Settings.Models;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
using Ombi.Store.Repository.Requests;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ombi.Core.Tests.Services
|
||||
{
|
||||
[TestFixture]
|
||||
public class RecentlyRequestedServiceTests
|
||||
{
|
||||
private AutoMocker _mocker;
|
||||
private RecentlyRequestedService _subject;
|
||||
private Fixture _fixture;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_fixture = new Fixture();
|
||||
|
||||
_fixture.Behaviors.OfType<ThrowingRecursionBehavior>().ToList()
|
||||
.ForEach(b => _fixture.Behaviors.Remove(b));
|
||||
_fixture.Behaviors.Add(new OmitOnRecursionBehavior());
|
||||
_mocker = new AutoMocker();
|
||||
_subject = _mocker.CreateInstance<RecentlyRequestedService>();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetRecentlyRequested_Movies()
|
||||
{
|
||||
_mocker.Setup<ISettingsService<CustomizationSettings>, Task<CustomizationSettings>>(x => x.GetSettingsAsync())
|
||||
.ReturnsAsync(new CustomizationSettings());
|
||||
var releaseDate = new DateTime(2019, 01, 01);
|
||||
var requestDate = DateTime.Now;
|
||||
var movies = new List<MovieRequests>
|
||||
{
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 1,
|
||||
Approved = true,
|
||||
Available = true,
|
||||
ReleaseDate = releaseDate,
|
||||
Title = "title",
|
||||
Overview = "overview",
|
||||
RequestedDate = requestDate,
|
||||
RequestedUser = new Store.Entities.OmbiUser
|
||||
{
|
||||
UserName = "a"
|
||||
},
|
||||
RequestedUserId = "b",
|
||||
}
|
||||
};
|
||||
var albums = new List<AlbumRequest>();
|
||||
var chilRequests = new List<ChildRequests>();
|
||||
_mocker.Setup<IMovieRequestRepository, IQueryable<MovieRequests>>(x => x.GetAll()).Returns(movies.AsQueryable().BuildMock().Object);
|
||||
_mocker.Setup<IMusicRequestRepository, IQueryable<AlbumRequest>>(x => x.GetAll()).Returns(albums.AsQueryable().BuildMock().Object);
|
||||
_mocker.Setup<ITvRequestRepository, IQueryable<ChildRequests>>(x => x.GetChild()).Returns(chilRequests.AsQueryable().BuildMock().Object);
|
||||
|
||||
var result = await _subject.GetRecentlyRequested(CancellationToken.None);
|
||||
|
||||
Assert.That(result.Count, Is.EqualTo(1));
|
||||
Assert.That(result.First(), Is.InstanceOf<RecentlyRequestedModel>()
|
||||
.With.Property(nameof(RecentlyRequestedModel.RequestId)).EqualTo(1)
|
||||
.With.Property(nameof(RecentlyRequestedModel.Approved)).EqualTo(true)
|
||||
.With.Property(nameof(RecentlyRequestedModel.Available)).EqualTo(true)
|
||||
.With.Property(nameof(RecentlyRequestedModel.Title)).EqualTo("title")
|
||||
.With.Property(nameof(RecentlyRequestedModel.Overview)).EqualTo("overview")
|
||||
.With.Property(nameof(RecentlyRequestedModel.RequestDate)).EqualTo(requestDate)
|
||||
.With.Property(nameof(RecentlyRequestedModel.ReleaseDate)).EqualTo(releaseDate)
|
||||
.With.Property(nameof(RecentlyRequestedModel.Type)).EqualTo(RequestType.Movie)
|
||||
);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetRecentlyRequested_Movies_HideAvailable()
|
||||
{
|
||||
_mocker.Setup<ISettingsService<CustomizationSettings>, Task<CustomizationSettings>>(x => x.GetSettingsAsync())
|
||||
.ReturnsAsync(new CustomizationSettings() { HideAvailableRecentlyRequested = true });
|
||||
var releaseDate = new DateTime(2019, 01, 01);
|
||||
var requestDate = DateTime.Now;
|
||||
var movies = new List<MovieRequests>
|
||||
{
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 1,
|
||||
Approved = true,
|
||||
Available = true,
|
||||
ReleaseDate = releaseDate,
|
||||
Title = "title",
|
||||
Overview = "overview",
|
||||
RequestedDate = requestDate,
|
||||
RequestedUser = new Store.Entities.OmbiUser
|
||||
{
|
||||
UserName = "a"
|
||||
},
|
||||
RequestedUserId = "b",
|
||||
},
|
||||
|
||||
new MovieRequests
|
||||
{
|
||||
Id = 1,
|
||||
Approved = true,
|
||||
Available = false,
|
||||
ReleaseDate = releaseDate,
|
||||
Title = "title2",
|
||||
Overview = "overview2",
|
||||
RequestedDate = requestDate,
|
||||
RequestedUser = new Store.Entities.OmbiUser
|
||||
{
|
||||
UserName = "a"
|
||||
},
|
||||
RequestedUserId = "b",
|
||||
}
|
||||
};
|
||||
var albums = new List<AlbumRequest>();
|
||||
var chilRequests = new List<ChildRequests>();
|
||||
_mocker.Setup<IMovieRequestRepository, IQueryable<MovieRequests>>(x => x.GetAll()).Returns(movies.AsQueryable().BuildMock().Object);
|
||||
_mocker.Setup<IMusicRequestRepository, IQueryable<AlbumRequest>>(x => x.GetAll()).Returns(albums.AsQueryable().BuildMock().Object);
|
||||
_mocker.Setup<ITvRequestRepository, IQueryable<ChildRequests>>(x => x.GetChild()).Returns(chilRequests.AsQueryable().BuildMock().Object);
|
||||
|
||||
var result = await _subject.GetRecentlyRequested(CancellationToken.None);
|
||||
|
||||
Assert.That(result.Count, Is.EqualTo(1));
|
||||
Assert.That(result.First(), Is.InstanceOf<RecentlyRequestedModel>()
|
||||
.With.Property(nameof(RecentlyRequestedModel.RequestId)).EqualTo(1)
|
||||
.With.Property(nameof(RecentlyRequestedModel.Approved)).EqualTo(true)
|
||||
.With.Property(nameof(RecentlyRequestedModel.Available)).EqualTo(false)
|
||||
.With.Property(nameof(RecentlyRequestedModel.Title)).EqualTo("title2")
|
||||
.With.Property(nameof(RecentlyRequestedModel.Overview)).EqualTo("overview2")
|
||||
.With.Property(nameof(RecentlyRequestedModel.RequestDate)).EqualTo(requestDate)
|
||||
.With.Property(nameof(RecentlyRequestedModel.ReleaseDate)).EqualTo(releaseDate)
|
||||
.With.Property(nameof(RecentlyRequestedModel.Type)).EqualTo(RequestType.Movie)
|
||||
);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task GetRecentlyRequested()
|
||||
{
|
||||
_mocker.Setup<ISettingsService<CustomizationSettings>, Task<CustomizationSettings>>(x => x.GetSettingsAsync())
|
||||
.ReturnsAsync(new CustomizationSettings());
|
||||
var releaseDate = new DateTime(2019, 01, 01);
|
||||
var requestDate = DateTime.Now;
|
||||
|
||||
var movies = _fixture.CreateMany<MovieRequests>(10);
|
||||
var albums = _fixture.CreateMany<AlbumRequest>(10);
|
||||
var chilRequests = _fixture.CreateMany<ChildRequests>(10);
|
||||
|
||||
_mocker.Setup<IMovieRequestRepository, IQueryable<MovieRequests>>(x => x.GetAll()).Returns(movies.AsQueryable().BuildMock().Object);
|
||||
_mocker.Setup<IMusicRequestRepository, IQueryable<AlbumRequest>>(x => x.GetAll()).Returns(albums.AsQueryable().BuildMock().Object);
|
||||
_mocker.Setup<ITvRequestRepository, IQueryable<ChildRequests>>(x => x.GetChild()).Returns(chilRequests.AsQueryable().BuildMock().Object);
|
||||
|
||||
var result = await _subject.GetRecentlyRequested(CancellationToken.None);
|
||||
|
||||
Assert.That(result.Count, Is.EqualTo(21));
|
||||
}
|
||||
}
|
||||
}
|
20
src/Ombi.Core/Models/Requests/RecentlyRequestedModel.cs
Normal file
20
src/Ombi.Core/Models/Requests/RecentlyRequestedModel.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using Ombi.Store.Entities;
|
||||
using System;
|
||||
|
||||
namespace Ombi.Core.Models.Requests
|
||||
{
|
||||
public class RecentlyRequestedModel
|
||||
{
|
||||
public int RequestId { get; set; }
|
||||
public RequestType Type { get; set; }
|
||||
public string UserId { get; set; }
|
||||
public string Username { get; set; }
|
||||
public bool Available { get; set; }
|
||||
public bool TvPartiallyAvailable { get; set; }
|
||||
public DateTime RequestDate { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Overview { get; set; }
|
||||
public DateTime ReleaseDate { get; set; }
|
||||
public bool Approved { get; set; }
|
||||
}
|
||||
}
|
12
src/Ombi.Core/Services/IRecentlyRequestedService.cs
Normal file
12
src/Ombi.Core/Services/IRecentlyRequestedService.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
using Ombi.Core.Models.Requests;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ombi.Core.Services
|
||||
{
|
||||
public interface IRecentlyRequestedService
|
||||
{
|
||||
Task<IEnumerable<RecentlyRequestedModel>> GetRecentlyRequested(CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
111
src/Ombi.Core/Services/RecentlyRequestedService.cs
Normal file
111
src/Ombi.Core/Services/RecentlyRequestedService.cs
Normal file
|
@ -0,0 +1,111 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Settings.Settings.Models;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Repository.Requests;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ombi.Core.Services
|
||||
{
|
||||
public class RecentlyRequestedService : IRecentlyRequestedService
|
||||
{
|
||||
private readonly IMovieRequestRepository _movieRequestRepository;
|
||||
private readonly ITvRequestRepository _tvRequestRepository;
|
||||
private readonly IMusicRequestRepository _musicRequestRepository;
|
||||
private readonly ISettingsService<CustomizationSettings> _customizationSettings;
|
||||
|
||||
private const int AmountToTake = 7;
|
||||
|
||||
public RecentlyRequestedService(
|
||||
IMovieRequestRepository movieRequestRepository,
|
||||
ITvRequestRepository tvRequestRepository,
|
||||
IMusicRequestRepository musicRequestRepository,
|
||||
ISettingsService<CustomizationSettings> customizationSettings)
|
||||
{
|
||||
_movieRequestRepository = movieRequestRepository;
|
||||
_tvRequestRepository = tvRequestRepository;
|
||||
_musicRequestRepository = musicRequestRepository;
|
||||
_customizationSettings = customizationSettings;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RecentlyRequestedModel>> GetRecentlyRequested(CancellationToken cancellationToken)
|
||||
{
|
||||
var customizationSettingsTask = _customizationSettings.GetSettingsAsync();
|
||||
|
||||
var recentMovieRequests = _movieRequestRepository.GetAll().Include(x => x.RequestedUser).OrderByDescending(x => x.RequestedDate).Take(AmountToTake);
|
||||
var recentTvRequests = _tvRequestRepository.GetChild().Include(x => x.RequestedUser).Include(x => x.ParentRequest).OrderByDescending(x => x.RequestedDate).Take(AmountToTake);
|
||||
var recentMusicRequests = _musicRequestRepository.GetAll().Include(x => x.RequestedUser).OrderByDescending(x => x.RequestedDate).Take(AmountToTake);
|
||||
|
||||
var settings = await customizationSettingsTask;
|
||||
if (settings.HideAvailableRecentlyRequested)
|
||||
{
|
||||
recentMovieRequests = recentMovieRequests.Where(x => !x.Available);
|
||||
recentTvRequests = recentTvRequests.Where(x => !x.Available);
|
||||
recentMusicRequests = recentMusicRequests.Where(x => !x.Available);
|
||||
}
|
||||
|
||||
var model = new List<RecentlyRequestedModel>();
|
||||
|
||||
foreach (var item in await recentMovieRequests.ToListAsync(cancellationToken))
|
||||
{
|
||||
model.Add(new RecentlyRequestedModel
|
||||
{
|
||||
RequestId = item.Id,
|
||||
Available = item.Available,
|
||||
Overview = item.Overview,
|
||||
ReleaseDate = item.ReleaseDate,
|
||||
RequestDate = item.RequestedDate,
|
||||
Title = item.Title,
|
||||
Type = RequestType.Movie,
|
||||
Approved = item.Approved,
|
||||
UserId = item.RequestedUserId,
|
||||
Username = item.RequestedUser.UserAlias
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var item in await recentMusicRequests.ToListAsync(cancellationToken))
|
||||
{
|
||||
model.Add(new RecentlyRequestedModel
|
||||
{
|
||||
RequestId = item.Id,
|
||||
Available = item.Available,
|
||||
Overview = item.ArtistName,
|
||||
Approved = item.Approved,
|
||||
ReleaseDate = item.ReleaseDate,
|
||||
RequestDate = item.RequestedDate,
|
||||
Title = item.Title,
|
||||
Type = RequestType.Album,
|
||||
UserId = item.RequestedUserId,
|
||||
Username = item.RequestedUser.UserAlias
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var item in await recentTvRequests.ToListAsync(cancellationToken))
|
||||
{
|
||||
var partialAvailability = item.SeasonRequests.SelectMany(x => x.Episodes).Any(e => e.Available);
|
||||
model.Add(new RecentlyRequestedModel
|
||||
{
|
||||
RequestId = item.Id,
|
||||
Available = item.Available,
|
||||
Overview = item.ParentRequest.Overview,
|
||||
ReleaseDate = item.ParentRequest.ReleaseDate,
|
||||
Approved = item.Approved,
|
||||
RequestDate = item.RequestedDate,
|
||||
TvPartiallyAvailable = partialAvailability,
|
||||
Title = item.ParentRequest.Title,
|
||||
Type = RequestType.TvShow,
|
||||
UserId = item.RequestedUserId,
|
||||
Username = item.RequestedUser.UserAlias
|
||||
});
|
||||
}
|
||||
|
||||
return model.OrderByDescending(x => x.RequestDate);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -224,6 +224,7 @@ namespace Ombi.DependencyInjection
|
|||
services.AddTransient<ITelegramNotification, TelegramNotification>();
|
||||
services.AddTransient<ILegacyMobileNotification, LegacyMobileNotification>();
|
||||
services.AddTransient<IChangeLogProcessor, ChangeLogProcessor>();
|
||||
services.AddTransient<IRecentlyRequestedService, RecentlyRequestedService>();
|
||||
}
|
||||
|
||||
public static void RegisterJobs(this IServiceCollection services)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
public bool RecentlyAddedPage { get; set; }
|
||||
public bool UseCustomPage { get; set; }
|
||||
public bool HideAvailableFromDiscover { get; set; }
|
||||
public bool HideAvailableRecentlyRequested { get; set; }
|
||||
|
||||
public string AddToUrl(string part)
|
||||
{
|
||||
|
|
|
@ -13,6 +13,8 @@ using System.Linq;
|
|||
using Microsoft.Extensions.Logging;
|
||||
using Ombi.Attributes;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Core.Services;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ombi.Controllers.V2
|
||||
{
|
||||
|
@ -24,15 +26,17 @@ namespace Ombi.Controllers.V2
|
|||
private readonly IMusicRequestEngine _musicRequestEngine;
|
||||
private readonly IVoteEngine _voteEngine;
|
||||
private readonly ILogger<RequestsController> _logger;
|
||||
private readonly IRecentlyRequestedService _recentlyRequestedService;
|
||||
|
||||
public RequestsController(IMovieRequestEngine movieRequestEngine, ITvRequestEngine tvRequestEngine, IMusicRequestEngine musicRequestEngine,
|
||||
IVoteEngine voteEngine, ILogger<RequestsController> logger)
|
||||
IVoteEngine voteEngine, ILogger<RequestsController> logger, IRecentlyRequestedService recentlyRequestedService)
|
||||
{
|
||||
_movieRequestEngine = movieRequestEngine;
|
||||
_tvRequestEngine = tvRequestEngine;
|
||||
_musicRequestEngine = musicRequestEngine;
|
||||
_voteEngine = voteEngine;
|
||||
_logger = logger;
|
||||
_recentlyRequestedService = recentlyRequestedService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -223,6 +227,12 @@ namespace Ombi.Controllers.V2
|
|||
return await _movieRequestEngine.RequestCollection(collectionId, HttpContext.RequestAborted);
|
||||
}
|
||||
|
||||
[HttpGet("recentlyRequested")]
|
||||
public Task<IEnumerable<RecentlyRequestedModel>> RecentlyRequested()
|
||||
{
|
||||
return _recentlyRequestedService.GetRecentlyRequested(CancellationToken);
|
||||
}
|
||||
|
||||
private string GetApiAlias()
|
||||
{
|
||||
// Make sure this only applies when using the API KEY
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue