< 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: 61
Coverable lines: 64
Total lines: 148
Line coverage: 4.6%
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 1/23/2026 - 12:11:06 AM Line coverage: 60% (3/5) Total lines: 1442/19/2026 - 12:13:41 AM Line coverage: 60% (3/5) Total lines: 1484/19/2026 - 12:14:27 AM Line coverage: 4.6% (3/64) Branch coverage: 0% (0/32) Total lines: 148 4/19/2026 - 12:14:27 AM Line coverage: 4.6% (3/64) Branch coverage: 0% (0/32) Total lines: 148

Coverage delta

Coverage delta 56 -56

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;
 2using System.Collections.Generic;
 3using System.Globalization;
 4using System.Net.Http;
 5using System.Threading;
 6using System.Threading.Tasks;
 7using MediaBrowser.Common.Net;
 8using MediaBrowser.Controller.Entities;
 9using MediaBrowser.Controller.Providers;
 10using MediaBrowser.Model.Entities;
 11using MediaBrowser.Model.Providers;
 12
 13namespace MediaBrowser.Providers.Plugins.Tmdb.People
 14{
 15    /// <summary>
 16    /// Person image provider powered by TMDb.
 17    /// </summary>
 18    public class TmdbPersonProvider : IRemoteMetadataProvider<Person, PersonLookupInfo>
 19    {
 20        private readonly IHttpClientFactory _httpClientFactory;
 21        private readonly TmdbClientManager _tmdbClientManager;
 22
 23        /// <summary>
 24        /// Initializes a new instance of the <see cref="TmdbPersonProvider"/> class.
 25        /// </summary>
 26        /// <param name="httpClientFactory">The <see cref="IHttpClientFactory"/>.</param>
 27        /// <param name="tmdbClientManager">The <see cref="TmdbClientManager"/>.</param>
 28        public TmdbPersonProvider(IHttpClientFactory httpClientFactory, TmdbClientManager tmdbClientManager)
 29        {
 2130            _httpClientFactory = httpClientFactory;
 2131            _tmdbClientManager = tmdbClientManager;
 2132        }
 33
 34        /// <inheritdoc />
 035        public string Name => TmdbUtils.ProviderName;
 36
 37        /// <inheritdoc />
 38        public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(PersonLookupInfo searchInfo, CancellationTok
 39        {
 040            if (searchInfo.TryGetProviderId(MetadataProvider.Tmdb, out var personTmdbId))
 41            {
 042                var personResult = await _tmdbClientManager.GetPersonAsync(int.Parse(personTmdbId, CultureInfo.Invariant
 43
 044                if (personResult is not null)
 45                {
 046                    var result = new RemoteSearchResult
 047                    {
 048                        Name = personResult.Name,
 049                        SearchProviderName = Name,
 050                        Overview = personResult.Biography
 051                    };
 52
 053                    if (personResult.Images?.Profiles is not null && personResult.Images.Profiles.Count > 0)
 54                    {
 055                        result.ImageUrl = _tmdbClientManager.GetProfileUrl(personResult.Images.Profiles[0].FilePath);
 56                    }
 57
 058                    result.SetProviderId(MetadataProvider.Tmdb, personResult.Id.ToString(CultureInfo.InvariantCulture));
 059                    result.TrySetProviderId(MetadataProvider.Imdb, personResult.ExternalIds?.ImdbId);
 60
 061                    return [result];
 62                }
 63            }
 64
 065            var personSearchResult = await _tmdbClientManager.SearchPersonAsync(searchInfo.Name, cancellationToken).Conf
 066            if (personSearchResult is null)
 67            {
 068                return [];
 69            }
 70
 071            var remoteSearchResults = new RemoteSearchResult[personSearchResult.Count];
 072            for (var i = 0; i < personSearchResult.Count; i++)
 73            {
 074                var person = personSearchResult[i];
 075                var remoteSearchResult = new RemoteSearchResult
 076                {
 077                    SearchProviderName = Name,
 078                    Name = person.Name,
 079                    ImageUrl = _tmdbClientManager.GetProfileUrl(person.ProfilePath)
 080                };
 81
 082                remoteSearchResult.SetProviderId(MetadataProvider.Tmdb, person.Id.ToString(CultureInfo.InvariantCulture)
 083                remoteSearchResults[i] = remoteSearchResult;
 84            }
 85
 086            return remoteSearchResults;
 087        }
 88
 89        /// <inheritdoc />
 90        public async Task<MetadataResult<Person>> GetMetadata(PersonLookupInfo info, CancellationToken cancellationToken
 91        {
 092            var personTmdbId = Convert.ToInt32(info.GetProviderId(MetadataProvider.Tmdb), CultureInfo.InvariantCulture);
 93
 94            // We don't already have an Id, need to fetch it
 095            if (personTmdbId <= 0)
 96            {
 097                var personSearchResults = await _tmdbClientManager.SearchPersonAsync(info.Name, cancellationToken).Confi
 098                if (personSearchResults?.Count > 0)
 99                {
 0100                    personTmdbId = personSearchResults[0].Id;
 101                }
 102            }
 103
 0104            var result = new MetadataResult<Person>();
 105
 0106            if (personTmdbId > 0)
 107            {
 0108                var person = await _tmdbClientManager.GetPersonAsync(personTmdbId, info.MetadataLanguage, info.MetadataC
 0109                if (person is null)
 110                {
 0111                    return result;
 112                }
 113
 0114                result.HasMetadata = true;
 115
 0116                var item = new Person
 0117                {
 0118                    // Take name from incoming info, don't rename the person
 0119                    // TODO: This should go in PersonMetadataService, not each person provider
 0120                    Name = info.Name,
 0121                    HomePageUrl = person.Homepage,
 0122                    Overview = person.Biography,
 0123                    PremiereDate = person.Birthday?.ToUniversalTime(),
 0124                    EndDate = person.Deathday?.ToUniversalTime()
 0125                };
 126
 0127                if (!string.IsNullOrWhiteSpace(person.PlaceOfBirth))
 128                {
 0129                    item.ProductionLocations = new[] { person.PlaceOfBirth };
 130                }
 131
 0132                item.SetProviderId(MetadataProvider.Tmdb, person.Id.ToString(CultureInfo.InvariantCulture));
 0133                item.TrySetProviderId(MetadataProvider.Imdb, person.ImdbId);
 134
 0135                result.HasMetadata = true;
 0136                result.Item = item;
 137            }
 138
 0139            return result;
 0140        }
 141
 142        /// <inheritdoc />
 143        public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
 144        {
 0145            return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken);
 146        }
 147    }
 148}