You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Ombi/src/Ombi.Core/Engine/TvSearchEngine.cs

262 lines
10 KiB

using AutoMapper;
using Ombi.Api.Trakt;
using Ombi.Api.TvMaze;
using Ombi.Core.Engine.Interfaces;
using Ombi.Core.Models.Requests;
using Ombi.Core.Models.Search;
using Ombi.Core.Settings;
using Ombi.Store.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
using Ombi.Core.Rule.Interfaces;
using Ombi.Store.Repository.Requests;
using Ombi.Core.Authentication;
using Ombi.Helpers;
using Ombi.Settings.Settings.Models;
using Ombi.Store.Entities;
using Ombi.Api.TheMovieDb;
using Ombi.Api.TheMovieDb.Models;
using System.Threading;
using TraktSharp.Entities;
using Ombi.Core.Helpers;
namespace Ombi.Core.Engine
{
public class TvSearchEngine : BaseMediaEngine, ITvSearchEngine
{
private readonly ISettingsService<CustomizationSettings> _customizationSettings;
private readonly IImageService _imageService;
private readonly IMovieDbApi _theMovieDbApi;
public TvSearchEngine(ICurrentUser identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper,
ITraktApi trakt, IRuleEvaluator r, OmbiUserManager um, ISettingsService<CustomizationSettings> customizationSettings,
ICacheService memCache, ISettingsService<OmbiSettings> s, IRepository<RequestSubscription> sub, IImageService imageService,
IMovieDbApi theMovieDbApi)
: base(identity, service, r, um, memCache, s, sub)
{
_imageService = imageService;
_theMovieDbApi = theMovieDbApi;
TvMazeApi = tvMaze;
Mapper = mapper;
TraktApi = trakt;
_customizationSettings = customizationSettings;
}
protected ITvMazeApi TvMazeApi { get; }
protected IMapper Mapper { get; }
private ITraktApi TraktApi { get; }
public async Task<IEnumerable<SearchTvShowViewModel>> Search(string searchTerm)
{
var searchResult = await TvMazeApi.Search(searchTerm);
if (searchResult != null)
{
var retVal = new List<SearchTvShowViewModel>();
foreach (var tvMazeSearch in searchResult)
{
if (tvMazeSearch.show.externals == null || !(tvMazeSearch.show.externals?.thetvdb.HasValue ?? false))
{
continue;
}
var mappedResult = await ProcessResult(tvMazeSearch, false);
if (mappedResult == null)
{
continue;
}
retVal.Add(mappedResult);
}
return retVal;
}
return null;
}
public async Task<SearchTvShowViewModel> GetShowInformation(string tvdbid, CancellationToken token)
{
var show = await Cache.GetOrAddAsync(nameof(GetShowInformation) + tvdbid,
() => TvMazeApi.ShowLookupByTheTvDbId(int.Parse(tvdbid)), DateTimeOffset.Now.AddHours(12));
if (show == null)
{
// We don't have enough information
return null;
}
var episodes = await Cache.GetOrAddAsync("TvMazeEpisodeLookup" + show.id,
() => TvMazeApi.EpisodeLookup(show.id), DateTimeOffset.Now.AddHours(12));
if (episodes == null || !episodes.Any())
{
// We don't have enough information
return null;
}
var mapped = Mapper.Map<SearchTvShowViewModel>(show);
foreach (var e in episodes)
{
var season = mapped.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == e.season);
if (season == null)
{
var newSeason = new SeasonRequests
{
SeasonNumber = e.season,
Episodes = new List<EpisodeRequests>()
};
var hasAirDate = e.airstamp.HasValue();
var airDate = DateTime.MinValue;
if (hasAirDate)
{
hasAirDate = DateTime.TryParse(e.airdate, out airDate);
}
newSeason.Episodes.Add(new EpisodeRequests
{
Url = e.url.ToHttpsUrl(),
Title = e.name,
AirDate = airDate,
EpisodeNumber = e.number,
});
mapped.SeasonRequests.Add(newSeason);
}
else
{
var hasAirDate = e.airstamp.HasValue();
var airDate = DateTime.MinValue;
if (hasAirDate)
{
hasAirDate = DateTime.TryParse(e.airdate, out airDate);
}
// We already have the season, so just add the episode
season.Episodes.Add(new EpisodeRequests
{
Url = e.url.ToHttpsUrl(),
Title = e.name,
AirDate = airDate,
EpisodeNumber = e.number,
});
}
}
return await ProcessResult(mapped, false);
}
public async Task<IEnumerable<SearchTvShowViewModel>> Popular()
{
var result = await Cache.GetOrAddAsync(CacheKeys.PopularTv, () => TraktApi.GetPopularShows(null, ResultLimit), DateTimeOffset.Now.AddHours(12));
var processed = ProcessResults(result);
return await processed;
}
public async Task<IEnumerable<SearchTvShowViewModel>> Popular(int currentlyLoaded, int amountToLoad, bool includeImages = false)
{
var langCode = await DefaultLanguageCode(null);
var pages = PaginationHelper.GetNextPages(currentlyLoaded, amountToLoad, ResultLimit);
var results = new List<TraktShow>();
foreach (var pagesToLoad in pages)
{
var apiResult = await Cache.GetOrAddAsync(nameof(Popular) + langCode + pagesToLoad.Page,
() => TraktApi.GetPopularShows(pagesToLoad.Page, ResultLimit), DateTimeOffset.Now.AddHours(12));
results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take));
}
var processed = ProcessResults(results, includeImages);
return await processed;
}
public async Task<IEnumerable<SearchTvShowViewModel>> Anticipated()
{
var result = await Cache.GetOrAddAsync(CacheKeys.AnticipatedTv, () => TraktApi.GetAnticipatedShows(null, ResultLimit), DateTimeOffset.Now.AddHours(12));
var processed = ProcessResults(result);
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<TraktShow>();
foreach (var pagesToLoad in pages)
{
var apiResult = await Cache.GetOrAddAsync(nameof(Anticipated) + langCode + pagesToLoad.Page,
() => TraktApi.GetAnticipatedShows(pagesToLoad.Page, ResultLimit), DateTimeOffset.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()
{
var result = await Cache.GetOrAddAsync(CacheKeys.TrendingTv, () => TraktApi.GetTrendingShows(null, ResultLimit), DateTimeOffset.Now.AddHours(12));
var processed = ProcessResults(result);
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<TraktShow>();
foreach (var pagesToLoad in pages)
{
var apiResult = await Cache.GetOrAddAsync(nameof(Trending) + langCode + pagesToLoad.Page,
() => TraktApi.GetTrendingShows(pagesToLoad.Page, ResultLimit), DateTimeOffset.Now.AddHours(12));
results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take));
}
var processed = ProcessResults(results);
return await processed;
}
protected async Task<IEnumerable<SearchTvShowViewModel>> ProcessResults<T>(IEnumerable<T> items, bool includeImages = false)
{
var retVal = new List<SearchTvShowViewModel>();
var settings = await _customizationSettings.GetSettingsAsync();
foreach (var tvMazeSearch in items)
{
var result = await ProcessResult(tvMazeSearch, includeImages);
if (result == null || settings.HideAvailableFromDiscover && result.Available)
{
continue;
}
retVal.Add(result);
}
return retVal;
}
protected async Task<SearchTvShowViewModel> ProcessResult<T>(T tvMazeSearch, bool includeImages)
{
var mapped = Mapper.Map<SearchTvShowViewModel>(tvMazeSearch);
return await ProcessResult(mapped, includeImages);
}
private async Task<SearchTvShowViewModel> ProcessResult(SearchTvShowViewModel item, bool includeImages)
{
if (item.Id == 0)
{
return null;
}
item.TheMovieDbId = item.Id.ToString();
//item.TheTvDbId = item.Id.ToString();
//if (includeImages)
//{
// if (item.TheTvDbId.HasValue())
// {
// item.BackdropPath = await _imageService.GetTvBackground(item.TheTvDbId);
// }
//}
await RunSearchRules(item);
return item;
}
}
}