using System; using AutoMapper; 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.Trakt; using Ombi.Api.TvMaze; using Ombi.Core.Models.Requests; using Ombi.Core.Models.Search; using Ombi.Core.Models.Search.V2; using Ombi.Core.Settings; using Ombi.Core.Settings.Models.External; using Ombi.Store.Repository; using TraktSharp.Entities; namespace Ombi.Core.Engine.V2 { public class TvSearchEngineV2 : BaseMediaEngine, ITVSearchEngineV2 { public TvSearchEngineV2(IPrincipal identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper, ISettingsService plexSettings, ISettingsService embySettings, IPlexContentRepository repo, IEmbyContentRepository embyRepo, ITraktApi trakt, IRuleEvaluator r, OmbiUserManager um, ICacheService memCache, ISettingsService s, IRepository sub) : base(identity, service, r, um, memCache, s, sub) { TvMazeApi = tvMaze; Mapper = mapper; PlexSettings = plexSettings; EmbySettings = embySettings; PlexContentRepo = repo; TraktApi = trakt; EmbyContentRepo = embyRepo; } private ITvMazeApi TvMazeApi { get; } private IMapper Mapper { get; } private ISettingsService PlexSettings { get; } private ISettingsService EmbySettings { get; } private IPlexContentRepository PlexContentRepo { get; } private IEmbyContentRepository EmbyContentRepo { get; } private ITraktApi TraktApi { get; } public async Task GetShowInformation(int tvdbid) { var tvdbshow = await Cache.GetOrAdd(nameof(GetShowInformation) + tvdbid, async () => await TvMazeApi.ShowLookupByTheTvDbId(tvdbid), DateTime.Now.AddHours(12)); var show = await Cache.GetOrAdd("GetTvFullInformation" + tvdbshow.id, async () => await TvMazeApi.GetTvFullInformation(tvdbshow.id), DateTime.Now.AddHours(12)); if (show == null) { // We don't have enough information return null; } // Setup the task so we can get the data later on if we have a IMDBID Task traktInfoTask = new Task(() => null); if (show.externals?.imdb.HasValue() ?? false) { traktInfoTask = Cache.GetOrAdd("GetExtendedTvInfoTrakt" + show.externals?.imdb, () => TraktApi.GetTvExtendedInfo(show.externals?.imdb), DateTime.Now.AddHours(12)); } var mapped = Mapper.Map(show); foreach (var e in show._embedded.episodes) { var season = mapped.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == e.season); if (season == null) { var newSeason = new SeasonRequests { SeasonNumber = e.season, Episodes = new List() }; newSeason.Episodes.Add(new EpisodeRequests { Url = e.url, Title = e.name, AirDate = e.airstamp, EpisodeNumber = e.number, }); mapped.SeasonRequests.Add(newSeason); } else { // We already have the season, so just add the episode season.Episodes.Add(new EpisodeRequests { Url = e.url, Title = e.name, AirDate = e.airstamp, EpisodeNumber = e.number, }); } } return await ProcessResult(mapped, traktInfoTask); } private IEnumerable ProcessResults(IEnumerable items) { var retVal = new List(); foreach (var tvMazeSearch in items) { retVal.Add(ProcessResult(tvMazeSearch)); } return retVal; } private SearchTvShowViewModel ProcessResult(T tvMazeSearch) { return Mapper.Map(tvMazeSearch); } private async Task ProcessResult(SearchFullInfoTvShowViewModel item, Task showInfoTask) { item.TheTvDbId = item.Id.ToString(); var oldModel = Mapper.Map(item); await RunSearchRules(oldModel); item.Available = oldModel.Available; item.FullyAvailable = oldModel.FullyAvailable; item.PartlyAvailable = oldModel.PartlyAvailable; item.Requested = oldModel.Requested; item.Available = oldModel.Available; item.Approved = oldModel.Approved; item.SeasonRequests = oldModel.SeasonRequests; item.RequestId = oldModel.RequestId; return await GetExtraInfo(showInfoTask, item); } private async Task GetExtraInfo(Task showInfoTask, SearchFullInfoTvShowViewModel model) { var result = await showInfoTask; if(result == null) { return model; } model.Trailer = result.Trailer.AbsoluteUri; model.Certification = result.Certification; model.Homepage = result.Homepage.AbsoluteUri; return model; } } }