mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-22 14:13:36 -07:00
feat(discover): ⚡ Images for the recently requested area are now loading faster and just better all around
This commit is contained in:
parent
6e7303fb3b
commit
363b30d96b
8 changed files with 84 additions and 30 deletions
|
@ -37,6 +37,9 @@ namespace Ombi.Core.Tests.Services
|
||||||
.ForEach(b => _fixture.Behaviors.Remove(b));
|
.ForEach(b => _fixture.Behaviors.Remove(b));
|
||||||
_fixture.Behaviors.Add(new OmitOnRecursionBehavior());
|
_fixture.Behaviors.Add(new OmitOnRecursionBehavior());
|
||||||
_mocker = new AutoMocker();
|
_mocker = new AutoMocker();
|
||||||
|
|
||||||
|
_mocker.Setup<ICurrentUser, Task<OmbiUser>>(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "test", Alias = "alias", Language = "en" });
|
||||||
|
_mocker.Setup<ICurrentUser, string>(x => x.Username).Returns("test");
|
||||||
_subject = _mocker.CreateInstance<RecentlyRequestedService>();
|
_subject = _mocker.CreateInstance<RecentlyRequestedService>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,8 +73,6 @@ namespace Ombi.Core.Tests.Services
|
||||||
_mocker.Setup<IMovieRequestRepository, IQueryable<MovieRequests>>(x => x.GetAll()).Returns(movies.AsQueryable().BuildMock().Object);
|
_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<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<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);
|
var result = await _subject.GetRecentlyRequested(CancellationToken.None);
|
||||||
|
|
||||||
|
@ -134,8 +135,6 @@ namespace Ombi.Core.Tests.Services
|
||||||
_mocker.Setup<IMovieRequestRepository, IQueryable<MovieRequests>>(x => x.GetAll()).Returns(movies.AsQueryable().BuildMock().Object);
|
_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<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<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);
|
var result = await _subject.GetRecentlyRequested(CancellationToken.None);
|
||||||
|
|
||||||
|
@ -167,8 +166,6 @@ namespace Ombi.Core.Tests.Services
|
||||||
_mocker.Setup<IMovieRequestRepository, IQueryable<MovieRequests>>(x => x.GetAll()).Returns(movies.AsQueryable().BuildMock().Object);
|
_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<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<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);
|
var result = await _subject.GetRecentlyRequested(CancellationToken.None);
|
||||||
|
|
||||||
|
|
|
@ -17,5 +17,8 @@ namespace Ombi.Core.Models.Requests
|
||||||
public DateTime ReleaseDate { get; set; }
|
public DateTime ReleaseDate { get; set; }
|
||||||
public bool Approved { get; set; }
|
public bool Approved { get; set; }
|
||||||
public string MediaId { get; set; }
|
public string MediaId { get; set; }
|
||||||
|
|
||||||
|
public string PosterPath { get; set; }
|
||||||
|
public string Background { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Ombi.Api.TheMovieDb;
|
||||||
using Ombi.Core.Authentication;
|
using Ombi.Core.Authentication;
|
||||||
using Ombi.Core.Engine.Interfaces;
|
using Ombi.Core.Engine.Interfaces;
|
||||||
using Ombi.Core.Helpers;
|
using Ombi.Core.Helpers;
|
||||||
|
@ -12,7 +13,6 @@ using Ombi.Store.Repository.Requests;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using static Ombi.Core.Engine.BaseMediaEngine;
|
using static Ombi.Core.Engine.BaseMediaEngine;
|
||||||
|
@ -26,7 +26,8 @@ namespace Ombi.Core.Services
|
||||||
private readonly IMusicRequestRepository _musicRequestRepository;
|
private readonly IMusicRequestRepository _musicRequestRepository;
|
||||||
private readonly ISettingsService<CustomizationSettings> _customizationSettings;
|
private readonly ISettingsService<CustomizationSettings> _customizationSettings;
|
||||||
private readonly ISettingsService<OmbiSettings> _ombiSettings;
|
private readonly ISettingsService<OmbiSettings> _ombiSettings;
|
||||||
|
private readonly IMovieDbApi _movieDbApi;
|
||||||
|
private readonly ICacheService _cache;
|
||||||
private const int AmountToTake = 7;
|
private const int AmountToTake = 7;
|
||||||
|
|
||||||
public RecentlyRequestedService(
|
public RecentlyRequestedService(
|
||||||
|
@ -37,13 +38,17 @@ namespace Ombi.Core.Services
|
||||||
ISettingsService<OmbiSettings> ombiSettings,
|
ISettingsService<OmbiSettings> ombiSettings,
|
||||||
ICurrentUser user,
|
ICurrentUser user,
|
||||||
OmbiUserManager um,
|
OmbiUserManager um,
|
||||||
IRuleEvaluator rules) : base(user, um, rules)
|
IRuleEvaluator rules,
|
||||||
|
IMovieDbApi movieDbApi,
|
||||||
|
ICacheService cache) : base(user, um, rules)
|
||||||
{
|
{
|
||||||
_movieRequestRepository = movieRequestRepository;
|
_movieRequestRepository = movieRequestRepository;
|
||||||
_tvRequestRepository = tvRequestRepository;
|
_tvRequestRepository = tvRequestRepository;
|
||||||
_musicRequestRepository = musicRequestRepository;
|
_musicRequestRepository = musicRequestRepository;
|
||||||
_customizationSettings = customizationSettings;
|
_customizationSettings = customizationSettings;
|
||||||
_ombiSettings = ombiSettings;
|
_ombiSettings = ombiSettings;
|
||||||
|
_movieDbApi = movieDbApi;
|
||||||
|
_cache = cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<RecentlyRequestedModel>> GetRecentlyRequested(CancellationToken cancellationToken)
|
public async Task<IEnumerable<RecentlyRequestedModel>> GetRecentlyRequested(CancellationToken cancellationToken)
|
||||||
|
@ -65,8 +70,10 @@ namespace Ombi.Core.Services
|
||||||
|
|
||||||
var model = new List<RecentlyRequestedModel>();
|
var model = new List<RecentlyRequestedModel>();
|
||||||
|
|
||||||
|
var lang = await DefaultLanguageCode();
|
||||||
foreach (var item in await recentMovieRequests.ToListAsync(cancellationToken))
|
foreach (var item in await recentMovieRequests.ToListAsync(cancellationToken))
|
||||||
{
|
{
|
||||||
|
var images = await _cache.GetOrAddAsync($"{CacheKeys.TmdbImages}movie{item.TheMovieDbId}", () => _movieDbApi.GetMovieImages(item.TheMovieDbId.ToString(), cancellationToken), DateTimeOffset.Now.AddDays(1));
|
||||||
model.Add(new RecentlyRequestedModel
|
model.Add(new RecentlyRequestedModel
|
||||||
{
|
{
|
||||||
RequestId = item.Id,
|
RequestId = item.Id,
|
||||||
|
@ -80,6 +87,8 @@ namespace Ombi.Core.Services
|
||||||
UserId = hideUsers.Hide ? string.Empty : item.RequestedUserId,
|
UserId = hideUsers.Hide ? string.Empty : item.RequestedUserId,
|
||||||
Username = hideUsers.Hide ? string.Empty : item.RequestedUser.UserAlias,
|
Username = hideUsers.Hide ? string.Empty : item.RequestedUser.UserAlias,
|
||||||
MediaId = item.TheMovieDbId.ToString(),
|
MediaId = item.TheMovieDbId.ToString(),
|
||||||
|
PosterPath = images?.posters?.Where(x => lang.Equals(x?.iso_639_1, StringComparison.InvariantCultureIgnoreCase))?.OrderByDescending(x => x.vote_count)?.Select(x => x.file_path)?.FirstOrDefault(),
|
||||||
|
Background = images?.backdrops?.Where(x => lang.Equals(x?.iso_639_1, StringComparison.InvariantCultureIgnoreCase))?.OrderByDescending(x => x.vote_count)?.Select(x => x.file_path)?.FirstOrDefault(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +112,9 @@ namespace Ombi.Core.Services
|
||||||
|
|
||||||
foreach (var item in await recentTvRequests.ToListAsync(cancellationToken))
|
foreach (var item in await recentTvRequests.ToListAsync(cancellationToken))
|
||||||
{
|
{
|
||||||
|
var providerId = item.ParentRequest.ExternalProviderId.ToString();
|
||||||
|
var images = await _cache.GetOrAddAsync($"{CacheKeys.TmdbImages}tv{providerId}", () => _movieDbApi.GetTvImages(providerId.ToString(), cancellationToken), DateTimeOffset.Now.AddDays(1));
|
||||||
|
|
||||||
var partialAvailability = item.SeasonRequests.SelectMany(x => x.Episodes).Any(e => e.Available);
|
var partialAvailability = item.SeasonRequests.SelectMany(x => x.Episodes).Any(e => e.Available);
|
||||||
model.Add(new RecentlyRequestedModel
|
model.Add(new RecentlyRequestedModel
|
||||||
{
|
{
|
||||||
|
@ -117,7 +129,9 @@ namespace Ombi.Core.Services
|
||||||
Type = RequestType.TvShow,
|
Type = RequestType.TvShow,
|
||||||
UserId = hideUsers.Hide ? string.Empty : item.RequestedUserId,
|
UserId = hideUsers.Hide ? string.Empty : item.RequestedUserId,
|
||||||
Username = hideUsers.Hide ? string.Empty : item.RequestedUser.UserAlias,
|
Username = hideUsers.Hide ? string.Empty : item.RequestedUser.UserAlias,
|
||||||
MediaId = item.ParentRequest.ExternalProviderId.ToString()
|
MediaId = providerId.ToString(),
|
||||||
|
PosterPath = images?.posters?.Where(x => lang.Equals(x?.iso_639_1, StringComparison.InvariantCultureIgnoreCase))?.OrderByDescending(x => x.vote_count)?.Select(x => x.file_path)?.FirstOrDefault(),
|
||||||
|
Background = images?.backdrops?.Where(x => lang.Equals(x?.iso_639_1, StringComparison.InvariantCultureIgnoreCase))?.OrderByDescending(x => x.vote_count)?.Select(x => x.file_path)?.FirstOrDefault(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +148,7 @@ namespace Ombi.Core.Services
|
||||||
UserId = user.Id
|
UserId = user.Id
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
var settings = await _ombiSettings.GetSettingsAsync();
|
var settings = await GetOmbiSettings();
|
||||||
var result = new HideResult
|
var result = new HideResult
|
||||||
{
|
{
|
||||||
Hide = settings.HideRequestsUsers,
|
Hide = settings.HideRequestsUsers,
|
||||||
|
@ -142,5 +156,28 @@ namespace Ombi.Core.Services
|
||||||
};
|
};
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
protected async Task<string> DefaultLanguageCode()
|
||||||
|
{
|
||||||
|
var user = await 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 ??= await _ombiSettings.GetSettingsAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ namespace Ombi.Api.TheMovieDb
|
||||||
Task<List<Language>> GetLanguages(CancellationToken cancellationToken);
|
Task<List<Language>> GetLanguages(CancellationToken cancellationToken);
|
||||||
Task<List<WatchProvidersResults>> SearchWatchProviders(string media, string searchTerm, CancellationToken cancellationToken);
|
Task<List<WatchProvidersResults>> SearchWatchProviders(string media, string searchTerm, CancellationToken cancellationToken);
|
||||||
Task<List<MovieDbSearchResult>> AdvancedSearch(DiscoverModel model, int page, CancellationToken cancellationToken);
|
Task<List<MovieDbSearchResult>> AdvancedSearch(DiscoverModel model, int page, CancellationToken cancellationToken);
|
||||||
Task<TvImages> GetTvImages(string theMovieDbId, CancellationToken token);
|
Task<MovieDbImages> GetTvImages(string theMovieDbId, CancellationToken token);
|
||||||
|
Task<MovieDbImages> GetMovieImages(string theMovieDbId, CancellationToken token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
namespace Ombi.Api.TheMovieDb.Models
|
namespace Ombi.Api.TheMovieDb.Models
|
||||||
{
|
{
|
||||||
public class TvImages
|
public class MovieDbImages
|
||||||
{
|
{
|
||||||
public Backdrop[] backdrops { get; set; }
|
public Backdrop[] backdrops { get; set; }
|
||||||
public int id { get; set; }
|
public int id { get; set; }
|
||||||
|
|
|
@ -514,12 +514,20 @@ namespace Ombi.Api.TheMovieDb
|
||||||
return Api.Request<WatchProviders>(request, token);
|
return Api.Request<WatchProviders>(request, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<TvImages> GetTvImages(string theMovieDbId, CancellationToken token)
|
public Task<MovieDbImages> GetTvImages(string theMovieDbId, CancellationToken token)
|
||||||
{
|
{
|
||||||
var request = new Request($"tv/{theMovieDbId}/images", BaseUri, HttpMethod.Get);
|
var request = new Request($"tv/{theMovieDbId}/images", BaseUri, HttpMethod.Get);
|
||||||
request.AddQueryString("api_key", ApiToken);
|
request.AddQueryString("api_key", ApiToken);
|
||||||
|
|
||||||
return Api.Request<TvImages>(request, token);
|
return Api.Request<MovieDbImages>(request, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<MovieDbImages> GetMovieImages(string theMovieDbId, CancellationToken token)
|
||||||
|
{
|
||||||
|
var request = new Request($"movie/{theMovieDbId}/images", BaseUri, HttpMethod.Get);
|
||||||
|
request.AddQueryString("api_key", ApiToken);
|
||||||
|
|
||||||
|
return Api.Request<MovieDbImages>(request, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task AddDiscoverSettings(Request request)
|
private async Task AddDiscoverSettings(Request request)
|
||||||
|
|
|
@ -27,20 +27,10 @@ import { DomSanitizer, SafeStyle } from "@angular/platform-browser";
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
if (!this.request.posterPath) {
|
if (!this.request.posterPath) {
|
||||||
switch (this.request.type) {
|
this.loadImages();
|
||||||
case RequestType.movie:
|
} else {
|
||||||
this.imageService.getMoviePoster(this.request.mediaId).pipe(takeUntil(this.$imageSub)).subscribe(x => this.request.posterPath = x);
|
this.request.posterPath = `https://image.tmdb.org/t/p/w300${this.request.posterPath}`;
|
||||||
this.imageService.getMovieBackground(this.request.mediaId).pipe(takeUntil(this.$imageSub)).subscribe(x => {
|
this.background = this.sanitizer.bypassSecurityTrustStyle("linear-gradient(rgba(0,0,0,.5), rgba(0,0,0,.5)), url(https://image.tmdb.org/t/p/w300" + this.request.background + ")");
|
||||||
this.background = this.sanitizer.bypassSecurityTrustStyle("linear-gradient(rgba(0,0,0,.5), rgba(0,0,0,.5)), url(" + x + ")");
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case RequestType.tvShow:
|
|
||||||
this.imageService.getTmdbTvPoster(Number(this.request.mediaId)).pipe(takeUntil(this.$imageSub)).subscribe(x => this.request.posterPath = `https://image.tmdb.org/t/p/w300${x}`);
|
|
||||||
this.imageService.getTmdbTvBackground(Number(this.request.mediaId)).pipe(takeUntil(this.$imageSub)).subscribe(x => {
|
|
||||||
this.background = this.sanitizer.bypassSecurityTrustStyle("linear-gradient(rgba(0,0,0,.5), rgba(0,0,0,.5)), url(https://image.tmdb.org/t/p/w300" + x + ")");
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,4 +72,21 @@ import { DomSanitizer, SafeStyle } from "@angular/platform-browser";
|
||||||
this.$imageSub.complete();
|
this.$imageSub.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private loadImages() {
|
||||||
|
switch (this.request.type) {
|
||||||
|
case RequestType.movie:
|
||||||
|
this.imageService.getMoviePoster(this.request.mediaId).pipe(takeUntil(this.$imageSub)).subscribe(x => this.request.posterPath = x);
|
||||||
|
this.imageService.getMovieBackground(this.request.mediaId).pipe(takeUntil(this.$imageSub)).subscribe(x => {
|
||||||
|
this.background = this.sanitizer.bypassSecurityTrustStyle("linear-gradient(rgba(0,0,0,.5), rgba(0,0,0,.5)), url(" + x + ")");
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case RequestType.tvShow:
|
||||||
|
this.imageService.getTmdbTvPoster(Number(this.request.mediaId)).pipe(takeUntil(this.$imageSub)).subscribe(x => this.request.posterPath = `https://image.tmdb.org/t/p/w300${x}`);
|
||||||
|
this.imageService.getTmdbTvBackground(Number(this.request.mediaId)).pipe(takeUntil(this.$imageSub)).subscribe(x => {
|
||||||
|
this.background = this.sanitizer.bypassSecurityTrustStyle("linear-gradient(rgba(0,0,0,.5), rgba(0,0,0,.5)), url(https://image.tmdb.org/t/p/w300" + x + ")");
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -15,4 +15,5 @@ export interface IRecentlyRequested {
|
||||||
type: RequestType;
|
type: RequestType;
|
||||||
|
|
||||||
posterPath: string;
|
posterPath: string;
|
||||||
|
background: string;
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue