aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormateusbandeiraa <mateus@bandeira.dev>2026-09-27 16:30:53 -0400
committerCody Robibero <cody@robibe.ro>2026-09-27 16:30:53 -0400
commita62c35315c1e95f95d4ec41848cab19898c33347 (patch)
treec9bb646e5a0fab5811c01a23e33aa60fffb1fe94
parente31699cd3eee6d90d12f6308bdb85aecba2a1eaf (diff)
Backport pull request #18150 from jellyfin/release-12.z
Read the image region when determining TMDb image language in `TmdbUtils` Original-merge: 1d3ee4dd5118daeb83f84b155315f5bf957fb5cd Merged-by: crobibero <cody@robibe.ro> Backported-by: Cody Robibero <cody@robibe.ro>
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/TmdbClientManager.cs2
-rw-r--r--MediaBrowser.Providers/Plugins/Tmdb/TmdbUtils.cs37
-rw-r--r--tests/Jellyfin.Providers.Tests/Tmdb/TmdbUtilsTests.cs25
3 files changed, 43 insertions, 21 deletions
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TmdbClientManager.cs b/MediaBrowser.Providers/Plugins/Tmdb/TmdbClientManager.cs
index d75ebae988..8dd1a546fa 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/TmdbClientManager.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/TmdbClientManager.cs
@@ -675,7 +675,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
var image = images[i];
var imageType = type;
- var language = TmdbUtils.AdjustImageLanguage(image.Iso_639_1, requestLanguage);
+ var language = TmdbUtils.GetImageLanguage(image.Iso_639_1, image.Iso_3166_1, requestLanguage);
// Return Backdrops with a language specified (it has text) as Thumb.
if (imageType == ImageType.Backdrop && !string.IsNullOrEmpty(language))
diff --git a/MediaBrowser.Providers/Plugins/Tmdb/TmdbUtils.cs b/MediaBrowser.Providers/Plugins/Tmdb/TmdbUtils.cs
index f004251594..c8db90799d 100644
--- a/MediaBrowser.Providers/Plugins/Tmdb/TmdbUtils.cs
+++ b/MediaBrowser.Providers/Plugins/Tmdb/TmdbUtils.cs
@@ -464,30 +464,41 @@ namespace MediaBrowser.Providers.Plugins.Tmdb
}
/// <summary>
- /// Adjusts the image's language code preferring the 5 letter language code eg. en-US.
+ /// Determines the language code to report for an image.
/// </summary>
- /// <param name="imageLanguage">The image's actual language code.</param>
+ /// <remarks>
+ /// TMDb keeps an image's region in iso_3166_1, which is what separates a pt-PT poster from a pt-BR
+ /// one. The region is added to the returned code only when it differs from the requested one, as in
+ /// a pt-PT image for a pt-BR request. TMDb files nearly every image under a region, so adding it
+ /// unconditionally would return en-US for an image that has to keep matching a plain "en" request.
+ /// </remarks>
+ /// <param name="imageLanguage">The image's ISO 639-1 language code.</param>
+ /// <param name="imageRegion">The image's ISO 3166-1 country code.</param>
/// <param name="requestLanguage">The requested language code.</param>
/// <returns>The language code.</returns>
- public static string AdjustImageLanguage(string? imageLanguage, string requestLanguage)
+ public static string GetImageLanguage(string? imageLanguage, string? imageRegion, string? requestLanguage)
{
- if (string.IsNullOrEmpty(imageLanguage))
+ // TMDb now returns xx for no language instead of an empty string.
+ if (string.IsNullOrEmpty(imageLanguage) || string.Equals(imageLanguage, "xx", StringComparison.OrdinalIgnoreCase))
{
return string.Empty;
}
- if (!string.IsNullOrEmpty(requestLanguage)
- && requestLanguage.Length > 2
- && imageLanguage.Length == 2
- && requestLanguage.StartsWith(imageLanguage, StringComparison.OrdinalIgnoreCase))
+ if (string.IsNullOrEmpty(requestLanguage))
{
- return requestLanguage;
+ return imageLanguage;
}
- // TMDb now returns xx for no language instead of an empty string.
- return string.Equals(imageLanguage, "xx", StringComparison.OrdinalIgnoreCase)
- ? string.Empty
- : imageLanguage;
+ var requestParts = requestLanguage.Split('-');
+
+ if (requestParts.Length != 2 || !string.Equals(requestParts[0], imageLanguage, StringComparison.OrdinalIgnoreCase))
+ {
+ return imageLanguage;
+ }
+
+ return string.IsNullOrEmpty(imageRegion) || string.Equals(imageRegion, requestParts[1], StringComparison.OrdinalIgnoreCase)
+ ? requestLanguage
+ : imageLanguage + "-" + imageRegion.ToUpperInvariant();
}
/// <summary>
diff --git a/tests/Jellyfin.Providers.Tests/Tmdb/TmdbUtilsTests.cs b/tests/Jellyfin.Providers.Tests/Tmdb/TmdbUtilsTests.cs
index 03bad3555e..8342621d97 100644
--- a/tests/Jellyfin.Providers.Tests/Tmdb/TmdbUtilsTests.cs
+++ b/tests/Jellyfin.Providers.Tests/Tmdb/TmdbUtilsTests.cs
@@ -30,14 +30,25 @@ namespace Jellyfin.Providers.Tests.Tmdb
}
[Theory]
- [InlineData("en", "en-US", "en-US")]
- [InlineData("fr-CA", "fr-BE", "fr-CA")]
- [InlineData("fr-CA", "fr", "fr-CA")]
- [InlineData("de", "en-US", "de")]
- [InlineData("", "en-US", "")]
- public static void AdjustImageLanguage_Valid_Success(string imageLanguage, string requestLanguage, string? expected)
+ // A regional request is only answered with a region when the image contradicts it.
+ [InlineData("pt", "BR", "pt-BR", "pt-BR")]
+ [InlineData("pt", "PT", "pt-BR", "pt-PT")]
+ [InlineData("en", "GB", "en-US", "en-GB")]
+ [InlineData("en", "US", "en-US", "en-US")]
+ [InlineData("en", null, "en-US", "en-US")]
+ // TMDb files nearly every image under a region, which must not stop a plain request matching.
+ [InlineData("en", "US", "en", "en")]
+ [InlineData("pt", "PT", "pt", "pt")]
+ // An image in another language keeps its bare code, so the English fallback still resolves.
+ [InlineData("en", "US", "pt-BR", "en")]
+ [InlineData("de", "DE", "en-US", "de")]
+ // TMDb returns xx rather than an empty string for an image with no text.
+ [InlineData("xx", "US", "en-US", "")]
+ [InlineData("", "US", "en-US", "")]
+ [InlineData(null, null, "en-US", "")]
+ public static void GetImageLanguage_Valid_Success(string? imageLanguage, string? imageRegion, string? requestLanguage, string expected)
{
- Assert.Equal(expected, TmdbUtils.AdjustImageLanguage(imageLanguage, requestLanguage));
+ Assert.Equal(expected, TmdbUtils.GetImageLanguage(imageLanguage, imageRegion, requestLanguage));
}
[Theory]