diff --git a/src/Ombi.Core/Engine/Demo/DemoTvSearchEngine.cs b/src/Ombi.Core/Engine/Demo/DemoTvSearchEngine.cs index 54dacda6b..ee857129a 100644 --- a/src/Ombi.Core/Engine/Demo/DemoTvSearchEngine.cs +++ b/src/Ombi.Core/Engine/Demo/DemoTvSearchEngine.cs @@ -26,8 +26,8 @@ namespace Ombi.Core.Engine.Demo public DemoTvSearchEngine(IPrincipal identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper, ITraktApi trakt, IRuleEvaluator r, OmbiUserManager um, ICacheService memCache, - ISettingsService s, IRepository sub, IOptions lists) - : base(identity, service, tvMaze, mapper, trakt, r, um, memCache, s, sub) + ISettingsService s, IRepository sub, IOptions lists, IImageService imageService) + : base(identity, service, tvMaze, mapper, trakt, r, um, memCache, s, sub, imageService) { _demoLists = lists.Value; } @@ -55,7 +55,7 @@ namespace Ombi.Core.Engine.Demo { continue; } - retVal.Add(await ProcessResult(tvMazeSearch)); + retVal.Add(await ProcessResult(tvMazeSearch, false)); } return retVal; } @@ -77,7 +77,7 @@ namespace Ombi.Core.Engine.Demo } var movieResult = await TvMazeApi.ShowLookup(tv); - responses.Add(await ProcessResult(movieResult)); + responses.Add(await ProcessResult(movieResult, false)); } return responses; diff --git a/src/Ombi.Core/Engine/Interfaces/ITvSearchEngine.cs b/src/Ombi.Core/Engine/Interfaces/ITvSearchEngine.cs index 7ee6c4cf1..b2afb4c6f 100644 --- a/src/Ombi.Core/Engine/Interfaces/ITvSearchEngine.cs +++ b/src/Ombi.Core/Engine/Interfaces/ITvSearchEngine.cs @@ -9,7 +9,7 @@ namespace Ombi.Core.Engine.Interfaces Task> Search(string searchTerm); Task GetShowInformation(int tvdbid); Task> Popular(); - Task> Popular(int currentlyLoaded, int amountToLoad); + Task> Popular(int currentlyLoaded, int amountToLoad, bool includeImages = false); Task> Anticipated(); Task> Anticipated(int currentlyLoaded, int amountToLoad); Task> Trending(); diff --git a/src/Ombi.Core/Engine/TvSearchEngine.cs b/src/Ombi.Core/Engine/TvSearchEngine.cs index f854a5eee..a2b707ff9 100644 --- a/src/Ombi.Core/Engine/TvSearchEngine.cs +++ b/src/Ombi.Core/Engine/TvSearchEngine.cs @@ -27,11 +27,14 @@ namespace Ombi.Core.Engine { public class TvSearchEngine : BaseMediaEngine, ITvSearchEngine { + private readonly IImageService _imageService; + public TvSearchEngine(IPrincipal identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper, ITraktApi trakt, IRuleEvaluator r, OmbiUserManager um, - ICacheService memCache, ISettingsService s, IRepository sub) + ICacheService memCache, ISettingsService s, IRepository sub, IImageService imageService) : base(identity, service, r, um, memCache, s, sub) { + _imageService = imageService; TvMazeApi = tvMaze; Mapper = mapper; TraktApi = trakt; @@ -54,7 +57,7 @@ namespace Ombi.Core.Engine { continue; } - retVal.Add(await ProcessResult(tvMazeSearch)); + retVal.Add(await ProcessResult(tvMazeSearch, false)); } return retVal; } @@ -66,7 +69,7 @@ namespace Ombi.Core.Engine var show = await Cache.GetOrAdd(nameof(GetShowInformation) + tvdbid, async () => await TvMazeApi.ShowLookupByTheTvDbId(tvdbid), DateTime.Now.AddHours(12)); if (show == null) - { + { // We don't have enough information return null; } @@ -113,7 +116,7 @@ namespace Ombi.Core.Engine }); } } - return await ProcessResult(mapped); + return await ProcessResult(mapped, false); } public async Task> Popular() @@ -123,7 +126,7 @@ namespace Ombi.Core.Engine return await processed; } - public async Task> Popular(int currentlyLoaded, int amountToLoad) + public async Task> Popular(int currentlyLoaded, int amountToLoad, bool includeImages = false) { var pages = PaginationHelper.GetNextPages(currentlyLoaded, amountToLoad, ResultLimit); var results = new List(); @@ -133,7 +136,8 @@ namespace Ombi.Core.Engine async () => await TraktApi.GetPopularShows(pagesToLoad.Page, ResultLimit), DateTime.Now.AddHours(12)); results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take)); } - var processed = ProcessResults(results); + + var processed = ProcessResults(results, includeImages); return await processed; } @@ -150,7 +154,7 @@ namespace Ombi.Core.Engine var pages = PaginationHelper.GetNextPages(currentlyLoaded, amountToLoad, ResultLimit); var results = new List(); foreach (var pagesToLoad in pages) - { + { var apiResult = await Cache.GetOrAdd(nameof(Anticipated) + pagesToLoad.Page, async () => await TraktApi.GetAnticipatedShows(pagesToLoad.Page, ResultLimit), DateTime.Now.AddHours(12)); results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take)); @@ -181,26 +185,35 @@ namespace Ombi.Core.Engine return await processed; } - protected async Task> ProcessResults(IEnumerable items) + protected async Task> ProcessResults(IEnumerable items, bool includeImages = false) { var retVal = new List(); foreach (var tvMazeSearch in items) { - retVal.Add(await ProcessResult(tvMazeSearch)); + retVal.Add(await ProcessResult(tvMazeSearch, includeImages)); } return retVal; } - protected async Task ProcessResult(T tvMazeSearch) + protected async Task ProcessResult(T tvMazeSearch, bool includeImages) { var mapped = Mapper.Map(tvMazeSearch); - return await ProcessResult(mapped); + return await ProcessResult(mapped, includeImages); } - private async Task ProcessResult(SearchTvShowViewModel item) + private async Task ProcessResult(SearchTvShowViewModel item, bool includeImages) { item.TheTvDbId = item.Id.ToString(); - + if (includeImages) + { + + if (item.TheTvDbId.HasValue()) + { + item.BackdropPath = await _imageService.GetTvBackground(item.TheTvDbId); + } + + } + await RunSearchRules(item); return item; diff --git a/src/Ombi.Core/IImageService.cs b/src/Ombi.Core/IImageService.cs new file mode 100644 index 000000000..1493133e6 --- /dev/null +++ b/src/Ombi.Core/IImageService.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Ombi.Core +{ + public interface IImageService + { + Task GetTvBackground(string tvdbId); + } +} \ No newline at end of file diff --git a/src/Ombi.Core/ImageService.cs b/src/Ombi.Core/ImageService.cs new file mode 100644 index 000000000..e22605441 --- /dev/null +++ b/src/Ombi.Core/ImageService.cs @@ -0,0 +1,47 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using Ombi.Api.FanartTv; +using Ombi.Helpers; +using Ombi.Store.Repository; + +namespace Ombi.Core +{ + public class ImageService : IImageService + { + private readonly IApplicationConfigRepository _configRepository; + private readonly IFanartTvApi _fanartTvApi; + private readonly ICacheService _cache; + + public ImageService(IApplicationConfigRepository configRepository, IFanartTvApi fanartTvApi, + ICacheService cache) + { + _configRepository = configRepository; + _fanartTvApi = fanartTvApi; + _cache = cache; + } + + public async Task GetTvBackground(string tvdbId) + { + var key = await _cache.GetOrAdd(CacheKeys.FanartTv, async () => await _configRepository.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTime.Now.AddDays(1)); + var images = await _cache.GetOrAdd($"{CacheKeys.FanartTv}tv{tvdbId}", async () => await _fanartTvApi.GetTvImages(int.Parse(tvdbId), key.Value), DateTime.Now.AddDays(1)); + + if (images == null) + { + return string.Empty; + } + + if (images.showbackground?.Any() ?? false) + { + var enImage = images.showbackground.Where(x => x.lang == "en").OrderByDescending(x => x.likes).Select(x => x.url).FirstOrDefault(); + if (enImage == null) + { + return images.showbackground.OrderByDescending(x => x.likes).Select(x => x.url).FirstOrDefault(); + } + return enImage; + } + + return string.Empty; + } + } +} \ No newline at end of file diff --git a/src/Ombi.Core/Models/Search/SearchTvShowViewModel.cs b/src/Ombi.Core/Models/Search/SearchTvShowViewModel.cs index c421af45f..dfd038a91 100644 --- a/src/Ombi.Core/Models/Search/SearchTvShowViewModel.cs +++ b/src/Ombi.Core/Models/Search/SearchTvShowViewModel.cs @@ -57,5 +57,10 @@ namespace Ombi.Core.Models.Search // We only have some episodes public bool PartlyAvailable { get; set; } public override RequestType Type => RequestType.TvShow; + + /// + /// Only set on the images call + /// + public string BackdropPath { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Core/Ombi.Core.csproj b/src/Ombi.Core/Ombi.Core.csproj index 54d34589e..2d93f7969 100644 --- a/src/Ombi.Core/Ombi.Core.csproj +++ b/src/Ombi.Core/Ombi.Core.csproj @@ -22,6 +22,7 @@ + diff --git a/src/Ombi.DependencyInjection/IocExtensions.cs b/src/Ombi.DependencyInjection/IocExtensions.cs index 49d10c192..dd7dcd3b8 100644 --- a/src/Ombi.DependencyInjection/IocExtensions.cs +++ b/src/Ombi.DependencyInjection/IocExtensions.cs @@ -180,6 +180,7 @@ namespace Ombi.DependencyInjection services.AddTransient(); services.AddTransient(); services.AddSingleton(); + services.AddScoped(); services.AddTransient(); services.AddTransient(); diff --git a/src/Ombi.TheMovieDbApi/Models/FullMovieInfo.cs b/src/Ombi.TheMovieDbApi/Models/FullMovieInfo.cs index 0e352580f..3149ed5a1 100644 --- a/src/Ombi.TheMovieDbApi/Models/FullMovieInfo.cs +++ b/src/Ombi.TheMovieDbApi/Models/FullMovieInfo.cs @@ -70,6 +70,23 @@ namespace Ombi.Api.TheMovieDb.Models public ExternalIds ExternalIds { get; set; } [JsonProperty("keywords")] public Keywords Keywords { get; set; } + + //[JsonProperty("images")] + //public List Images { get; set; } // add images to append_to_response + } + + public class Images + { + [JsonProperty("backdrops")] + public List Backdrops { get; set; } + [JsonProperty("posters")] + public List Posters { get; set; } + } + + public class ImageContent + { + [JsonProperty("file_path")] + public string FilePath { get; set; } } public class Keywords diff --git a/src/Ombi/ClientApp/src/app/discover/components/discover/discover.component.ts b/src/Ombi/ClientApp/src/app/discover/components/discover/discover.component.ts index 9dc3c066d..4c6d1c5a2 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/discover/discover.component.ts +++ b/src/Ombi/ClientApp/src/app/discover/components/discover/discover.component.ts @@ -19,8 +19,8 @@ import { trigger, transition, style, animate } from "@angular/animations"; export class DiscoverComponent implements OnInit { public discoverResults: IDiscoverCardResult[] = []; - public movies: ISearchMovieResult[]; - public tvShows: ISearchTvResult[]; + public movies: ISearchMovieResult[] = []; + public tvShows: ISearchTvResult[] = []; public defaultTvPoster: string; diff --git a/src/Ombi/Controllers/V1/ImagesController.cs b/src/Ombi/Controllers/V1/ImagesController.cs index 9e1295f21..249a6e9bd 100644 --- a/src/Ombi/Controllers/V1/ImagesController.cs +++ b/src/Ombi/Controllers/V1/ImagesController.cs @@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Ombi.Api.FanartTv; using Ombi.Config; +using Ombi.Core; using Ombi.Helpers; using Ombi.Store.Repository; @@ -16,18 +17,20 @@ namespace Ombi.Controllers.V1 public class ImagesController : ControllerBase { public ImagesController(IFanartTvApi fanartTvApi, IApplicationConfigRepository config, - IOptions options, ICacheService c) + IOptions options, ICacheService c, IImageService imageService) { FanartTvApi = fanartTvApi; Config = config; Options = options.Value; _cache = c; + _imageService = imageService; } private IFanartTvApi FanartTvApi { get; } private IApplicationConfigRepository Config { get; } private LandingPageBackground Options { get; } private readonly ICacheService _cache; + private readonly IImageService _imageService; [HttpGet("tv/{tvdbid}")] public async Task GetTvBanner(int tvdbid) @@ -179,26 +182,8 @@ namespace Ombi.Controllers.V1 { return string.Empty; } - var key = await _cache.GetOrAdd(CacheKeys.FanartTv, async () => await Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTime.Now.AddDays(1)); - - var images = await _cache.GetOrAdd($"{CacheKeys.FanartTv}tv{tvdbid}", async () => await FanartTvApi.GetTvImages(tvdbid, key.Value), DateTime.Now.AddDays(1)); - - if (images == null) - { - return string.Empty; - } - if (images.showbackground?.Any() ?? false) - { - var enImage = images.showbackground.Where(x => x.lang == "en").OrderByDescending(x => x.likes).Select(x => x.url).FirstOrDefault(); - if (enImage == null) - { - return images.showbackground.OrderByDescending(x => x.likes).Select(x => x.url).FirstOrDefault(); - } - return enImage; - } - - return string.Empty; + return await _imageService.GetTvBackground(tvdbid.ToString()); } [HttpGet("background")] diff --git a/src/Ombi/Controllers/V2/SearchController.cs b/src/Ombi/Controllers/V2/SearchController.cs index 1e2f9776c..929dbdf57 100644 --- a/src/Ombi/Controllers/V2/SearchController.cs +++ b/src/Ombi/Controllers/V2/SearchController.cs @@ -240,6 +240,19 @@ namespace Ombi.Controllers.V2 return await _tvSearchEngine.Popular(currentPosition, amountToLoad); } + /// + /// Returns Popular Tv Shows + /// + /// We use Trakt.tv as the Provider + /// + [HttpGet("tv/popular/{currentPosition}/{amountToLoad}/images")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesDefaultResponseType] + public async Task> PopularTvWithImages(int currentPosition, int amountToLoad) + { + return await _tvSearchEngine.Popular(currentPosition, amountToLoad, true); + } + /// /// Returns most Anticipated tv shows. ///