using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using Jellyfin.Data.Enums; using Jellyfin.Extensions; 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 { /// /// TV season provider powered by TheMovieDb. /// public class TmdbSeasonProvider : IRemoteMetadataProvider { private readonly IHttpClientFactory _httpClientFactory; private readonly TmdbClientManager _tmdbClientManager; /// /// Initializes a new instance of the class. /// /// The . /// The . public TmdbSeasonProvider(IHttpClientFactory httpClientFactory, TmdbClientManager tmdbClientManager) { _httpClientFactory = httpClientFactory; _tmdbClientManager = tmdbClientManager; } /// public string Name => TmdbUtils.ProviderName; /// public async Task> GetMetadata(SeasonInfo info, CancellationToken cancellationToken) { var result = new MetadataResult(); var config = Plugin.Instance.Configuration; info.SeriesProviderIds.TryGetValue(MetadataProvider.Tmdb.ToString(), out string? seriesTmdbId); var seasonNumber = info.IndexNumber; if (string.IsNullOrWhiteSpace(seriesTmdbId) || !seasonNumber.HasValue) { return result; } var seasonResult = await _tmdbClientManager .GetSeasonAsync(Convert.ToInt32(seriesTmdbId, CultureInfo.InvariantCulture), seasonNumber.Value, info.MetadataLanguage, TmdbUtils.GetImageLanguagesParam(info.MetadataLanguage), cancellationToken) .ConfigureAwait(false); if (seasonResult is null) { return result; } result.HasMetadata = true; result.Item = new Season { IndexNumber = seasonNumber, Overview = seasonResult.Overview, PremiereDate = seasonResult.AirDate, ProductionYear = seasonResult.AirDate?.Year }; if (config.ImportSeasonName) { result.Item.Name = seasonResult.Name; } result.Item.TrySetProviderId(MetadataProvider.Tvdb, seasonResult.ExternalIds.TvdbId); // TODO why was this disabled? var credits = seasonResult.Credits; if (credits?.Cast is not null) { var castQuery = config.HideMissingCastMembers ? credits.Cast.Where(a => !string.IsNullOrEmpty(a.ProfilePath)).OrderBy(a => a.Order) : credits.Cast.OrderBy(a => a.Order); foreach (var actor in castQuery.Take(config.MaxCastMembers)) { if (string.IsNullOrWhiteSpace(actor.Name)) { continue; } var personInfo = new PersonInfo { Name = actor.Name.Trim(), Role = actor.Character?.Trim() ?? string.Empty, Type = PersonKind.Actor, SortOrder = actor.Order, ImageUrl = _tmdbClientManager.GetProfileUrl(actor.ProfilePath) }; if (actor.Id > 0) { personInfo.SetProviderId(MetadataProvider.Tmdb, actor.Id.ToString(CultureInfo.InvariantCulture)); } result.AddPerson(personInfo); } } if (credits?.Crew is not null) { var crewQuery = credits.Crew .Select(crewMember => new { CrewMember = crewMember, PersonType = TmdbUtils.MapCrewToPersonType(crewMember) }) .Where(entry => TmdbUtils.WantedCrewKinds.Contains(entry.PersonType) || TmdbUtils.WantedCrewTypes.Contains(entry.CrewMember.Job ?? string.Empty, StringComparison.OrdinalIgnoreCase)); if (config.HideMissingCrewMembers) { crewQuery = crewQuery.Where(entry => !string.IsNullOrEmpty(entry.CrewMember.ProfilePath)); } foreach (var entry in crewQuery.Take(config.MaxCrewMembers)) { var crewMember = entry.CrewMember; if (string.IsNullOrWhiteSpace(crewMember.Name)) { continue; } var personInfo = new PersonInfo { Name = crewMember.Name.Trim(), Role = crewMember.Job?.Trim() ?? string.Empty, Type = entry.PersonType, ImageUrl = _tmdbClientManager.GetProfileUrl(crewMember.ProfilePath) }; if (crewMember.Id > 0) { personInfo.SetProviderId(MetadataProvider.Tmdb, crewMember.Id.ToString(CultureInfo.InvariantCulture)); } result.AddPerson(personInfo); } } return result; } /// public Task> GetSearchResults(SeasonInfo searchInfo, CancellationToken cancellationToken) { return Task.FromResult(Enumerable.Empty()); } /// public Task GetImageResponse(string url, CancellationToken cancellationToken) { return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken); } } }