diff options
| author | Shadowghost <Ghost_of_Stone@web.de> | 2026-05-13 21:23:53 +0200 |
|---|---|---|
| committer | Shadowghost <Ghost_of_Stone@web.de> | 2026-05-13 21:23:53 +0200 |
| commit | b8c0017b7466e5b50a8a32476469b8b6d2215b8c (patch) | |
| tree | b42e75592113faff6cba23254e646561ef00c40f /Emby.Server.Implementations/Localization/LocalizationManager.cs | |
| parent | 95164883c1acb9a48002ae2c8182a7ddb05fb4cb (diff) | |
Build BCP47 map reflexively
Diffstat (limited to 'Emby.Server.Implementations/Localization/LocalizationManager.cs')
| -rw-r--r-- | Emby.Server.Implementations/Localization/LocalizationManager.cs | 48 |
1 files changed, 21 insertions, 27 deletions
diff --git a/Emby.Server.Implementations/Localization/LocalizationManager.cs b/Emby.Server.Implementations/Localization/LocalizationManager.cs index 5c2376ea00..94aa933c92 100644 --- a/Emby.Server.Implementations/Localization/LocalizationManager.cs +++ b/Emby.Server.Implementations/Localization/LocalizationManager.cs @@ -31,15 +31,6 @@ namespace Emby.Server.Implementations.Localization private static readonly Assembly _assembly = typeof(LocalizationManager).Assembly; private static readonly string[] _unratedValues = ["n/a", "unrated", "not rated", "nr"]; - // Maps BCP-47 hyphenated culture codes (set by ASP.NET Core's RequestLocalizationMiddleware - // and used as CurrentUICulture.Name) to Jellyfin's underscore-based resource file codes. - private static readonly FrozenDictionary<string, string> _bcp47ToJellyfinMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) - { - ["es-419"] = "es_419", - ["es-DO"] = "es_DO", - ["ur-PK"] = "ur_PK" - }.ToFrozenDictionary(StringComparer.OrdinalIgnoreCase); - private readonly IServerConfigurationManager _configurationManager; private readonly ILogger<LocalizationManager> _logger; @@ -52,7 +43,13 @@ namespace Emby.Server.Implementations.Localization private readonly ConcurrentDictionary<string, CultureDto?> _cultureCache = new(StringComparer.OrdinalIgnoreCase); private List<CultureDto> _cultures = []; - private static readonly IReadOnlyList<LocalizationOption> _localizationOptions = BuildLocalizationOptions(); + private static readonly (IReadOnlyList<LocalizationOption> Options, FrozenDictionary<string, string> Bcp47ToJellyfinMap) _localizationData = BuildLocalizationData(); + private static readonly IReadOnlyList<LocalizationOption> _localizationOptions = _localizationData.Options; + + // Maps BCP-47 hyphenated culture codes (set by ASP.NET Core's RequestLocalizationMiddleware + // and used as CurrentUICulture.Name) to Jellyfin's underscore-based resource file codes. + // Built reflexively from the resource file scan so both directions stay in sync. + private static readonly FrozenDictionary<string, string> _bcp47ToJellyfinMap = _localizationData.Bcp47ToJellyfinMap; private FrozenDictionary<string, string> _iso6392BtoT = null!; @@ -575,9 +572,10 @@ namespace Emby.Server.Implementations.Localization return _localizationOptions; } - private static IReadOnlyList<LocalizationOption> BuildLocalizationOptions() + private static (IReadOnlyList<LocalizationOption> Options, FrozenDictionary<string, string> Bcp47ToJellyfinMap) BuildLocalizationData() { var options = new List<LocalizationOption>(); + var bcp47Map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); var prefix = CoreResourcePrefix; foreach (var resource in _assembly.GetManifestResourceNames()) @@ -591,6 +589,12 @@ namespace Emby.Server.Implementations.Localization // Extract culture code from resource name: "...Core.de.json" -> "de", "...Core.pt-BR.json" -> "pt-BR" var code = resource[prefix.Length..^5]; + // Record the BCP-47 → Jellyfin mapping for any resource file using underscores. + if (code.Contains('_', StringComparison.Ordinal)) + { + bcp47Map[code.Replace('_', '-')] = code; + } + // Skip the base language file — en-US is added explicitly below if (code.Equals(DefaultCulture, StringComparison.OrdinalIgnoreCase)) { @@ -605,29 +609,19 @@ namespace Emby.Server.Implementations.Localization options.Add(new LocalizationOption("English", DefaultCulture)); options.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase)); - return options; + return (options, bcp47Map.ToFrozenDictionary(StringComparer.OrdinalIgnoreCase)); } private static string GetDisplayName(string cultureCode) { - // Handle Jellyfin-specific codes that aren't valid CultureInfo names - if (_bcp47ToJellyfinMap.Values.Contains(cultureCode)) - { - // Convert underscore to hyphen for CultureInfo lookup - var normalized = cultureCode.Replace('_', '-'); - try - { - return CultureInfo.GetCultureInfo(normalized).NativeName; - } - catch (CultureNotFoundException) - { - return cultureCode; - } - } + // Resource files use underscores for codes that .NET's CultureInfo doesn't accept directly (e.g. es_419). + var lookup = cultureCode.Contains('_', StringComparison.Ordinal) + ? cultureCode.Replace('_', '-') + : cultureCode; try { - return CultureInfo.GetCultureInfo(cultureCode).NativeName; + return CultureInfo.GetCultureInfo(lookup).NativeName; } catch (CultureNotFoundException) { |
