diff options
Diffstat (limited to 'MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs')
| -rw-r--r-- | MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs new file mode 100644 index 000000000..93998a110 --- /dev/null +++ b/MediaBrowser.Providers/Plugins/Tmdb/TV/TmdbEpisodeProvider.cs @@ -0,0 +1,207 @@ +#pragma warning disable CS1591 + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; + +namespace MediaBrowser.Providers.Plugins.Tmdb.TV +{ + public class TmdbEpisodeProvider : IRemoteMetadataProvider<Episode, EpisodeInfo>, IHasOrder + { + private readonly IHttpClientFactory _httpClientFactory; + private readonly TmdbClientManager _tmdbClientManager; + + public TmdbEpisodeProvider(IHttpClientFactory httpClientFactory, TmdbClientManager tmdbClientManager) + { + _httpClientFactory = httpClientFactory; + _tmdbClientManager = tmdbClientManager; + } + + // After TheTvDb + public int Order => 1; + + public string Name => TmdbUtils.ProviderName; + + public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(EpisodeInfo searchInfo, CancellationToken cancellationToken) + { + // The search query must either provide an episode number or date + if (!searchInfo.IndexNumber.HasValue || !searchInfo.ParentIndexNumber.HasValue) + { + return Enumerable.Empty<RemoteSearchResult>(); + } + + var metadataResult = await GetMetadata(searchInfo, cancellationToken).ConfigureAwait(false); + + if (!metadataResult.HasMetadata) + { + return Enumerable.Empty<RemoteSearchResult>(); + } + + var item = metadataResult.Item; + + return new[] + { + new RemoteSearchResult + { + IndexNumber = item.IndexNumber, + Name = item.Name, + ParentIndexNumber = item.ParentIndexNumber, + PremiereDate = item.PremiereDate, + ProductionYear = item.ProductionYear, + ProviderIds = item.ProviderIds, + SearchProviderName = Name, + IndexNumberEnd = item.IndexNumberEnd + } + }; + } + + public async Task<MetadataResult<Episode>> GetMetadata(EpisodeInfo info, CancellationToken cancellationToken) + { + var metadataResult = new MetadataResult<Episode>(); + + // Allowing this will dramatically increase scan times + if (info.IsMissingEpisode) + { + return metadataResult; + } + + info.SeriesProviderIds.TryGetValue(MetadataProvider.Tmdb.ToString(), out string tmdbId); + + var seriesTmdbId = Convert.ToInt32(tmdbId, CultureInfo.InvariantCulture); + if (seriesTmdbId <= 0) + { + return metadataResult; + } + + var seasonNumber = info.ParentIndexNumber; + var episodeNumber = info.IndexNumber; + + if (!seasonNumber.HasValue || !episodeNumber.HasValue) + { + return metadataResult; + } + + var episodeResult = await _tmdbClientManager + .GetEpisodeAsync(seriesTmdbId, seasonNumber.Value, episodeNumber.Value, info.MetadataLanguage, TmdbUtils.GetImageLanguagesParam(info.MetadataLanguage), cancellationToken) + .ConfigureAwait(false); + + if (episodeResult == null) + { + return metadataResult; + } + + metadataResult.HasMetadata = true; + metadataResult.QueriedById = true; + + if (!string.IsNullOrEmpty(episodeResult.Overview)) + { + // if overview is non-empty, we can assume that localized data was returned + metadataResult.ResultLanguage = info.MetadataLanguage; + } + + var item = new Episode + { + Name = info.Name, + IndexNumber = info.IndexNumber, + ParentIndexNumber = info.ParentIndexNumber, + IndexNumberEnd = info.IndexNumberEnd + }; + + if (!string.IsNullOrEmpty(episodeResult.ExternalIds?.TvdbId)) + { + item.SetProviderId(MetadataProvider.Tvdb, episodeResult.ExternalIds.TvdbId); + } + + item.PremiereDate = episodeResult.AirDate; + item.ProductionYear = episodeResult.AirDate?.Year; + + item.Name = episodeResult.Name; + item.Overview = episodeResult.Overview; + + item.CommunityRating = Convert.ToSingle(episodeResult.VoteAverage); + + if (episodeResult.Videos?.Results != null) + { + foreach (var video in episodeResult.Videos.Results) + { + if (TmdbUtils.IsTrailerType(video)) + { + item.AddTrailerUrl("https://www.youtube.com/watch?v=" + video.Key); + } + } + } + + var credits = episodeResult.Credits; + + if (credits?.Cast != null) + { + foreach (var actor in credits.Cast.OrderBy(a => a.Order).Take(TmdbUtils.MaxCastMembers)) + { + metadataResult.AddPerson(new PersonInfo + { + Name = actor.Name.Trim(), + Role = actor.Character, + Type = PersonType.Actor, + SortOrder = actor.Order + }); + } + } + + if (credits?.GuestStars != null) + { + foreach (var guest in credits.GuestStars.OrderBy(a => a.Order).Take(TmdbUtils.MaxCastMembers)) + { + metadataResult.AddPerson(new PersonInfo + { + Name = guest.Name.Trim(), + Role = guest.Character, + Type = PersonType.GuestStar, + SortOrder = guest.Order + }); + } + } + + // and the rest from crew + if (credits?.Crew != null) + { + foreach (var person in credits.Crew) + { + // Normalize this + var type = TmdbUtils.MapCrewToPersonType(person); + + if (!TmdbUtils.WantedCrewTypes.Contains(type, StringComparer.OrdinalIgnoreCase) + && !TmdbUtils.WantedCrewTypes.Contains(person.Job ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + { + continue; + } + + metadataResult.AddPerson(new PersonInfo + { + Name = person.Name.Trim(), + Role = person.Job, + Type = type + }); + } + } + + metadataResult.Item = item; + + return metadataResult; + } + + public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken) + { + return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken); + } + } +} |
