Explorar o código

Merge pull request #5270 from Bond-009/imdb

Joshua M. Boniface %!s(int64=4) %!d(string=hai) anos
pai
achega
5ce4df4178

+ 35 - 26
MediaBrowser.Model/Entities/ProviderIdsExtensions.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 
 namespace MediaBrowser.Model.Entities
 {
@@ -9,14 +10,26 @@ namespace MediaBrowser.Model.Entities
     public static class ProviderIdsExtensions
     {
         /// <summary>
-        /// Determines whether [has provider identifier] [the specified instance].
+        /// Gets a provider id.
         /// </summary>
         /// <param name="instance">The instance.</param>
-        /// <param name="provider">The provider.</param>
-        /// <returns><c>true</c> if [has provider identifier] [the specified instance]; otherwise, <c>false</c>.</returns>
-        public static bool HasProviderId(this IHasProviderIds instance, MetadataProvider provider)
+        /// <param name="name">The name.</param>
+        /// <param name="id">The provider id.</param>
+        /// <returns><c>true</c> if a provider id with the given name was found; otherwise <c>false</c>.</returns>
+        public static bool TryGetProviderId(this IHasProviderIds instance, string name, [MaybeNullWhen(false)] out string id)
         {
-            return !string.IsNullOrEmpty(instance.GetProviderId(provider.ToString()));
+            if (instance == null)
+            {
+                throw new ArgumentNullException(nameof(instance));
+            }
+
+            if (instance.ProviderIds == null)
+            {
+                id = null;
+                return false;
+            }
+
+            return instance.ProviderIds.TryGetValue(name, out id);
         }
 
         /// <summary>
@@ -24,10 +37,11 @@ namespace MediaBrowser.Model.Entities
         /// </summary>
         /// <param name="instance">The instance.</param>
         /// <param name="provider">The provider.</param>
-        /// <returns>System.String.</returns>
-        public static string? GetProviderId(this IHasProviderIds instance, MetadataProvider provider)
+        /// <param name="id">The provider id.</param>
+        /// <returns><c>true</c> if a provider id with the given name was found; otherwise <c>false</c>.</returns>
+        public static bool TryGetProviderId(this IHasProviderIds instance, MetadataProvider provider, [MaybeNullWhen(false)] out string id)
         {
-            return instance.GetProviderId(provider.ToString());
+            return instance.TryGetProviderId(provider.ToString(), out id);
         }
 
         /// <summary>
@@ -38,18 +52,19 @@ namespace MediaBrowser.Model.Entities
         /// <returns>System.String.</returns>
         public static string? GetProviderId(this IHasProviderIds instance, string name)
         {
-            if (instance == null)
-            {
-                throw new ArgumentNullException(nameof(instance));
-            }
-
-            if (instance.ProviderIds == null)
-            {
-                return null;
-            }
+            instance.TryGetProviderId(name, out string? id);
+            return id;
+        }
 
-            instance.ProviderIds.TryGetValue(name, out string? id);
-            return string.IsNullOrEmpty(id) ? null : id;
+        /// <summary>
+        /// Gets a provider id.
+        /// </summary>
+        /// <param name="instance">The instance.</param>
+        /// <param name="provider">The provider.</param>
+        /// <returns>System.String.</returns>
+        public static string? GetProviderId(this IHasProviderIds instance, MetadataProvider provider)
+        {
+            return instance.GetProviderId(provider.ToString());
         }
 
         /// <summary>
@@ -68,13 +83,7 @@ namespace MediaBrowser.Model.Entities
             // If it's null remove the key from the dictionary
             if (string.IsNullOrEmpty(value))
             {
-                if (instance.ProviderIds != null)
-                {
-                    if (instance.ProviderIds.ContainsKey(name))
-                    {
-                        instance.ProviderIds.Remove(name);
-                    }
-                }
+                instance.ProviderIds?.Remove(name);
             }
             else
             {

+ 68 - 41
MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs

@@ -7,6 +7,8 @@ using System.Linq;
 using System.Net.Http;
 using System.Threading;
 using System.Threading.Tasks;
+using TMDbLib.Objects.Find;
+using TMDbLib.Objects.Search;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Movies;
@@ -43,64 +45,89 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
 
         public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(MovieInfo searchInfo, CancellationToken cancellationToken)
         {
-            var tmdbId = Convert.ToInt32(searchInfo.GetProviderId(MetadataProvider.Tmdb), CultureInfo.InvariantCulture);
-
-            if (tmdbId == 0)
+            if (searchInfo.TryGetProviderId(MetadataProvider.Tmdb, out var id))
             {
-                var movieResults = await _tmdbClientManager
-                    .SearchMovieAsync(searchInfo.Name, searchInfo.Year ?? 0, searchInfo.MetadataLanguage, cancellationToken)
+                var movie = await _tmdbClientManager
+                    .GetMovieAsync(
+                        int.Parse(id, CultureInfo.InvariantCulture),
+                        searchInfo.MetadataLanguage,
+                        TmdbUtils.GetImageLanguagesParam(searchInfo.MetadataLanguage),
+                        cancellationToken)
                     .ConfigureAwait(false);
 
-                var remoteSearchResults = new List<RemoteSearchResult>();
-                for (var i = 0; i < movieResults.Count; i++)
+                var remoteResult = new RemoteSearchResult
                 {
-                    var movieResult = movieResults[i];
-                    var remoteSearchResult = new RemoteSearchResult
-                    {
-                        Name = movieResult.Title ?? movieResult.OriginalTitle,
-                        ImageUrl = _tmdbClientManager.GetPosterUrl(movieResult.PosterPath),
-                        Overview = movieResult.Overview,
-                        SearchProviderName = Name
-                    };
+                    Name = movie.Title ?? movie.OriginalTitle,
+                    SearchProviderName = Name,
+                    ImageUrl = _tmdbClientManager.GetPosterUrl(movie.PosterPath),
+                    Overview = movie.Overview
+                };
+
+                if (movie.ReleaseDate != null)
+                {
+                    var releaseDate = movie.ReleaseDate.Value.ToUniversalTime();
+                    remoteResult.PremiereDate = releaseDate;
+                    remoteResult.ProductionYear = releaseDate.Year;
+                }
 
-                    var releaseDate = movieResult.ReleaseDate?.ToUniversalTime();
-                    remoteSearchResult.PremiereDate = releaseDate;
-                    remoteSearchResult.ProductionYear = releaseDate?.Year;
+                remoteResult.SetProviderId(MetadataProvider.Tmdb, movie.Id.ToString(CultureInfo.InvariantCulture));
 
-                    remoteSearchResult.SetProviderId(MetadataProvider.Tmdb, movieResult.Id.ToString(CultureInfo.InvariantCulture));
-                    remoteSearchResults.Add(remoteSearchResult);
+                if (!string.IsNullOrWhiteSpace(movie.ImdbId))
+                {
+                    remoteResult.SetProviderId(MetadataProvider.Imdb, movie.ImdbId);
                 }
 
-                return remoteSearchResults;
+                return new[] { remoteResult };
             }
 
-            var movie = await _tmdbClientManager
-                .GetMovieAsync(tmdbId, searchInfo.MetadataLanguage, TmdbUtils.GetImageLanguagesParam(searchInfo.MetadataLanguage), cancellationToken)
-                .ConfigureAwait(false);
-
-            var remoteResult = new RemoteSearchResult
+            IReadOnlyList<SearchMovie> movieResults;
+            if (searchInfo.TryGetProviderId(MetadataProvider.Imdb, out id))
             {
-                Name = movie.Title ?? movie.OriginalTitle,
-                SearchProviderName = Name,
-                ImageUrl = _tmdbClientManager.GetPosterUrl(movie.PosterPath),
-                Overview = movie.Overview
-            };
-
-            if (movie.ReleaseDate != null)
+                var result = await _tmdbClientManager.FindByExternalIdAsync(
+                    id,
+                    FindExternalSource.Imdb,
+                    TmdbUtils.GetImageLanguagesParam(searchInfo.MetadataLanguage),
+                    cancellationToken).ConfigureAwait(false);
+                movieResults = result.MovieResults;
+            }
+            else if (searchInfo.TryGetProviderId(MetadataProvider.Tvdb, out id))
             {
-                var releaseDate = movie.ReleaseDate.Value.ToUniversalTime();
-                remoteResult.PremiereDate = releaseDate;
-                remoteResult.ProductionYear = releaseDate.Year;
+                var result = await _tmdbClientManager.FindByExternalIdAsync(
+                    id,
+                    FindExternalSource.TvDb,
+                    TmdbUtils.GetImageLanguagesParam(searchInfo.MetadataLanguage),
+                    cancellationToken).ConfigureAwait(false);
+                movieResults = result.MovieResults;
+            }
+            else
+            {
+                movieResults = await _tmdbClientManager
+                    .SearchMovieAsync(searchInfo.Name, searchInfo.Year ?? 0, searchInfo.MetadataLanguage, cancellationToken)
+                    .ConfigureAwait(false);
             }
 
-            remoteResult.SetProviderId(MetadataProvider.Tmdb, movie.Id.ToString(CultureInfo.InvariantCulture));
-
-            if (!string.IsNullOrWhiteSpace(movie.ImdbId))
+            var len = movieResults.Count;
+            var remoteSearchResults = new RemoteSearchResult[len];
+            for (var i = 0; i < len; i++)
             {
-                remoteResult.SetProviderId(MetadataProvider.Imdb, movie.ImdbId);
+                var movieResult = movieResults[i];
+                var remoteSearchResult = new RemoteSearchResult
+                {
+                    Name = movieResult.Title ?? movieResult.OriginalTitle,
+                    ImageUrl = _tmdbClientManager.GetPosterUrl(movieResult.PosterPath),
+                    Overview = movieResult.Overview,
+                    SearchProviderName = Name
+                };
+
+                var releaseDate = movieResult.ReleaseDate?.ToUniversalTime();
+                remoteSearchResult.PremiereDate = releaseDate;
+                remoteSearchResult.ProductionYear = releaseDate?.Year;
+
+                remoteSearchResult.SetProviderId(MetadataProvider.Tmdb, movieResult.Id.ToString(CultureInfo.InvariantCulture));
+                remoteSearchResults[i] = remoteSearchResult;
             }
 
-            return new[] { remoteResult };
+            return remoteSearchResults;
         }
 
         public async Task<MetadataResult<Movie>> GetMetadata(MovieInfo info, CancellationToken cancellationToken)

+ 139 - 0
tests/Jellyfin.Model.Tests/Entities/ProviderIdsExtensionsTests.cs

@@ -0,0 +1,139 @@
+using System;
+using System.Collections.Generic;
+using MediaBrowser.Model.Entities;
+using Xunit;
+
+namespace Jellyfin.Model.Tests.Entities
+{
+    public class ProviderIdsExtensionsTests
+    {
+        private const string ExampleImdbId = "tt0113375";
+
+        [Fact]
+        public void GetProviderId_NullInstance_ThrowsArgumentNullException()
+        {
+            Assert.Throws<ArgumentNullException>(() => ProviderIdsExtensions.GetProviderId(null!, MetadataProvider.Imdb));
+        }
+
+        [Fact]
+        public void GetProviderId_NullName_ThrowsArgumentNullException()
+        {
+            Assert.Throws<ArgumentNullException>(() => ProviderIdsExtensionsTestsObject.Empty.GetProviderId(null!));
+        }
+
+        [Fact]
+        public void GetProviderId_NotFoundName_Null()
+        {
+            Assert.Null(ProviderIdsExtensionsTestsObject.Empty.GetProviderId(MetadataProvider.Imdb));
+        }
+
+        [Fact]
+        public void GetProviderId_NullProvider_Null()
+        {
+            var nullProvider = new ProviderIdsExtensionsTestsObject()
+            {
+                ProviderIds = null!
+            };
+
+            Assert.Null(nullProvider.GetProviderId(MetadataProvider.Imdb));
+        }
+
+        [Fact]
+        public void TryGetProviderId_NotFoundName_False()
+        {
+            Assert.False(ProviderIdsExtensionsTestsObject.Empty.TryGetProviderId(MetadataProvider.Imdb, out _));
+        }
+
+        [Fact]
+        public void TryGetProviderId_NullProvider_False()
+        {
+            var nullProvider = new ProviderIdsExtensionsTestsObject()
+            {
+                ProviderIds = null!
+            };
+
+            Assert.False(nullProvider.TryGetProviderId(MetadataProvider.Imdb, out _));
+        }
+
+        [Fact]
+        public void GetProviderId_FoundName_Id()
+        {
+            var provider = new ProviderIdsExtensionsTestsObject();
+            provider.ProviderIds[MetadataProvider.Imdb.ToString()] = ExampleImdbId;
+
+            Assert.Equal(ExampleImdbId, provider.GetProviderId(MetadataProvider.Imdb));
+        }
+
+        [Fact]
+        public void TryGetProviderId_FoundName_True()
+        {
+            var provider = new ProviderIdsExtensionsTestsObject();
+            provider.ProviderIds[MetadataProvider.Imdb.ToString()] = ExampleImdbId;
+
+            Assert.True(provider.TryGetProviderId(MetadataProvider.Imdb, out var id));
+            Assert.Equal(ExampleImdbId, id);
+        }
+
+        [Fact]
+        public void SetProviderId_NullInstance_ThrowsArgumentNullException()
+        {
+            Assert.Throws<ArgumentNullException>(() => ProviderIdsExtensions.SetProviderId(null!, MetadataProvider.Imdb, ExampleImdbId));
+        }
+
+        [Fact]
+        public void SetProviderId_Null_Remove()
+        {
+            var provider = new ProviderIdsExtensionsTestsObject();
+            provider.SetProviderId(MetadataProvider.Imdb, null!);
+            Assert.Empty(provider.ProviderIds);
+        }
+
+        [Fact]
+        public void SetProviderId_EmptyName_Remove()
+        {
+            var provider = new ProviderIdsExtensionsTestsObject();
+            provider.ProviderIds[MetadataProvider.Imdb.ToString()] = ExampleImdbId;
+            provider.SetProviderId(MetadataProvider.Imdb, string.Empty);
+            Assert.Empty(provider.ProviderIds);
+        }
+
+        [Fact]
+        public void SetProviderId_NonEmptyId_Success()
+        {
+            var provider = new ProviderIdsExtensionsTestsObject();
+            provider.SetProviderId(MetadataProvider.Imdb, ExampleImdbId);
+            Assert.Single(provider.ProviderIds);
+        }
+
+        [Fact]
+        public void SetProviderId_NullProvider_Success()
+        {
+            var nullProvider = new ProviderIdsExtensionsTestsObject()
+            {
+                ProviderIds = null!
+            };
+
+            nullProvider.SetProviderId(MetadataProvider.Imdb, ExampleImdbId);
+            Assert.Single(nullProvider.ProviderIds);
+        }
+
+        [Fact]
+        public void SetProviderId_NullProviderAndEmptyName_Success()
+        {
+            var nullProvider = new ProviderIdsExtensionsTestsObject()
+            {
+                ProviderIds = null!
+            };
+
+            nullProvider.SetProviderId(MetadataProvider.Imdb, string.Empty);
+            Assert.Null(nullProvider.ProviderIds);
+        }
+
+        private class ProviderIdsExtensionsTestsObject : IHasProviderIds
+        {
+            public static readonly ProviderIdsExtensionsTestsObject Empty = new ProviderIdsExtensionsTestsObject();
+
+            public Dictionary<string, string> ProviderIds { get; set; } = new Dictionary<string, string>();
+        }
+    }
+}