|   |  | 1 |  | using System; | 
|   |  | 2 |  | using System.Collections.Generic; | 
|   |  | 3 |  | using System.Globalization; | 
|   |  | 4 |  | using System.Net.Http; | 
|   |  | 5 |  | using System.Threading; | 
|   |  | 6 |  | using System.Threading.Tasks; | 
|   |  | 7 |  | using MediaBrowser.Common.Net; | 
|   |  | 8 |  | using MediaBrowser.Controller.Entities; | 
|   |  | 9 |  | using MediaBrowser.Controller.Providers; | 
|   |  | 10 |  | using MediaBrowser.Model.Entities; | 
|   |  | 11 |  | using MediaBrowser.Model.Providers; | 
|   |  | 12 |  |  | 
|   |  | 13 |  | namespace 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 |  |         { | 
|   | 21 | 30 |  |             _httpClientFactory = httpClientFactory; | 
|   | 21 | 31 |  |             _tmdbClientManager = tmdbClientManager; | 
|   | 21 | 32 |  |         } | 
|   |  | 33 |  |  | 
|   |  | 34 |  |         /// <inheritdoc /> | 
|   | 0 | 35 |  |         public string Name => TmdbUtils.ProviderName; | 
|   |  | 36 |  |  | 
|   |  | 37 |  |         /// <inheritdoc /> | 
|   |  | 38 |  |         public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(PersonLookupInfo searchInfo, CancellationTok | 
|   |  | 39 |  |         { | 
|   |  | 40 |  |             if (searchInfo.TryGetProviderId(MetadataProvider.Tmdb, out var personTmdbId)) | 
|   |  | 41 |  |             { | 
|   |  | 42 |  |                 var personResult = await _tmdbClientManager.GetPersonAsync(int.Parse(personTmdbId, CultureInfo.Invariant | 
|   |  | 43 |  |  | 
|   |  | 44 |  |                 if (personResult is not null) | 
|   |  | 45 |  |                 { | 
|   |  | 46 |  |                     var result = new RemoteSearchResult | 
|   |  | 47 |  |                     { | 
|   |  | 48 |  |                         Name = personResult.Name, | 
|   |  | 49 |  |                         SearchProviderName = Name, | 
|   |  | 50 |  |                         Overview = personResult.Biography | 
|   |  | 51 |  |                     }; | 
|   |  | 52 |  |  | 
|   |  | 53 |  |                     if (personResult.Images?.Profiles is not null && personResult.Images.Profiles.Count > 0) | 
|   |  | 54 |  |                     { | 
|   |  | 55 |  |                         result.ImageUrl = _tmdbClientManager.GetProfileUrl(personResult.Images.Profiles[0].FilePath); | 
|   |  | 56 |  |                     } | 
|   |  | 57 |  |  | 
|   |  | 58 |  |                     result.SetProviderId(MetadataProvider.Tmdb, personResult.Id.ToString(CultureInfo.InvariantCulture)); | 
|   |  | 59 |  |                     result.TrySetProviderId(MetadataProvider.Imdb, personResult.ExternalIds.ImdbId); | 
|   |  | 60 |  |  | 
|   |  | 61 |  |                     return new[] { result }; | 
|   |  | 62 |  |                 } | 
|   |  | 63 |  |             } | 
|   |  | 64 |  |  | 
|   |  | 65 |  |             var personSearchResult = await _tmdbClientManager.SearchPersonAsync(searchInfo.Name, cancellationToken).Conf | 
|   |  | 66 |  |  | 
|   |  | 67 |  |             var remoteSearchResults = new RemoteSearchResult[personSearchResult.Count]; | 
|   |  | 68 |  |             for (var i = 0; i < personSearchResult.Count; i++) | 
|   |  | 69 |  |             { | 
|   |  | 70 |  |                 var person = personSearchResult[i]; | 
|   |  | 71 |  |                 var remoteSearchResult = new RemoteSearchResult | 
|   |  | 72 |  |                 { | 
|   |  | 73 |  |                     SearchProviderName = Name, | 
|   |  | 74 |  |                     Name = person.Name, | 
|   |  | 75 |  |                     ImageUrl = _tmdbClientManager.GetProfileUrl(person.ProfilePath) | 
|   |  | 76 |  |                 }; | 
|   |  | 77 |  |  | 
|   |  | 78 |  |                 remoteSearchResult.SetProviderId(MetadataProvider.Tmdb, person.Id.ToString(CultureInfo.InvariantCulture) | 
|   |  | 79 |  |                 remoteSearchResults[i] = remoteSearchResult; | 
|   |  | 80 |  |             } | 
|   |  | 81 |  |  | 
|   |  | 82 |  |             return remoteSearchResults; | 
|   |  | 83 |  |         } | 
|   |  | 84 |  |  | 
|   |  | 85 |  |         /// <inheritdoc /> | 
|   |  | 86 |  |         public async Task<MetadataResult<Person>> GetMetadata(PersonLookupInfo info, CancellationToken cancellationToken | 
|   |  | 87 |  |         { | 
|   |  | 88 |  |             var personTmdbId = Convert.ToInt32(info.GetProviderId(MetadataProvider.Tmdb), CultureInfo.InvariantCulture); | 
|   |  | 89 |  |  | 
|   |  | 90 |  |             // We don't already have an Id, need to fetch it | 
|   |  | 91 |  |             if (personTmdbId <= 0) | 
|   |  | 92 |  |             { | 
|   |  | 93 |  |                 var personSearchResults = await _tmdbClientManager.SearchPersonAsync(info.Name, cancellationToken).Confi | 
|   |  | 94 |  |                 if (personSearchResults.Count > 0) | 
|   |  | 95 |  |                 { | 
|   |  | 96 |  |                     personTmdbId = personSearchResults[0].Id; | 
|   |  | 97 |  |                 } | 
|   |  | 98 |  |             } | 
|   |  | 99 |  |  | 
|   |  | 100 |  |             var result = new MetadataResult<Person>(); | 
|   |  | 101 |  |  | 
|   |  | 102 |  |             if (personTmdbId > 0) | 
|   |  | 103 |  |             { | 
|   |  | 104 |  |                 var person = await _tmdbClientManager.GetPersonAsync(personTmdbId, info.MetadataLanguage, info.MetadataC | 
|   |  | 105 |  |                 if (person is null) | 
|   |  | 106 |  |                 { | 
|   |  | 107 |  |                     return result; | 
|   |  | 108 |  |                 } | 
|   |  | 109 |  |  | 
|   |  | 110 |  |                 result.HasMetadata = true; | 
|   |  | 111 |  |  | 
|   |  | 112 |  |                 var item = new Person | 
|   |  | 113 |  |                 { | 
|   |  | 114 |  |                     // Take name from incoming info, don't rename the person | 
|   |  | 115 |  |                     // TODO: This should go in PersonMetadataService, not each person provider | 
|   |  | 116 |  |                     Name = info.Name, | 
|   |  | 117 |  |                     HomePageUrl = person.Homepage, | 
|   |  | 118 |  |                     Overview = person.Biography, | 
|   |  | 119 |  |                     PremiereDate = person.Birthday?.ToUniversalTime(), | 
|   |  | 120 |  |                     EndDate = person.Deathday?.ToUniversalTime() | 
|   |  | 121 |  |                 }; | 
|   |  | 122 |  |  | 
|   |  | 123 |  |                 if (!string.IsNullOrWhiteSpace(person.PlaceOfBirth)) | 
|   |  | 124 |  |                 { | 
|   |  | 125 |  |                     item.ProductionLocations = new[] { person.PlaceOfBirth }; | 
|   |  | 126 |  |                 } | 
|   |  | 127 |  |  | 
|   |  | 128 |  |                 item.SetProviderId(MetadataProvider.Tmdb, person.Id.ToString(CultureInfo.InvariantCulture)); | 
|   |  | 129 |  |                 item.TrySetProviderId(MetadataProvider.Imdb, person.ImdbId); | 
|   |  | 130 |  |  | 
|   |  | 131 |  |                 result.HasMetadata = true; | 
|   |  | 132 |  |                 result.Item = item; | 
|   |  | 133 |  |             } | 
|   |  | 134 |  |  | 
|   |  | 135 |  |             return result; | 
|   |  | 136 |  |         } | 
|   |  | 137 |  |  | 
|   |  | 138 |  |         /// <inheritdoc /> | 
|   |  | 139 |  |         public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken) | 
|   |  | 140 |  |         { | 
|   | 0 | 141 |  |             return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken); | 
|   |  | 142 |  |         } | 
|   |  | 143 |  |     } | 
|   |  | 144 |  | } |