diff --git a/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs b/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs
index 98097477c6..4aff6e3a4f 100644
--- a/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs
+++ b/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
{
///
- /// Determines whether [has provider identifier] [the specified instance].
+ /// Gets a provider id.
///
/// The instance.
- /// The provider.
- /// true if [has provider identifier] [the specified instance]; otherwise, false.
- public static bool HasProviderId(this IHasProviderIds instance, MetadataProvider provider)
+ /// The name.
+ /// The provider id.
+ /// true if a provider id with the given name was found; otherwise false.
+ 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);
}
///
@@ -24,10 +37,11 @@ namespace MediaBrowser.Model.Entities
///
/// The instance.
/// The provider.
- /// System.String.
- public static string? GetProviderId(this IHasProviderIds instance, MetadataProvider provider)
+ /// The provider id.
+ /// true if a provider id with the given name was found; otherwise false.
+ 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);
}
///
@@ -38,18 +52,19 @@ namespace MediaBrowser.Model.Entities
/// System.String.
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;
+ ///
+ /// Gets a provider id.
+ ///
+ /// The instance.
+ /// The provider.
+ /// System.String.
+ public static string? GetProviderId(this IHasProviderIds instance, MetadataProvider provider)
+ {
+ return instance.GetProviderId(provider.ToString());
}
///
@@ -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
{
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs
index f6926d680d..9a3e3d5fad 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs
+++ b/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> 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();
- 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 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> GetMetadata(MovieInfo info, CancellationToken cancellationToken)
diff --git a/tests/Jellyfin.Model.Tests/Entities/ProviderIdsExtensionsTests.cs b/tests/Jellyfin.Model.Tests/Entities/ProviderIdsExtensionsTests.cs
new file mode 100644
index 0000000000..c1a1525bad
--- /dev/null
+++ b/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(() => ProviderIdsExtensions.GetProviderId(null!, MetadataProvider.Imdb));
+ }
+
+ [Fact]
+ public void GetProviderId_NullName_ThrowsArgumentNullException()
+ {
+ Assert.Throws(() => 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(() => 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 ProviderIds { get; set; } = new Dictionary();
+ }
+ }
+}