< Summary - Jellyfin

Information
Class: MediaBrowser.Providers.Plugins.Tmdb.People.TmdbPersonProvider
Assembly: MediaBrowser.Providers
File(s): /srv/git/jellyfin/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonProvider.cs
Line coverage
4%
Covered lines: 3
Uncovered lines: 64
Coverable lines: 67
Total lines: 152
Line coverage: 4.4%
Branch coverage
0%
Covered branches: 0
Total branches: 32
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 5/11/2026 - 12:15:59 AM Line coverage: 4.6% (3/64) Branch coverage: 0% (0/32) Total lines: 14810/29/2026 - 12:17:11 AM Line coverage: 4.4% (3/67) Branch coverage: 0% (0/32) Total lines: 152 5/11/2026 - 12:15:59 AM Line coverage: 4.6% (3/64) Branch coverage: 0% (0/32) Total lines: 14810/29/2026 - 12:17:11 AM Line coverage: 4.4% (3/67) Branch coverage: 0% (0/32) Total lines: 152

Coverage delta

Coverage delta 1 -1

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_Name()100%210%
GetSearchResults()0%272160%
GetMetadata()0%272160%
GetImageResponse(...)100%210%

File(s)

/srv/git/jellyfin/MediaBrowser.Providers/Plugins/Tmdb/People/TmdbPersonProvider.cs

#LineLine coverage
 1using System.Collections.Generic;
 2using System.Globalization;
 3using System.Net.Http;
 4using System.Threading;
 5using System.Threading.Tasks;
 6using MediaBrowser.Common.Net;
 7using MediaBrowser.Controller.Entities;
 8using MediaBrowser.Controller.Providers;
 9using MediaBrowser.Model.Entities;
 10using MediaBrowser.Model.Providers;
 11
 12namespace MediaBrowser.Providers.Plugins.Tmdb.People
 13{
 14    /// <summary>
 15    /// Person image provider powered by TMDb.
 16    /// </summary>
 17    public class TmdbPersonProvider : IRemoteMetadataProvider<Person, PersonLookupInfo>
 18    {
 19        private readonly IHttpClientFactory _httpClientFactory;
 20        private readonly TmdbClientManager _tmdbClientManager;
 21
 22        /// <summary>
 23        /// Initializes a new instance of the <see cref="TmdbPersonProvider"/> class.
 24        /// </summary>
 25        /// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/>.</param>
 26        /// <param name="tmdbClientManager">The <see cref="TmdbClientManager"/>.</param>
 27        public TmdbPersonProvider(IHttpClientFactory httpClientFactory, TmdbClientManager tmdbClientManager)
 28        {
 2729            _httpClientFactory = httpClientFactory;
 2730            _tmdbClientManager = tmdbClientManager;
 2731        }
 32
 33        /// <inheritdoc />
 034        public string Name => TmdbUtils.ProviderName;
 35
 36        /// <inheritdoc />
 37        public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(PersonLookupInfo searchInfo, CancellationTok
 38        {
 039            if (searchInfo.TryGetTmdbId(out var personTmdbId))
 40            {
 041                var personResult = await _tmdbClientManager.GetPersonAsync(personTmdbId, searchInfo.MetadataLanguage, se
 42
 043                if (personResult is not null)
 44                {
 045                    var result = new RemoteSearchResult
 046                    {
 047                        Name = personResult.Name,
 048                        SearchProviderName = Name,
 049                        Overview = personResult.Biography
 050                    };
 51
 052                    if (personResult.Images?.Profiles is not null && personResult.Images.Profiles.Count > 0)
 53                    {
 054                        result.ImageUrl = _tmdbClientManager.GetProfileUrl(personResult.Images.Profiles[0].FilePath);
 55                    }
 56
 057                    result.SetProviderId(MetadataProvider.Tmdb, personResult.Id.ToString(CultureInfo.InvariantCulture));
 058                    result.TrySetProviderId(MetadataProvider.Imdb, personResult.ExternalIds?.ImdbId);
 59
 060                    return [result];
 61                }
 62            }
 63
 064            var personSearchResult = await _tmdbClientManager.SearchPersonAsync(searchInfo.Name, cancellationToken).Conf
 065            if (personSearchResult is null)
 66            {
 067                return [];
 68            }
 69
 070            var remoteSearchResults = new RemoteSearchResult[personSearchResult.Count];
 071            for (var i = 0; i < personSearchResult.Count; i++)
 72            {
 073                var person = personSearchResult[i];
 074                var remoteSearchResult = new RemoteSearchResult
 075                {
 076                    SearchProviderName = Name,
 077                    Name = person.Name,
 078                    ImageUrl = _tmdbClientManager.GetProfileUrl(person.ProfilePath)
 079                };
 80
 081                remoteSearchResult.SetProviderId(MetadataProvider.Tmdb, person.Id.ToString(CultureInfo.InvariantCulture)
 082                remoteSearchResults[i] = remoteSearchResult;
 83            }
 84
 085            return remoteSearchResults;
 086        }
 87
 88        /// <inheritdoc />
 89        public async Task<MetadataResult<Person>> GetMetadata(PersonLookupInfo info, CancellationToken cancellationToken
 90        {
 91            // A person can carry another provider's id under the TMDb key, which is no more usable here
 92            // than no id at all, so both take the search path and get the stored id repaired.
 093            info.TryGetTmdbId(out var personTmdbId);
 94
 95            // We don't already have an Id, need to fetch it
 096            if (personTmdbId <= 0)
 97            {
 098                var personSearchResults = await _tmdbClientManager.SearchPersonAsync(info.Name, cancellationToken).Confi
 099                if (personSearchResults?.Count > 0)
 100                {
 0101                    personTmdbId = personSearchResults[0].Id;
 102                }
 103            }
 104
 0105            var result = new MetadataResult<Person>
 0106            {
 0107                ResultLanguage = info.MetadataLanguage
 0108            };
 109
 0110            if (personTmdbId > 0)
 111            {
 0112                var person = await _tmdbClientManager.GetPersonAsync(personTmdbId, info.MetadataLanguage, info.MetadataC
 0113                if (person is null)
 114                {
 0115                    return result;
 116                }
 117
 0118                result.HasMetadata = true;
 119
 0120                var item = new Person
 0121                {
 0122                    // Take name from incoming info, don't rename the person
 0123                    // TODO: This should go in PersonMetadataService, not each person provider
 0124                    Name = info.Name,
 0125                    HomePageUrl = person.Homepage,
 0126                    Overview = person.Biography,
 0127                    PremiereDate = person.Birthday?.ToUniversalTime(),
 0128                    EndDate = person.Deathday?.ToUniversalTime()
 0129                };
 130
 0131                if (!string.IsNullOrWhiteSpace(person.PlaceOfBirth))
 132                {
 0133                    item.ProductionLocations = new[] { person.PlaceOfBirth };
 134                }
 135
 0136                item.SetProviderId(MetadataProvider.Tmdb, person.Id.ToString(CultureInfo.InvariantCulture));
 0137                item.TrySetProviderId(MetadataProvider.Imdb, person.ImdbId);
 138
 0139                result.HasMetadata = true;
 0140                result.Item = item;
 141            }
 142
 0143            return result;
 0144        }
 145
 146        /// <inheritdoc />
 147        public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
 148        {
 0149            return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken);
 150        }
 151    }
 152}