Merge pull request #4121 from Ombi-app/bug/v1api-fix

Fixed the v1 API, added tests around that API to ensure we keep backw…
This commit is contained in:
Jamie 2021-03-28 22:33:19 +01:00 committed by GitHub
commit 606fd8c919
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 1432 additions and 137 deletions

View file

@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Ombi.Core.Models.Search;
using Ombi.Core.Models.Search.V2;
namespace Ombi.Core
@ -10,5 +11,8 @@ namespace Ombi.Core
Task<SearchFullInfoTvShowViewModel> GetShowInformation(string tvdbid, CancellationToken token);
Task<SearchFullInfoTvShowViewModel> GetShowByRequest(int requestId, CancellationToken token);
Task<IEnumerable<StreamingData>> GetStreamInformation(int movieDbId, CancellationToken cancellationToken);
Task<IEnumerable<SearchTvShowViewModel>> Popular(int currentlyLoaded, int amountToLoad);
Task<IEnumerable<SearchTvShowViewModel>> Anticipated(int currentlyLoaded, int amountToLoad);
Task<IEnumerable<SearchTvShowViewModel>> Trending(int currentlyLoaded, int amountToLoad);
}
}

View file

@ -22,6 +22,7 @@ using Ombi.Store.Entities;
using Ombi.Api.TheMovieDb;
using Ombi.Api.TheMovieDb.Models;
using System.Threading;
using TraktSharp.Entities;
namespace Ombi.Core.Engine
{
@ -51,18 +52,18 @@ namespace Ombi.Core.Engine
public async Task<IEnumerable<SearchTvShowViewModel>> Search(string searchTerm)
{
var searchResult = await _theMovieDbApi.SearchTv(searchTerm);
var searchResult = await TvMazeApi.Search(searchTerm);
if (searchResult != null)
{
var retVal = new List<SearchTvShowViewModel>();
foreach (var result in searchResult)
foreach (var tvMazeSearch in searchResult)
{
//if (tvMazeSearch.show.externals == null || !(tvMazeSearch.show.externals?.thetvdb.HasValue ?? false))
//{
// continue;
//}
var mappedResult = await ProcessResult(result, false);
if (tvMazeSearch.show.externals == null || !(tvMazeSearch.show.externals?.thetvdb.HasValue ?? false))
{
continue;
}
var mappedResult = await ProcessResult(tvMazeSearch, false);
if (mappedResult == null)
{
continue;
@ -74,61 +75,56 @@ namespace Ombi.Core.Engine
return null;
}
public async Task<SearchTvShowViewModel> GetShowInformation(string theMovieDbId, CancellationToken token)
public async Task<SearchTvShowViewModel> GetShowInformation(string tvdbid, CancellationToken token)
{
var show = await Cache.GetOrAdd(nameof(GetShowInformation) + theMovieDbId,
async () => await _theMovieDbApi.GetTVInfo(theMovieDbId), DateTime.Now.AddHours(12));
var show = await Cache.GetOrAdd(nameof(GetShowInformation) + tvdbid,
async () => await TvMazeApi.ShowLookupByTheTvDbId(int.Parse(tvdbid)), DateTime.Now.AddHours(12));
if (show == null)
{
// We don't have enough information
return null;
}
//var episodes = await Cache.GetOrAdd("TvMazeEpisodeLookup" + show.id,
// async () => await TvMazeApi.EpisodeLookup(show.id), DateTime.Now.AddHours(12));
//if (episodes == null || !episodes.Any())
//{
// // We don't have enough information
// return null;
//}
var episodes = await Cache.GetOrAdd("TvMazeEpisodeLookup" + show.id,
async () => await TvMazeApi.EpisodeLookup(show.id), DateTime.Now.AddHours(12));
if (episodes == null || !episodes.Any())
{
// We don't have enough information
return null;
}
var mapped = Mapper.Map<SearchTvShowViewModel>(show);
foreach(var tvSeason in show.seasons)
foreach (var e in episodes)
{
var seasonEpisodes = (await _theMovieDbApi.GetSeasonEpisodes(show.id, tvSeason.season_number, token));
foreach (var episode in seasonEpisodes.episodes)
var season = mapped.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == e.season);
if (season == null)
{
var season = mapped.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == episode.season_number);
if (season == null)
var newSeason = new SeasonRequests
{
var newSeason = new SeasonRequests
{
SeasonNumber = episode.season_number,
Episodes = new List<EpisodeRequests>()
};
newSeason.Episodes.Add(new EpisodeRequests
{
//Url = episode...ToHttpsUrl(),
Title = episode.name,
AirDate = episode.air_date.HasValue() ? DateTime.Parse(episode.air_date) : DateTime.MinValue,
EpisodeNumber = episode.episode_number,
SeasonNumber = e.season,
Episodes = new List<EpisodeRequests>()
};
newSeason.Episodes.Add(new EpisodeRequests
{
Url = e.url.ToHttpsUrl(),
Title = e.name,
AirDate = e.airstamp.HasValue() ? DateTime.Parse(e.airstamp) : DateTime.MinValue,
EpisodeNumber = e.number,
});
mapped.SeasonRequests.Add(newSeason);
}
else
});
mapped.SeasonRequests.Add(newSeason);
}
else
{
// We already have the season, so just add the episode
season.Episodes.Add(new EpisodeRequests
{
// We already have the season, so just add the episode
season.Episodes.Add(new EpisodeRequests
{
//Url = e.url.ToHttpsUrl(),
Title = episode.name,
AirDate = episode.air_date.HasValue() ? DateTime.Parse(episode.air_date) : DateTime.MinValue,
EpisodeNumber = episode.episode_number,
});
}
Url = e.url.ToHttpsUrl(),
Title = e.name,
AirDate = e.airstamp.HasValue() ? DateTime.Parse(e.airstamp) : DateTime.MinValue,
EpisodeNumber = e.number,
});
}
}
@ -147,11 +143,11 @@ namespace Ombi.Core.Engine
var langCode = await DefaultLanguageCode(null);
var pages = PaginationHelper.GetNextPages(currentlyLoaded, amountToLoad, ResultLimit);
var results = new List<MovieDbSearchResult>();
var results = new List<TraktShow>();
foreach (var pagesToLoad in pages)
{
var apiResult = await Cache.GetOrAdd(nameof(Popular) + langCode + pagesToLoad.Page,
async () => await _theMovieDbApi.PopularTv(langCode, pagesToLoad.Page), DateTime.Now.AddHours(12));
async () => await TraktApi.GetPopularShows(pagesToLoad.Page, ResultLimit), DateTime.Now.AddHours(12));
results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take));
}
@ -172,11 +168,11 @@ namespace Ombi.Core.Engine
var langCode = await DefaultLanguageCode(null);
var pages = PaginationHelper.GetNextPages(currentlyLoaded, amountToLoad, ResultLimit);
var results = new List<MovieDbSearchResult>();
var results = new List<TraktShow>();
foreach (var pagesToLoad in pages)
{
var apiResult = await Cache.GetOrAdd(nameof(Anticipated) + langCode + pagesToLoad.Page,
async () => await _theMovieDbApi.UpcomingTv(langCode, pagesToLoad.Page), DateTime.Now.AddHours(12));
async () => await TraktApi.GetAnticipatedShows(pagesToLoad.Page, ResultLimit), DateTime.Now.AddHours(12));
results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take));
}
var processed = ProcessResults(results);
@ -196,11 +192,11 @@ namespace Ombi.Core.Engine
var langCode = await DefaultLanguageCode(null);
var pages = PaginationHelper.GetNextPages(currentlyLoaded, amountToLoad, ResultLimit);
var results = new List<MovieDbSearchResult>();
var results = new List<TraktShow>();
foreach (var pagesToLoad in pages)
{
var apiResult = await Cache.GetOrAdd(nameof(Trending) + langCode + pagesToLoad.Page,
async () => await _theMovieDbApi.TopRatedTv(langCode, pagesToLoad.Page), DateTime.Now.AddHours(12));
async () => await TraktApi.GetTrendingShows(pagesToLoad.Page, ResultLimit), DateTime.Now.AddHours(12));
results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take));
}
var processed = ProcessResults(results);

View file

@ -21,6 +21,7 @@ using TraktSharp.Entities;
using Microsoft.EntityFrameworkCore;
using System.Threading;
using Ombi.Api.TheMovieDb;
using Ombi.Api.TheMovieDb.Models;
namespace Ombi.Core.Engine.V2
{
@ -30,16 +31,18 @@ namespace Ombi.Core.Engine.V2
private readonly IMapper _mapper;
private readonly ITraktApi _traktApi;
private readonly IMovieDbApi _movieApi;
private readonly ISettingsService<CustomizationSettings> _customization;
public TvSearchEngineV2(IPrincipal identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper,
ITraktApi trakt, IRuleEvaluator r, OmbiUserManager um, ICacheService memCache, ISettingsService<OmbiSettings> s,
IRepository<RequestSubscription> sub, IMovieDbApi movieApi)
IRepository<RequestSubscription> sub, IMovieDbApi movieApi, ISettingsService<CustomizationSettings> customization)
: base(identity, service, r, um, memCache, s, sub)
{
_tvMaze = tvMaze;
_mapper = mapper;
_traktApi = trakt;
_movieApi = movieApi;
_customization = customization;
}
@ -104,6 +107,56 @@ namespace Ombi.Core.Engine.V2
return await ProcessResult(mapped);
}
public async Task<IEnumerable<SearchTvShowViewModel>> Popular(int currentlyLoaded, int amountToLoad)
{
var langCode = await DefaultLanguageCode(null);
var pages = PaginationHelper.GetNextPages(currentlyLoaded, amountToLoad, ResultLimit);
var results = new List<MovieDbSearchResult>();
foreach (var pagesToLoad in pages)
{
var apiResult = await Cache.GetOrAdd(nameof(Popular) + langCode + pagesToLoad.Page,
async () => await _movieApi.PopularTv(langCode, pagesToLoad.Page), DateTime.Now.AddHours(12));
results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take));
}
var processed = ProcessResults(results);
return await processed;
}
public async Task<IEnumerable<SearchTvShowViewModel>> Anticipated(int currentlyLoaded, int amountToLoad)
{
var langCode = await DefaultLanguageCode(null);
var pages = PaginationHelper.GetNextPages(currentlyLoaded, amountToLoad, ResultLimit);
var results = new List<MovieDbSearchResult>();
foreach (var pagesToLoad in pages)
{
var apiResult = await Cache.GetOrAdd(nameof(Anticipated) + langCode + pagesToLoad.Page,
async () => await _movieApi.UpcomingTv(langCode, pagesToLoad.Page), DateTime.Now.AddHours(12));
results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take));
}
var processed = ProcessResults(results);
return await processed;
}
public async Task<IEnumerable<SearchTvShowViewModel>> Trending(int currentlyLoaded, int amountToLoad)
{
var langCode = await DefaultLanguageCode(null);
var pages = PaginationHelper.GetNextPages(currentlyLoaded, amountToLoad, ResultLimit);
var results = new List<MovieDbSearchResult>();
foreach (var pagesToLoad in pages)
{
var apiResult = await Cache.GetOrAdd(nameof(Trending) + langCode + pagesToLoad.Page,
async () => await _movieApi.TopRatedTv(langCode, pagesToLoad.Page), DateTime.Now.AddHours(12));
results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take));
}
var processed = ProcessResults(results);
return await processed;
}
public async Task<IEnumerable<StreamingData>> GetStreamInformation(int movieDbId, CancellationToken cancellationToken)
{
var providers = await _movieApi.GetTvWatchProviders(movieDbId, cancellationToken);
@ -124,19 +177,28 @@ namespace Ombi.Core.Engine.V2
return data;
}
private IEnumerable<SearchTvShowViewModel> ProcessResults<T>(IEnumerable<T> items)
private async Task<IEnumerable<SearchTvShowViewModel>> ProcessResults<T>(IEnumerable<T> items)
{
var retVal = new List<SearchTvShowViewModel>();
var retVal = new List<SearchTvShowViewModel>();
var settings = await _customization.GetSettingsAsync();
foreach (var tvMazeSearch in items)
{
retVal.Add(ProcessResult(tvMazeSearch));
var result = await ProcessResult(tvMazeSearch);
if (result == null || settings.HideAvailableFromDiscover && result.Available)
{
continue;
}
retVal.Add(result);
}
return retVal;
}
private SearchTvShowViewModel ProcessResult<T>(T tvMazeSearch)
private async Task<SearchTvShowViewModel> ProcessResult<T>(T tvMazeSearch)
{
return _mapper.Map<SearchTvShowViewModel>(tvMazeSearch);
var item = _mapper.Map<SearchTvShowViewModel>(tvMazeSearch);
await RunSearchRules(item);
return item;
}
private async Task<SearchFullInfoTvShowViewModel> ProcessResult(SearchFullInfoTvShowViewModel item)

View file

@ -18,7 +18,7 @@ namespace Ombi.Core.Rule.Rules.Search
// If we have all the episodes for this season, then this season is available
if (season.Episodes.All(x => x.Available))
{
season.SeasonAvailable = true;
season.SeasonAvailable = true;
}
}
if (search.SeasonRequests.All(x => x.Episodes.All(e => e.Available)))