mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-12 00:06:05 -07:00
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:
commit
606fd8c919
13 changed files with 1432 additions and 137 deletions
|
@ -1,6 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Ombi.Core.Models.Search;
|
||||||
using Ombi.Core.Models.Search.V2;
|
using Ombi.Core.Models.Search.V2;
|
||||||
|
|
||||||
namespace Ombi.Core
|
namespace Ombi.Core
|
||||||
|
@ -10,5 +11,8 @@ namespace Ombi.Core
|
||||||
Task<SearchFullInfoTvShowViewModel> GetShowInformation(string tvdbid, CancellationToken token);
|
Task<SearchFullInfoTvShowViewModel> GetShowInformation(string tvdbid, CancellationToken token);
|
||||||
Task<SearchFullInfoTvShowViewModel> GetShowByRequest(int requestId, CancellationToken token);
|
Task<SearchFullInfoTvShowViewModel> GetShowByRequest(int requestId, CancellationToken token);
|
||||||
Task<IEnumerable<StreamingData>> GetStreamInformation(int movieDbId, CancellationToken cancellationToken);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -22,6 +22,7 @@ using Ombi.Store.Entities;
|
||||||
using Ombi.Api.TheMovieDb;
|
using Ombi.Api.TheMovieDb;
|
||||||
using Ombi.Api.TheMovieDb.Models;
|
using Ombi.Api.TheMovieDb.Models;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using TraktSharp.Entities;
|
||||||
|
|
||||||
namespace Ombi.Core.Engine
|
namespace Ombi.Core.Engine
|
||||||
{
|
{
|
||||||
|
@ -51,18 +52,18 @@ namespace Ombi.Core.Engine
|
||||||
|
|
||||||
public async Task<IEnumerable<SearchTvShowViewModel>> Search(string searchTerm)
|
public async Task<IEnumerable<SearchTvShowViewModel>> Search(string searchTerm)
|
||||||
{
|
{
|
||||||
var searchResult = await _theMovieDbApi.SearchTv(searchTerm);
|
var searchResult = await TvMazeApi.Search(searchTerm);
|
||||||
|
|
||||||
if (searchResult != null)
|
if (searchResult != null)
|
||||||
{
|
{
|
||||||
var retVal = new List<SearchTvShowViewModel>();
|
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))
|
if (tvMazeSearch.show.externals == null || !(tvMazeSearch.show.externals?.thetvdb.HasValue ?? false))
|
||||||
//{
|
{
|
||||||
// continue;
|
continue;
|
||||||
//}
|
}
|
||||||
var mappedResult = await ProcessResult(result, false);
|
var mappedResult = await ProcessResult(tvMazeSearch, false);
|
||||||
if (mappedResult == null)
|
if (mappedResult == null)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -74,61 +75,56 @@ namespace Ombi.Core.Engine
|
||||||
return null;
|
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,
|
var show = await Cache.GetOrAdd(nameof(GetShowInformation) + tvdbid,
|
||||||
async () => await _theMovieDbApi.GetTVInfo(theMovieDbId), DateTime.Now.AddHours(12));
|
async () => await TvMazeApi.ShowLookupByTheTvDbId(int.Parse(tvdbid)), DateTime.Now.AddHours(12));
|
||||||
if (show == null)
|
if (show == null)
|
||||||
{
|
{
|
||||||
// We don't have enough information
|
// We don't have enough information
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//var episodes = await Cache.GetOrAdd("TvMazeEpisodeLookup" + show.id,
|
var episodes = await Cache.GetOrAdd("TvMazeEpisodeLookup" + show.id,
|
||||||
// async () => await TvMazeApi.EpisodeLookup(show.id), DateTime.Now.AddHours(12));
|
async () => await TvMazeApi.EpisodeLookup(show.id), DateTime.Now.AddHours(12));
|
||||||
//if (episodes == null || !episodes.Any())
|
if (episodes == null || !episodes.Any())
|
||||||
//{
|
{
|
||||||
// // We don't have enough information
|
// We don't have enough information
|
||||||
// return null;
|
return null;
|
||||||
//}
|
}
|
||||||
|
|
||||||
var mapped = Mapper.Map<SearchTvShowViewModel>(show);
|
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));
|
var season = mapped.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == e.season);
|
||||||
|
if (season == null)
|
||||||
foreach (var episode in seasonEpisodes.episodes)
|
|
||||||
{
|
{
|
||||||
var season = mapped.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == episode.season_number);
|
var newSeason = new SeasonRequests
|
||||||
if (season == null)
|
|
||||||
{
|
{
|
||||||
var newSeason = new SeasonRequests
|
SeasonNumber = e.season,
|
||||||
{
|
Episodes = new List<EpisodeRequests>()
|
||||||
SeasonNumber = episode.season_number,
|
};
|
||||||
Episodes = new List<EpisodeRequests>()
|
newSeason.Episodes.Add(new EpisodeRequests
|
||||||
};
|
{
|
||||||
newSeason.Episodes.Add(new EpisodeRequests
|
Url = e.url.ToHttpsUrl(),
|
||||||
{
|
Title = e.name,
|
||||||
//Url = episode...ToHttpsUrl(),
|
AirDate = e.airstamp.HasValue() ? DateTime.Parse(e.airstamp) : DateTime.MinValue,
|
||||||
Title = episode.name,
|
EpisodeNumber = e.number,
|
||||||
AirDate = episode.air_date.HasValue() ? DateTime.Parse(episode.air_date) : DateTime.MinValue,
|
|
||||||
EpisodeNumber = episode.episode_number,
|
|
||||||
|
|
||||||
});
|
});
|
||||||
mapped.SeasonRequests.Add(newSeason);
|
mapped.SeasonRequests.Add(newSeason);
|
||||||
}
|
}
|
||||||
else
|
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
|
Url = e.url.ToHttpsUrl(),
|
||||||
season.Episodes.Add(new EpisodeRequests
|
Title = e.name,
|
||||||
{
|
AirDate = e.airstamp.HasValue() ? DateTime.Parse(e.airstamp) : DateTime.MinValue,
|
||||||
//Url = e.url.ToHttpsUrl(),
|
EpisodeNumber = e.number,
|
||||||
Title = episode.name,
|
});
|
||||||
AirDate = episode.air_date.HasValue() ? DateTime.Parse(episode.air_date) : DateTime.MinValue,
|
|
||||||
EpisodeNumber = episode.episode_number,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,11 +143,11 @@ namespace Ombi.Core.Engine
|
||||||
var langCode = await DefaultLanguageCode(null);
|
var langCode = await DefaultLanguageCode(null);
|
||||||
|
|
||||||
var pages = PaginationHelper.GetNextPages(currentlyLoaded, amountToLoad, ResultLimit);
|
var pages = PaginationHelper.GetNextPages(currentlyLoaded, amountToLoad, ResultLimit);
|
||||||
var results = new List<MovieDbSearchResult>();
|
var results = new List<TraktShow>();
|
||||||
foreach (var pagesToLoad in pages)
|
foreach (var pagesToLoad in pages)
|
||||||
{
|
{
|
||||||
var apiResult = await Cache.GetOrAdd(nameof(Popular) + langCode + pagesToLoad.Page,
|
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));
|
results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,11 +168,11 @@ namespace Ombi.Core.Engine
|
||||||
var langCode = await DefaultLanguageCode(null);
|
var langCode = await DefaultLanguageCode(null);
|
||||||
|
|
||||||
var pages = PaginationHelper.GetNextPages(currentlyLoaded, amountToLoad, ResultLimit);
|
var pages = PaginationHelper.GetNextPages(currentlyLoaded, amountToLoad, ResultLimit);
|
||||||
var results = new List<MovieDbSearchResult>();
|
var results = new List<TraktShow>();
|
||||||
foreach (var pagesToLoad in pages)
|
foreach (var pagesToLoad in pages)
|
||||||
{
|
{
|
||||||
var apiResult = await Cache.GetOrAdd(nameof(Anticipated) + langCode + pagesToLoad.Page,
|
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));
|
results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take));
|
||||||
}
|
}
|
||||||
var processed = ProcessResults(results);
|
var processed = ProcessResults(results);
|
||||||
|
@ -196,11 +192,11 @@ namespace Ombi.Core.Engine
|
||||||
var langCode = await DefaultLanguageCode(null);
|
var langCode = await DefaultLanguageCode(null);
|
||||||
|
|
||||||
var pages = PaginationHelper.GetNextPages(currentlyLoaded, amountToLoad, ResultLimit);
|
var pages = PaginationHelper.GetNextPages(currentlyLoaded, amountToLoad, ResultLimit);
|
||||||
var results = new List<MovieDbSearchResult>();
|
var results = new List<TraktShow>();
|
||||||
foreach (var pagesToLoad in pages)
|
foreach (var pagesToLoad in pages)
|
||||||
{
|
{
|
||||||
var apiResult = await Cache.GetOrAdd(nameof(Trending) + langCode + pagesToLoad.Page,
|
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));
|
results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take));
|
||||||
}
|
}
|
||||||
var processed = ProcessResults(results);
|
var processed = ProcessResults(results);
|
||||||
|
|
|
@ -21,6 +21,7 @@ using TraktSharp.Entities;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Ombi.Api.TheMovieDb;
|
using Ombi.Api.TheMovieDb;
|
||||||
|
using Ombi.Api.TheMovieDb.Models;
|
||||||
|
|
||||||
namespace Ombi.Core.Engine.V2
|
namespace Ombi.Core.Engine.V2
|
||||||
{
|
{
|
||||||
|
@ -30,16 +31,18 @@ namespace Ombi.Core.Engine.V2
|
||||||
private readonly IMapper _mapper;
|
private readonly IMapper _mapper;
|
||||||
private readonly ITraktApi _traktApi;
|
private readonly ITraktApi _traktApi;
|
||||||
private readonly IMovieDbApi _movieApi;
|
private readonly IMovieDbApi _movieApi;
|
||||||
|
private readonly ISettingsService<CustomizationSettings> _customization;
|
||||||
|
|
||||||
public TvSearchEngineV2(IPrincipal identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper,
|
public TvSearchEngineV2(IPrincipal identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper,
|
||||||
ITraktApi trakt, IRuleEvaluator r, OmbiUserManager um, ICacheService memCache, ISettingsService<OmbiSettings> s,
|
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)
|
: base(identity, service, r, um, memCache, s, sub)
|
||||||
{
|
{
|
||||||
_tvMaze = tvMaze;
|
_tvMaze = tvMaze;
|
||||||
_mapper = mapper;
|
_mapper = mapper;
|
||||||
_traktApi = trakt;
|
_traktApi = trakt;
|
||||||
_movieApi = movieApi;
|
_movieApi = movieApi;
|
||||||
|
_customization = customization;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -104,6 +107,56 @@ namespace Ombi.Core.Engine.V2
|
||||||
return await ProcessResult(mapped);
|
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)
|
public async Task<IEnumerable<StreamingData>> GetStreamInformation(int movieDbId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var providers = await _movieApi.GetTvWatchProviders(movieDbId, cancellationToken);
|
var providers = await _movieApi.GetTvWatchProviders(movieDbId, cancellationToken);
|
||||||
|
@ -124,19 +177,28 @@ namespace Ombi.Core.Engine.V2
|
||||||
return data;
|
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)
|
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;
|
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)
|
private async Task<SearchFullInfoTvShowViewModel> ProcessResult(SearchFullInfoTvShowViewModel item)
|
||||||
|
|
|
@ -198,6 +198,7 @@ export class DiscoverCardComponent implements OnInit {
|
||||||
this.result.url = updated.imdbId;
|
this.result.url = updated.imdbId;
|
||||||
this.result.overview = updated.overview;
|
this.result.overview = updated.overview;
|
||||||
this.result.approved = updated.approved;
|
this.result.approved = updated.approved;
|
||||||
|
this.result.available = updated.fullyAvailable;
|
||||||
|
|
||||||
this.fullyLoaded = true;
|
this.fullyLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,10 @@ namespace Ombi.Controllers.V2
|
||||||
{
|
{
|
||||||
public class SearchController : V2Controller
|
public class SearchController : V2Controller
|
||||||
{
|
{
|
||||||
public SearchController(IMultiSearchEngine multiSearchEngine, ITvSearchEngine tvSearchEngine,
|
public SearchController(IMultiSearchEngine multiSearchEngine,
|
||||||
IMovieEngineV2 v2Movie, ITVSearchEngineV2 v2Tv, IMusicSearchEngineV2 musicEngine, IRottenTomatoesApi rottenTomatoesApi)
|
IMovieEngineV2 v2Movie, ITVSearchEngineV2 v2Tv, IMusicSearchEngineV2 musicEngine, IRottenTomatoesApi rottenTomatoesApi)
|
||||||
{
|
{
|
||||||
_multiSearchEngine = multiSearchEngine;
|
_multiSearchEngine = multiSearchEngine;
|
||||||
_tvSearchEngine = tvSearchEngine;
|
|
||||||
_tvSearchEngine.ResultLimit = 20;
|
|
||||||
_movieEngineV2 = v2Movie;
|
_movieEngineV2 = v2Movie;
|
||||||
_movieEngineV2.ResultLimit = 20;
|
_movieEngineV2.ResultLimit = 20;
|
||||||
_tvEngineV2 = v2Tv;
|
_tvEngineV2 = v2Tv;
|
||||||
|
@ -38,7 +36,6 @@ namespace Ombi.Controllers.V2
|
||||||
private readonly IMultiSearchEngine _multiSearchEngine;
|
private readonly IMultiSearchEngine _multiSearchEngine;
|
||||||
private readonly IMovieEngineV2 _movieEngineV2;
|
private readonly IMovieEngineV2 _movieEngineV2;
|
||||||
private readonly ITVSearchEngineV2 _tvEngineV2;
|
private readonly ITVSearchEngineV2 _tvEngineV2;
|
||||||
private readonly ITvSearchEngine _tvSearchEngine;
|
|
||||||
private readonly IMusicSearchEngineV2 _musicEngine;
|
private readonly IMusicSearchEngineV2 _musicEngine;
|
||||||
private readonly IRottenTomatoesApi _rottenTomatoesApi;
|
private readonly IRottenTomatoesApi _rottenTomatoesApi;
|
||||||
|
|
||||||
|
@ -258,19 +255,6 @@ namespace Ombi.Controllers.V2
|
||||||
return await _movieEngineV2.UpcomingMovies(currentPosition, amountToLoad);
|
return await _movieEngineV2.UpcomingMovies(currentPosition, amountToLoad);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns Popular Tv Shows
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>We use Trakt.tv as the Provider</remarks>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("tv/popular")]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
[ProducesDefaultResponseType]
|
|
||||||
public async Task<IEnumerable<SearchTvShowViewModel>> PopularTv()
|
|
||||||
{
|
|
||||||
return await _tvSearchEngine.Popular();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns Popular Tv Shows
|
/// Returns Popular Tv Shows
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -281,33 +265,7 @@ namespace Ombi.Controllers.V2
|
||||||
[ProducesDefaultResponseType]
|
[ProducesDefaultResponseType]
|
||||||
public async Task<IEnumerable<SearchTvShowViewModel>> PopularTv(int currentPosition, int amountToLoad)
|
public async Task<IEnumerable<SearchTvShowViewModel>> PopularTv(int currentPosition, int amountToLoad)
|
||||||
{
|
{
|
||||||
return await _tvSearchEngine.Popular(currentPosition, amountToLoad);
|
return await _tvEngineV2.Popular(currentPosition, amountToLoad);
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns Popular Tv Shows
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>We use Trakt.tv as the Provider</remarks>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("tv/popular/{currentPosition}/{amountToLoad}/images")]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
[ProducesDefaultResponseType]
|
|
||||||
public async Task<IEnumerable<SearchTvShowViewModel>> PopularTvWithImages(int currentPosition, int amountToLoad)
|
|
||||||
{
|
|
||||||
return await _tvSearchEngine.Popular(currentPosition, amountToLoad, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns most Anticipated tv shows.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>We use Trakt.tv as the Provider</remarks>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("tv/anticipated")]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
[ProducesDefaultResponseType]
|
|
||||||
public async Task<IEnumerable<SearchTvShowViewModel>> AnticipatedTv()
|
|
||||||
{
|
|
||||||
return await _tvSearchEngine.Anticipated();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -320,22 +278,7 @@ namespace Ombi.Controllers.V2
|
||||||
[ProducesDefaultResponseType]
|
[ProducesDefaultResponseType]
|
||||||
public async Task<IEnumerable<SearchTvShowViewModel>> AnticipatedTv(int currentPosition, int amountToLoad)
|
public async Task<IEnumerable<SearchTvShowViewModel>> AnticipatedTv(int currentPosition, int amountToLoad)
|
||||||
{
|
{
|
||||||
return await _tvSearchEngine.Anticipated(currentPosition, amountToLoad);
|
return await _tvEngineV2.Anticipated(currentPosition, amountToLoad);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns Most watched shows.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>We use Trakt.tv as the Provider</remarks>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("tv/mostwatched")]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
[ProducesDefaultResponseType]
|
|
||||||
[Obsolete("This method is obsolete, Trakt API no longer supports this")]
|
|
||||||
public async Task<IEnumerable<SearchTvShowViewModel>> MostWatched()
|
|
||||||
{
|
|
||||||
return await _tvSearchEngine.Popular();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -349,21 +292,9 @@ namespace Ombi.Controllers.V2
|
||||||
[Obsolete("This method is obsolete, Trakt API no longer supports this")]
|
[Obsolete("This method is obsolete, Trakt API no longer supports this")]
|
||||||
public async Task<IEnumerable<SearchTvShowViewModel>> MostWatched(int currentPosition, int amountToLoad)
|
public async Task<IEnumerable<SearchTvShowViewModel>> MostWatched(int currentPosition, int amountToLoad)
|
||||||
{
|
{
|
||||||
return await _tvSearchEngine.Popular(currentPosition, amountToLoad);
|
return await _tvEngineV2.Popular(currentPosition, amountToLoad);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns trending shows
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>We use Trakt.tv as the Provider</remarks>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HttpGet("tv/trending")]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
[ProducesDefaultResponseType]
|
|
||||||
public async Task<IEnumerable<SearchTvShowViewModel>> Trending()
|
|
||||||
{
|
|
||||||
return await _tvSearchEngine.Trending();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns trending shows by page
|
/// Returns trending shows by page
|
||||||
|
@ -375,10 +306,9 @@ namespace Ombi.Controllers.V2
|
||||||
[ProducesDefaultResponseType]
|
[ProducesDefaultResponseType]
|
||||||
public async Task<IEnumerable<SearchTvShowViewModel>> Trending(int currentPosition, int amountToLoad)
|
public async Task<IEnumerable<SearchTvShowViewModel>> Trending(int currentPosition, int amountToLoad)
|
||||||
{
|
{
|
||||||
return await _tvSearchEngine.Trending(currentPosition, amountToLoad);
|
return await _tvEngineV2.Trending(currentPosition, amountToLoad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns all the movies that is by the actor id
|
/// Returns all the movies that is by the actor id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
1211
tests/cypress/fixtures/api/v1/tv-search-extra-info.json
Normal file
1211
tests/cypress/fixtures/api/v1/tv-search-extra-info.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -17,6 +17,7 @@
|
||||||
import './commands'
|
import './commands'
|
||||||
import './request.commands';
|
import './request.commands';
|
||||||
import "cypress-real-events/support";
|
import "cypress-real-events/support";
|
||||||
|
import '@bahmutov/cy-api/support';
|
||||||
|
|
||||||
// Alternatively you can use CommonJS syntax:
|
// Alternatively you can use CommonJS syntax:
|
||||||
// require('./commands')
|
// require('./commands')
|
||||||
|
|
51
tests/cypress/tests/api/v1/tv-search.api.spec.ts
Normal file
51
tests/cypress/tests/api/v1/tv-search.api.spec.ts
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
import { movieDetailsPage as Page } from "@/integration/page-objects";
|
||||||
|
|
||||||
|
describe("TV Search V1 API tests", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.login();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Get Extra TV Info", () => {
|
||||||
|
cy.api({url: '/api/v1/search/tv/info/287247', headers: { 'Authorization': 'Bearer ' + window.localStorage.getItem('id_token')} })
|
||||||
|
.then((res) => {
|
||||||
|
expect(res.status).equal(200);
|
||||||
|
cy.fixture('api/v1/tv-search-extra-info').then(x => {
|
||||||
|
expect(res.body).deep.equal(x);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("TV Basic Search", () => {
|
||||||
|
cy.api({url: '/api/v1/search/tv/Shitts Creek', headers: { 'Authorization': 'Bearer ' + window.localStorage.getItem('id_token')} })
|
||||||
|
.then((res) => {
|
||||||
|
expect(res.status).equal(200);
|
||||||
|
const body = res.body;
|
||||||
|
expect(body[0].title).is.equal("Schitt's Creek")
|
||||||
|
expect(body[0].status).is.equal("Ended");
|
||||||
|
expect(body[0].id).is.not.null;
|
||||||
|
expect(body[0].id).to.be.an('number');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const types = [
|
||||||
|
'popular',
|
||||||
|
'trending',
|
||||||
|
'anticipated',
|
||||||
|
'mostwatched'
|
||||||
|
];
|
||||||
|
|
||||||
|
types.forEach((type) => {
|
||||||
|
// derive test name from data
|
||||||
|
it(`${type} TV List`, () => {
|
||||||
|
cy.api({url: '/api/v1/search/tv/'+type, headers: { 'Authorization': 'Bearer ' + window.localStorage.getItem('id_token')} })
|
||||||
|
.then((res) => {
|
||||||
|
expect(res.status).equal(200);
|
||||||
|
const body = res.body;
|
||||||
|
expect(body.length).is.greaterThan(0);
|
||||||
|
expect(body[0].title).is.not.null;
|
||||||
|
expect(body[0].id).is.not.null;
|
||||||
|
expect(body[0].id).to.be.an('number');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -227,6 +227,37 @@ describe("Discover Cards Requests Tests", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it.only("Available TV (From Details Call) does not allow us to request", () => {
|
||||||
|
cy.intercept("GET", "**/search/Tv/popular/**").as("cardsResponse");
|
||||||
|
window.localStorage.setItem("DiscoverOptions2", "3");
|
||||||
|
|
||||||
|
Page.visit();
|
||||||
|
|
||||||
|
cy.wait("@cardsResponse").then((res) => {
|
||||||
|
const body = res.response.body;
|
||||||
|
var expectedId = body[1].id;
|
||||||
|
cy.intercept("GET", "**/search/Tv/moviedb/"+expectedId, (req) => {
|
||||||
|
req.reply((res2) => {
|
||||||
|
const body = res2.body;
|
||||||
|
body.fullyAvailable = true;
|
||||||
|
res2.send(body);
|
||||||
|
});
|
||||||
|
}).as("movieDbResponse");
|
||||||
|
var title = body[1].title;
|
||||||
|
|
||||||
|
|
||||||
|
cy.wait("@movieDbResponse")
|
||||||
|
|
||||||
|
const card = Page.popularCarousel.getCard(expectedId, true, DiscoverType.Popular);
|
||||||
|
card.title.realHover();
|
||||||
|
|
||||||
|
card.verifyTitle(title);
|
||||||
|
card.requestButton.should("not.exist");
|
||||||
|
card.availabilityText.should("have.text", "Available");
|
||||||
|
card.statusClass.should("have.class", "available");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("Not available TV allow admin to request", () => {
|
it("Not available TV allow admin to request", () => {
|
||||||
cy.intercept("GET", "**/search/Tv/popular/**", (req) => {
|
cy.intercept("GET", "**/search/Tv/popular/**", (req) => {
|
||||||
req.reply((res) => {
|
req.reply((res) => {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@bahmutov/cy-api": "^1.5.0",
|
||||||
"cypress": "6.8.0",
|
"cypress": "6.8.0",
|
||||||
"cypress-wait-until": "^1.7.1",
|
"cypress-wait-until": "^1.7.1",
|
||||||
"typescript": "^4.2.3"
|
"typescript": "^4.2.3"
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"target": "es5",
|
||||||
"lib": ["es2018", "dom"],
|
"lib": ["es2018", "dom"],
|
||||||
"types": ["cypress", "cypress-wait-until", "cypress-image-snapshot", "cypress-real-events"],
|
"types": ["cypress", "cypress-wait-until", "cypress-image-snapshot", "cypress-real-events", "@bahmutov/cy-api"],
|
||||||
"baseUrl": "./cypress",
|
"baseUrl": "./cypress",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./*"]
|
"@/*": ["./*"]
|
||||||
|
|
|
@ -2,6 +2,13 @@
|
||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@bahmutov/cy-api@^1.5.0":
|
||||||
|
version "1.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@bahmutov/cy-api/-/cy-api-1.5.0.tgz#e6569f1d0f3040e55f97cf151a16932bfb10dcc6"
|
||||||
|
integrity sha512-N1pBawxcwXyDpJx0qwd78k/6yFEyHWVC71N7n78Rnaegs3LR1Z0odZJrKurpb56JFaP4abNm6EONXEEi5boMmQ==
|
||||||
|
dependencies:
|
||||||
|
common-tags "1.8.0"
|
||||||
|
|
||||||
"@cypress/listr-verbose-renderer@^0.4.1":
|
"@cypress/listr-verbose-renderer@^0.4.1":
|
||||||
version "0.4.1"
|
version "0.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#a77492f4b11dcc7c446a34b3e28721afd33c642a"
|
resolved "https://registry.yarnpkg.com/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#a77492f4b11dcc7c446a34b3e28721afd33c642a"
|
||||||
|
@ -330,7 +337,7 @@ commander@^5.1.0:
|
||||||
resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
|
resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
|
||||||
integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==
|
integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==
|
||||||
|
|
||||||
common-tags@^1.8.0:
|
common-tags@1.8.0, common-tags@^1.8.0:
|
||||||
version "1.8.0"
|
version "1.8.0"
|
||||||
resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937"
|
resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937"
|
||||||
integrity sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==
|
integrity sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue