mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-30 19:40:05 -07:00
Got the TV Page working nicely, requests are up next!
This commit is contained in:
parent
db4123b4ea
commit
be50b1eff1
37 changed files with 2924 additions and 195 deletions
|
@ -1,5 +1,6 @@
|
|||
using Ombi.Core.Models.Search;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ombi.Core.Engine.Interfaces
|
||||
|
@ -7,7 +8,7 @@ namespace Ombi.Core.Engine.Interfaces
|
|||
public interface ITvSearchEngine
|
||||
{
|
||||
Task<IEnumerable<SearchTvShowViewModel>> Search(string searchTerm);
|
||||
Task<SearchTvShowViewModel> GetShowInformation(int tvdbid);
|
||||
Task<SearchTvShowViewModel> GetShowInformation(string movieDbId, CancellationToken token);
|
||||
Task<IEnumerable<SearchTvShowViewModel>> Popular();
|
||||
Task<IEnumerable<SearchTvShowViewModel>> Popular(int currentlyLoaded, int amountToLoad, bool includeImages = false);
|
||||
Task<IEnumerable<SearchTvShowViewModel>> Anticipated();
|
||||
|
|
|
@ -7,8 +7,8 @@ namespace Ombi.Core
|
|||
{
|
||||
public interface ITVSearchEngineV2
|
||||
{
|
||||
Task<SearchFullInfoTvShowViewModel> GetShowInformation(int tvdbid);
|
||||
Task<SearchFullInfoTvShowViewModel> GetShowByRequest(int requestId);
|
||||
Task<IEnumerable<StreamingData>> GetStreamInformation(int tvDbId, int tvMazeId, CancellationToken cancellationToken);
|
||||
Task<SearchFullInfoTvShowViewModel> GetShowInformation(string tvdbid, CancellationToken token);
|
||||
Task<SearchFullInfoTvShowViewModel> GetShowByRequest(int requestId, CancellationToken token);
|
||||
Task<IEnumerable<StreamingData>> GetStreamInformation(int movieDbId, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
|
@ -6,7 +6,6 @@ using Ombi.Core.Engine.Interfaces;
|
|||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Models.Search;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Core.Settings.Models.External;
|
||||
using Ombi.Store.Repository;
|
||||
|
||||
using System;
|
||||
|
@ -16,14 +15,13 @@ using System.Security.Principal;
|
|||
using System.Threading.Tasks;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
using Ombi.Store.Repository.Requests;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Ombi.Core.Authentication;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Settings.Settings.Models;
|
||||
using Ombi.Store.Entities;
|
||||
using TraktSharp.Entities;
|
||||
using Ombi.Api.TheMovieDb;
|
||||
using Ombi.Api.TheMovieDb.Models;
|
||||
using System.Threading;
|
||||
|
||||
namespace Ombi.Core.Engine
|
||||
{
|
||||
|
@ -76,7 +74,7 @@ namespace Ombi.Core.Engine
|
|||
return null;
|
||||
}
|
||||
|
||||
public async Task<SearchTvShowViewModel> GetShowInformation(string theMovieDbId)
|
||||
public async Task<SearchTvShowViewModel> GetShowInformation(string theMovieDbId, CancellationToken token)
|
||||
{
|
||||
var show = await Cache.GetOrAdd(nameof(GetShowInformation) + theMovieDbId,
|
||||
async () => await _theMovieDbApi.GetTVInfo(theMovieDbId), DateTime.Now.AddHours(12));
|
||||
|
@ -96,38 +94,44 @@ namespace Ombi.Core.Engine
|
|||
|
||||
var mapped = Mapper.Map<SearchTvShowViewModel>(show);
|
||||
|
||||
foreach (var e in show.seasons)
|
||||
foreach(var tvSeason in show.seasons)
|
||||
{
|
||||
var season = mapped.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == e.season_number);
|
||||
if (season == null)
|
||||
{
|
||||
var newSeason = new SeasonRequests
|
||||
{
|
||||
SeasonNumber = e.season_number,
|
||||
Episodes = new List<EpisodeRequests>()
|
||||
};
|
||||
newSeason.Episodes.Add(new EpisodeRequests
|
||||
{
|
||||
//Url = e..ToHttpsUrl(),
|
||||
Title = e.name,
|
||||
AirDate = e.air_date.HasValue() ? DateTime.Parse(e.air_date) : DateTime.MinValue,
|
||||
EpisodeNumber = e,
|
||||
var seasonEpisodes = (await _theMovieDbApi.GetSeasonEpisodes(show.id, tvSeason.season_number, token));
|
||||
|
||||
});
|
||||
mapped.SeasonRequests.Add(newSeason);
|
||||
}
|
||||
else
|
||||
foreach (var episode in seasonEpisodes.episodes)
|
||||
{
|
||||
// We already have the season, so just add the episode
|
||||
season.Episodes.Add(new EpisodeRequests
|
||||
var season = mapped.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == episode.season_number);
|
||||
if (season == null)
|
||||
{
|
||||
Url = e.url.ToHttpsUrl(),
|
||||
Title = e.name,
|
||||
AirDate = e.airstamp.HasValue() ? DateTime.Parse(e.airstamp) : DateTime.MinValue,
|
||||
EpisodeNumber = e.number,
|
||||
});
|
||||
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,
|
||||
|
||||
});
|
||||
mapped.SeasonRequests.Add(newSeason);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return await ProcessResult(mapped, false);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,89 +43,70 @@ namespace Ombi.Core.Engine.V2
|
|||
}
|
||||
|
||||
|
||||
public async Task<SearchFullInfoTvShowViewModel> GetShowByRequest(int requestId)
|
||||
public async Task<SearchFullInfoTvShowViewModel> GetShowByRequest(int requestId, CancellationToken token)
|
||||
{
|
||||
var request = await RequestService.TvRequestService.Get().FirstOrDefaultAsync(x => x.Id == requestId);
|
||||
return await GetShowInformation(request.TvDbId);
|
||||
return await GetShowInformation(request.TvDbId.ToString(), token); // TODO
|
||||
}
|
||||
|
||||
public async Task<SearchFullInfoTvShowViewModel> GetShowInformation(int tvdbid)
|
||||
public async Task<SearchFullInfoTvShowViewModel> GetShowInformation(string tvdbid, CancellationToken token)
|
||||
{
|
||||
var tvdbshow = await Cache.GetOrAdd(nameof(GetShowInformation) + tvdbid,
|
||||
async () => await _tvMaze.ShowLookupByTheTvDbId(tvdbid), DateTime.Now.AddHours(12));
|
||||
if (tvdbshow == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var show = await Cache.GetOrAdd("GetTvFullInformation" + tvdbshow.id,
|
||||
async () => await _tvMaze.GetTvFullInformation(tvdbshow.id), DateTime.Now.AddHours(12));
|
||||
var show = await Cache.GetOrAdd(nameof(GetShowInformation) + tvdbid,
|
||||
async () => await _movieApi.GetTVInfo(tvdbid), 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<TraktShow> traktInfoTask = 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<SearchFullInfoTvShowViewModel>(show);
|
||||
|
||||
foreach (var e in show._embedded?.episodes ?? new Api.TvMaze.Models.V2.Episode[0])
|
||||
{
|
||||
var season = mapped.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == e.season);
|
||||
if (season == null)
|
||||
{
|
||||
var newSeason = new SeasonRequests
|
||||
{
|
||||
SeasonNumber = e.season,
|
||||
Episodes = new List<EpisodeRequests>()
|
||||
};
|
||||
newSeason.Episodes.Add(new EpisodeRequests
|
||||
{
|
||||
Url = e.url.ToHttpsUrl(),
|
||||
Title = e.name,
|
||||
AirDate = e.airstamp,
|
||||
EpisodeNumber = e.number,
|
||||
|
||||
});
|
||||
mapped.SeasonRequests.Add(newSeason);
|
||||
}
|
||||
else
|
||||
foreach (var tvSeason in show.seasons.Where(x => x.season_number != 0)) // skip the first season
|
||||
{
|
||||
var seasonEpisodes = (await _movieApi.GetSeasonEpisodes(show.id, tvSeason.season_number, token));
|
||||
|
||||
foreach (var episode in seasonEpisodes.episodes)
|
||||
{
|
||||
// We already have the season, so just add the episode
|
||||
season.Episodes.Add(new EpisodeRequests
|
||||
var season = mapped.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == episode.season_number);
|
||||
if (season == null)
|
||||
{
|
||||
Url = e.url.ToHttpsUrl(),
|
||||
Title = e.name,
|
||||
AirDate = e.airstamp,
|
||||
EpisodeNumber = e.number,
|
||||
});
|
||||
var newSeason = new SeasonRequests
|
||||
{
|
||||
SeasonNumber = episode.season_number,
|
||||
Overview = tvSeason.overview,
|
||||
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,
|
||||
|
||||
});
|
||||
mapped.SeasonRequests.Add(newSeason);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return await ProcessResult(mapped, traktInfoTask);
|
||||
|
||||
return await ProcessResult(mapped);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<StreamingData>> GetStreamInformation(int tvDbId, int tvMazeId, CancellationToken cancellationToken)
|
||||
public async Task<IEnumerable<StreamingData>> GetStreamInformation(int movieDbId, CancellationToken cancellationToken)
|
||||
{
|
||||
var tvdbshow = await Cache.GetOrAdd(nameof(GetShowInformation) + tvMazeId,
|
||||
async () => await _tvMaze.ShowLookupByTheTvDbId(tvMazeId), DateTime.Now.AddHours(12));
|
||||
if (tvdbshow == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// this is a best effort guess since TV maze do not provide the TheMovieDbId
|
||||
var movieDbResults = await _movieApi.SearchTv(tvdbshow.name, tvdbshow.premiered.Substring(0, 4));
|
||||
var potential = movieDbResults.FirstOrDefault();
|
||||
tvDbId = potential.Id;
|
||||
// end guess
|
||||
|
||||
var providers = await _movieApi.GetTvWatchProviders(tvDbId, cancellationToken);
|
||||
var providers = await _movieApi.GetTvWatchProviders(movieDbId, cancellationToken);
|
||||
var results = await GetUserWatchProvider(providers);
|
||||
|
||||
var data = new List<StreamingData>();
|
||||
|
@ -158,9 +139,9 @@ namespace Ombi.Core.Engine.V2
|
|||
return _mapper.Map<SearchTvShowViewModel>(tvMazeSearch);
|
||||
}
|
||||
|
||||
private async Task<SearchFullInfoTvShowViewModel> ProcessResult(SearchFullInfoTvShowViewModel item, Task<TraktShow> showInfoTask)
|
||||
private async Task<SearchFullInfoTvShowViewModel> ProcessResult(SearchFullInfoTvShowViewModel item)
|
||||
{
|
||||
item.TheTvDbId = item.Id.ToString();
|
||||
item.TheMovieDbId = item.Id.ToString();
|
||||
|
||||
var oldModel = _mapper.Map<SearchTvShowViewModel>(item);
|
||||
await RunSearchRules(oldModel);
|
||||
|
@ -179,18 +160,9 @@ namespace Ombi.Core.Engine.V2
|
|||
item.Images.Medium = item.Images.Medium.ToHttpsUrl();
|
||||
}
|
||||
|
||||
if (item.Cast?.Any() ?? false)
|
||||
{
|
||||
foreach (var cast in item.Cast)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(cast.Character?.Image?.Medium))
|
||||
{
|
||||
cast.Character.Image.Medium = cast.Character?.Image?.Medium.ToHttpsUrl();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return await GetExtraInfo(showInfoTask, item);
|
||||
|
||||
return item;
|
||||
//return await GetExtraInfo(showInfoTask, item);
|
||||
}
|
||||
|
||||
private async Task<SearchFullInfoTvShowViewModel> GetExtraInfo(Task<TraktShow> showInfoTask, SearchFullInfoTvShowViewModel model)
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace Ombi.Core.Helpers
|
|||
public TvRequests NewRequest { get; protected set; }
|
||||
protected TvMazeShow ShowInfo { get; set; }
|
||||
protected List<TvSearchResult> Results { get; set; }
|
||||
protected TvSearchResult TheMovieDbRecord { get; set; }
|
||||
|
||||
public async Task<TvShowRequestBuilder> GetShowInfo(int id)
|
||||
{
|
||||
|
@ -42,7 +43,8 @@ namespace Ombi.Core.Helpers
|
|||
Results = await MovieDbApi.SearchTv(ShowInfo.name);
|
||||
foreach (TvSearchResult result in Results) {
|
||||
if (result.Name.Equals(ShowInfo.name, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
{
|
||||
TheMovieDbRecord = result;
|
||||
var showIds = await MovieDbApi.GetTvExternals(result.Id);
|
||||
ShowInfo.externals.imdb = showIds.imdb_id;
|
||||
BackdropPath = result.BackdropPath;
|
||||
|
@ -240,6 +242,7 @@ namespace Ombi.Core.Helpers
|
|||
PosterPath = PosterPath,
|
||||
Title = ShowInfo.name,
|
||||
ReleaseDate = FirstAir,
|
||||
ExternalProviderId = TheMovieDbRecord.Id,
|
||||
Status = ShowInfo.status,
|
||||
ImdbId = ShowInfo.externals?.imdb ?? string.Empty,
|
||||
TvDbId = tv.TvDbId,
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace Ombi.Core.Models.Search.V2
|
|||
public string FirstAired { get; set; }
|
||||
public string NetworkId { get; set; }
|
||||
public string Runtime { get; set; }
|
||||
public List<string> Genre { get; set; }
|
||||
public GenreViewModel[] Genres { get; set; }
|
||||
public string Overview { get; set; }
|
||||
public int LastUpdated { get; set; }
|
||||
public string AirsDayOfWeek { get; set; }
|
||||
|
@ -24,23 +24,12 @@ namespace Ombi.Core.Models.Search.V2
|
|||
public NetworkViewModel Network { get; set; }
|
||||
public Images Images { get; set; }
|
||||
public List<CastViewModel> Cast { get; set; }
|
||||
public List<CrewViewModel> Crew { get; set; }
|
||||
public List<PersonViewModel> Crew { get; set; }
|
||||
public string Certification { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This is used from the Trakt API
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The trailer.
|
||||
/// </value>
|
||||
public string Tagline { get; set; }
|
||||
public Keywords Keywords { get; set; }
|
||||
public ExternalIds ExternalIds { get; set; }
|
||||
public string Trailer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This is used from the Trakt API
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The trailer.
|
||||
/// </value>
|
||||
public string Homepage { get; set; }
|
||||
|
||||
public List<SeasonRequests> SeasonRequests { get; set; } = new List<SeasonRequests>();
|
||||
|
@ -66,7 +55,7 @@ namespace Ombi.Core.Models.Search.V2
|
|||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public Country Country { get; set; }
|
||||
public string Country { get; set; }
|
||||
}
|
||||
|
||||
public class Country
|
||||
|
@ -84,8 +73,9 @@ namespace Ombi.Core.Models.Search.V2
|
|||
|
||||
public class CastViewModel
|
||||
{
|
||||
public PersonViewModel Person { get; set; }
|
||||
public CharacterViewModel Character { get; set; }
|
||||
public string Person { get; set; }
|
||||
public string Character { get; set; }
|
||||
public string Image { get; set; }
|
||||
public bool Self { get; set; }
|
||||
public bool Voice { get; set; }
|
||||
}
|
||||
|
@ -95,7 +85,7 @@ namespace Ombi.Core.Models.Search.V2
|
|||
public int Id { get; set; }
|
||||
public string Url { get; set; }
|
||||
public string Name { get; set; }
|
||||
public Images Image { get; set; }
|
||||
public string Image { get; set; }
|
||||
}
|
||||
|
||||
public class CharacterViewModel
|
||||
|
@ -106,9 +96,4 @@ namespace Ombi.Core.Models.Search.V2
|
|||
public Images Image { get; set; }
|
||||
}
|
||||
|
||||
public class CrewViewModel
|
||||
{
|
||||
public string Type { get; set; }
|
||||
public PersonViewModel Person { get; set; }
|
||||
}
|
||||
}
|
|
@ -54,7 +54,7 @@ namespace Ombi.Core.Rule.Rules
|
|||
{
|
||||
var vm = (SearchTvShowViewModel) obj;
|
||||
// Check if it's in Radarr
|
||||
var result = await _ctx.SonarrCache.FirstOrDefaultAsync(x => x.TvDbId == vm.Id);
|
||||
var result = await _ctx.SonarrCache.FirstOrDefaultAsync(x => x.TvDbId.ToString() == vm.TheTvDbId);
|
||||
if (result != null)
|
||||
{
|
||||
vm.Approved = true;
|
||||
|
@ -69,7 +69,7 @@ namespace Ombi.Core.Rule.Rules
|
|||
// Check if we have it
|
||||
var monitoredInSonarr = await sonarrEpisodes.FirstOrDefaultAsync(x =>
|
||||
x.EpisodeNumber == ep.EpisodeNumber && x.SeasonNumber == season.SeasonNumber
|
||||
&& x.TvDbId == vm.Id);
|
||||
&& x.TvDbId.ToString() == vm.TheTvDbId);
|
||||
if (monitoredInSonarr != null)
|
||||
{
|
||||
ep.Approved = true;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue