Skip to content

Commit

Permalink
feat: ✨ Recently Requested on Discover Page (#4387)
Browse files Browse the repository at this point in the history
  • Loading branch information
tidusjar authored Aug 9, 2022
1 parent 26ac75f commit 44d38fb
Show file tree
Hide file tree
Showing 46 changed files with 3,810 additions and 3,592 deletions.
205 changes: 205 additions & 0 deletions src/Ombi.Core.Tests/Services/RecentlyRequestedServiceTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
using AutoFixture;
using MockQueryable.Moq;
using Moq;
using Moq.AutoMock;
using NUnit.Framework;
using Ombi.Core.Authentication;
using Ombi.Core.Helpers;
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);
_mocker.Setup<ICurrentUser, Task<OmbiUser>>(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "test", Alias = "alias" });
_mocker.Setup<ICurrentUser, string>(x => x.Username).Returns("test");

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);
_mocker.Setup<ICurrentUser, Task<OmbiUser>>(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "test", Alias = "alias" });
_mocker.Setup<ICurrentUser, string>(x => x.Username).Returns("test");

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);
_mocker.Setup<ICurrentUser, Task<OmbiUser>>(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "test", Alias = "alias" });
_mocker.Setup<ICurrentUser, string>(x => x.Username).Returns("test");

var result = await _subject.GetRecentlyRequested(CancellationToken.None);

Assert.That(result.Count, Is.EqualTo(21));
}


[Test]
public async Task GetRecentlyRequested_HideUsernames()
{
_mocker.Setup<ISettingsService<CustomizationSettings>, Task<CustomizationSettings>>(x => x.GetSettingsAsync())
.ReturnsAsync(new CustomizationSettings());
_mocker.Setup<ISettingsService<OmbiSettings>, Task<OmbiSettings>>(x => x.GetSettingsAsync())
.ReturnsAsync(new OmbiSettings { HideRequestsUsers = true });
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);
_mocker.Setup<ICurrentUser, Task<OmbiUser>>(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "test", Alias = "alias", UserType = UserType.LocalUser });
_mocker.Setup<ICurrentUser, string>(x => x.Username).Returns("test");
_mocker.Setup<OmbiUserManager, Task<bool>>(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), It.IsAny<string>())).ReturnsAsync(false);

var result = await _subject.GetRecentlyRequested(CancellationToken.None);

CollectionAssert.IsEmpty(result.Where(x => !string.IsNullOrEmpty(x.Username) && !string.IsNullOrEmpty(x.UserId)));
}
}
}
8 changes: 4 additions & 4 deletions src/Ombi.Core/Engine/MovieRequestEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,11 @@ public async Task<RequestEngineResult> RequestMovie(MovieRequestViewModel model)
if (model.Is4kRequest)
{
existingRequest.Is4kRequest = true;
existingRequest.RequestedDate4k = DateTime.Now;
existingRequest.RequestedDate4k = DateTime.UtcNow;
}
else
{
existingRequest.RequestedDate = DateTime.Now;
existingRequest.RequestedDate = DateTime.UtcNow;
}
isExisting = true;
requestModel = existingRequest;
Expand All @@ -134,7 +134,7 @@ public async Task<RequestEngineResult> RequestMovie(MovieRequestViewModel model)
? DateTime.Parse(movieInfo.ReleaseDate)
: DateTime.MinValue,
Status = movieInfo.Status,
RequestedDate = model.Is4kRequest ? DateTime.MinValue : DateTime.Now,
RequestedDate = model.Is4kRequest ? DateTime.MinValue : DateTime.UtcNow,
Approved = false,
Approved4K = false,
RequestedUserId = canRequestOnBehalf ? model.RequestOnBehalf : userDetails.Id,
Expand All @@ -143,7 +143,7 @@ public async Task<RequestEngineResult> RequestMovie(MovieRequestViewModel model)
RequestedByAlias = model.RequestedByAlias,
RootPathOverride = model.RootFolderOverride.GetValueOrDefault(),
QualityOverride = model.QualityPathOverride.GetValueOrDefault(),
RequestedDate4k = model.Is4kRequest ? DateTime.Now : DateTime.MinValue,
RequestedDate4k = model.Is4kRequest ? DateTime.UtcNow : DateTime.MinValue,
Is4kRequest = model.Is4kRequest,
Source = model.Source
};
Expand Down
5 changes: 4 additions & 1 deletion src/Ombi.Core/IImageService.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
using System.Threading.Tasks;
using System.Threading;
using System.Threading.Tasks;

namespace Ombi.Core
{
public interface IImageService
{
Task<string> GetTvBackground(string tvdbId);
Task<string> GetTmdbTvBackground(string id, CancellationToken token);
Task<string> GetTmdbTvPoster(string tmdbId, CancellationToken token);
}
}
77 changes: 76 additions & 1 deletion src/Ombi.Core/ImageService.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Ombi.Api.FanartTv;
using Ombi.Api.TheMovieDb;
using Ombi.Core.Helpers;
using Ombi.Core.Settings;
using Ombi.Helpers;
using Ombi.Settings.Settings.Models;
using Ombi.Store.Repository;

namespace Ombi.Core
Expand All @@ -12,13 +17,19 @@ public class ImageService : IImageService
private readonly IApplicationConfigRepository _configRepository;
private readonly IFanartTvApi _fanartTvApi;
private readonly ICacheService _cache;
private readonly IMovieDbApi _movieDbApi;
private readonly ICurrentUser _user;
private readonly ISettingsService<OmbiSettings> _ombiSettings;

public ImageService(IApplicationConfigRepository configRepository, IFanartTvApi fanartTvApi,
ICacheService cache)
ICacheService cache, IMovieDbApi movieDbApi, ICurrentUser user, ISettingsService<OmbiSettings> ombiSettings)
{
_configRepository = configRepository;
_fanartTvApi = fanartTvApi;
_cache = cache;
_movieDbApi = movieDbApi;
_user = user;
_ombiSettings = ombiSettings;
}

public async Task<string> GetTvBackground(string tvdbId)
Expand All @@ -43,5 +54,69 @@ public async Task<string> GetTvBackground(string tvdbId)

return string.Empty;
}

public async Task<string> GetTmdbTvBackground(string id, CancellationToken token)
{
var images = await _cache.GetOrAddAsync($"{CacheKeys.TmdbImages}tv{id}", () => _movieDbApi.GetTvImages(id, token), DateTimeOffset.Now.AddDays(1));

if (images?.backdrops?.Any() ?? false)
{
return images.backdrops.Select(x => x.file_path).FirstOrDefault();
}
if (images?.posters?.Any() ?? false)
{
return images.posters.Select(x => x.file_path).FirstOrDefault();
}

return string.Empty;
}

public async Task<string> GetTmdbTvPoster(string tmdbId, CancellationToken token)
{
var images = await _cache.GetOrAddAsync($"{CacheKeys.TmdbImages}tv{tmdbId}", () => _movieDbApi.GetTvImages(tmdbId, token), DateTimeOffset.Now.AddDays(1));

if (images?.posters?.Any() ?? false)
{
var lang = await DefaultLanguageCode();
var langImage = images.posters.Where(x => lang.Equals(x.iso_639_1, StringComparison.InvariantCultureIgnoreCase)).OrderByDescending(x => x.vote_count);
if (langImage.Any())
{
return langImage.Select(x => x.file_path).First();
}
else
{
return images.posters.Select(x => x.file_path).First();
}
}

if (images?.backdrops?.Any() ?? false)
{
return images.backdrops.Select(x => x.file_path).FirstOrDefault();
}
return string.Empty;
}

protected async Task<string> DefaultLanguageCode()
{
var user = await _user.GetUser();
if (user == null)
{
return "en";
}

if (string.IsNullOrEmpty(user.Language))
{
var s = await GetOmbiSettings();
return s.DefaultLanguageCode;
}

return user.Language;
}

private OmbiSettings ombiSettings;
protected async Task<OmbiSettings> GetOmbiSettings()
{
return ombiSettings ?? (ombiSettings = await _ombiSettings.GetSettingsAsync());
}
}
}
21 changes: 21 additions & 0 deletions src/Ombi.Core/Models/Requests/RecentlyRequestedModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
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; }
public string MediaId { get; set; }
}
}
12 changes: 12 additions & 0 deletions src/Ombi.Core/Services/IRecentlyRequestedService.cs
Original file line number Diff line number Diff line change
@@ -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);
}
}
Loading

0 comments on commit 44d38fb

Please sign in to comment.