Explorar o código

Merge pull request #1632 from Bond-009/locale

Improve LocalizationManager
Anthony Lavado %!s(int64=5) %!d(string=hai) anos
pai
achega
7a27dd8a1b

+ 1 - 1
Emby.Server.Implementations/ApplicationHost.cs

@@ -746,7 +746,7 @@ namespace Emby.Server.Implementations
 
             serviceCollection.AddSingleton(ServerConfigurationManager);
 
-            LocalizationManager = new LocalizationManager(ServerConfigurationManager, JsonSerializer, LoggerFactory);
+            LocalizationManager = new LocalizationManager(ServerConfigurationManager, JsonSerializer, LoggerFactory.CreateLogger<LocalizationManager>());
             await LocalizationManager.LoadAll().ConfigureAwait(false);
             serviceCollection.AddSingleton<ILocalizationManager>(LocalizationManager);
 

+ 80 - 91
Emby.Server.Implementations/Localization/LocalizationManager.cs

@@ -17,43 +17,49 @@ using Microsoft.Extensions.Logging;
 namespace Emby.Server.Implementations.Localization
 {
     /// <summary>
-    /// Class LocalizationManager
+    /// Class LocalizationManager.
     /// </summary>
     public class LocalizationManager : ILocalizationManager
     {
-        /// <summary>
-        /// The _configuration manager
-        /// </summary>
-        private readonly IServerConfigurationManager _configurationManager;
+        private const string DefaultCulture = "en-US";
+        private static readonly Assembly _assembly = typeof(LocalizationManager).Assembly;
+        private static readonly string[] _unratedValues = { "n/a", "unrated", "not rated" };
 
         /// <summary>
-        /// The us culture
+        /// The _configuration manager.
         /// </summary>
-        private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
+        private readonly IServerConfigurationManager _configurationManager;
+        private readonly IJsonSerializer _jsonSerializer;
+        private readonly ILogger _logger;
 
         private readonly Dictionary<string, Dictionary<string, ParentalRating>> _allParentalRatings =
             new Dictionary<string, Dictionary<string, ParentalRating>>(StringComparer.OrdinalIgnoreCase);
 
-        private readonly IJsonSerializer _jsonSerializer;
-        private readonly ILogger _logger;
-        private static readonly Assembly _assembly = typeof(LocalizationManager).Assembly;
+        private readonly ConcurrentDictionary<string, Dictionary<string, string>> _dictionaries =
+            new ConcurrentDictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
+
+        private List<CultureDto> _cultures;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="LocalizationManager" /> class.
         /// </summary>
         /// <param name="configurationManager">The configuration manager.</param>
         /// <param name="jsonSerializer">The json serializer.</param>
-        /// <param name="loggerFactory">The logger factory</param>
+        /// <param name="logger">The logger.</param>
         public LocalizationManager(
             IServerConfigurationManager configurationManager,
             IJsonSerializer jsonSerializer,
-            ILoggerFactory loggerFactory)
+            ILogger<LocalizationManager> logger)
         {
             _configurationManager = configurationManager;
             _jsonSerializer = jsonSerializer;
-            _logger = loggerFactory.CreateLogger(nameof(LocalizationManager));
+            _logger = logger;
         }
 
+        /// <summary>
+        /// Loads all resources into memory.
+        /// </summary>
+        /// <returns><see cref="Task" />.</returns>
         public async Task LoadAll()
         {
             const string RatingsResource = "Emby.Server.Implementations.Localization.Ratings.";
@@ -82,9 +88,10 @@ namespace Emby.Server.Implementations.Localization
 
                         string[] parts = line.Split(',');
                         if (parts.Length == 2
-                            && int.TryParse(parts[1], NumberStyles.Integer, UsCulture, out var value))
+                            && int.TryParse(parts[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var value))
                         {
-                            dict.Add(parts[0], new ParentalRating { Name = parts[0], Value = value });
+                            var name = parts[0];
+                            dict.Add(name, new ParentalRating(name, value));
                         }
 #if DEBUG
                         else
@@ -101,16 +108,11 @@ namespace Emby.Server.Implementations.Localization
             await LoadCultures().ConfigureAwait(false);
         }
 
-        public string NormalizeFormKD(string text)
-            => text.Normalize(NormalizationForm.FormKD);
-
-        private CultureDto[] _cultures;
-
         /// <summary>
         /// Gets the cultures.
         /// </summary>
-        /// <returns>IEnumerable{CultureDto}.</returns>
-        public CultureDto[] GetCultures()
+        /// <returns><see cref="IEnumerable{CultureDto}" />.</returns>
+        public IEnumerable<CultureDto> GetCultures()
             => _cultures;
 
         private async Task LoadCultures()
@@ -168,9 +170,10 @@ namespace Emby.Server.Implementations.Localization
                 }
             }
 
-            _cultures = list.ToArray();
+            _cultures = list;
         }
 
+        /// <inheritdoc />
         public CultureDto FindLanguageInfo(string language)
             => GetCultures()
                 .FirstOrDefault(i =>
@@ -179,25 +182,19 @@ namespace Emby.Server.Implementations.Localization
                     || i.ThreeLetterISOLanguageNames.Contains(language, StringComparer.OrdinalIgnoreCase)
                     || string.Equals(i.TwoLetterISOLanguageName, language, StringComparison.OrdinalIgnoreCase));
 
-        /// <summary>
-        /// Gets the countries.
-        /// </summary>
-        /// <returns>IEnumerable{CountryInfo}.</returns>
-        public Task<CountryInfo[]> GetCountries()
-            => _jsonSerializer.DeserializeFromStreamAsync<CountryInfo[]>(
+        /// <inheritdoc />
+        public IEnumerable<CountryInfo> GetCountries()
+            => _jsonSerializer.DeserializeFromStream<IEnumerable<CountryInfo>>(
                     _assembly.GetManifestResourceStream("Emby.Server.Implementations.Localization.countries.json"));
 
-        /// <summary>
-        /// Gets the parental ratings.
-        /// </summary>
-        /// <returns>IEnumerable{ParentalRating}.</returns>
+        /// <inheritdoc />
         public IEnumerable<ParentalRating> GetParentalRatings()
             => GetParentalRatingsDictionary().Values;
 
         /// <summary>
         /// Gets the parental ratings dictionary.
         /// </summary>
-        /// <returns>Dictionary{System.StringParentalRating}.</returns>
+        /// <returns><see cref="Dictionary{String, ParentalRating}" />.</returns>
         private Dictionary<string, ParentalRating> GetParentalRatingsDictionary()
         {
             var countryCode = _configurationManager.Configuration.MetadataCountryCode;
@@ -207,14 +204,14 @@ namespace Emby.Server.Implementations.Localization
                 countryCode = "us";
             }
 
-           return GetRatings(countryCode) ?? GetRatings("us");
+            return GetRatings(countryCode) ?? GetRatings("us");
         }
 
         /// <summary>
         /// Gets the ratings.
         /// </summary>
         /// <param name="countryCode">The country code.</param>
-        /// <returns>The ratings</returns>
+        /// <returns>The ratings.</returns>
         private Dictionary<string, ParentalRating> GetRatings(string countryCode)
         {
             _allParentalRatings.TryGetValue(countryCode, out var value);
@@ -222,14 +219,7 @@ namespace Emby.Server.Implementations.Localization
             return value;
         }
 
-        private static readonly string[] _unratedValues = { "n/a", "unrated", "not rated" };
-
         /// <inheritdoc />
-        /// <summary>
-        /// Gets the rating level.
-        /// </summary>
-        /// <param name="rating">Rating field</param>
-        /// <returns>The rating level</returns>&gt;
         public int? GetRatingLevel(string rating)
         {
             if (string.IsNullOrEmpty(rating))
@@ -277,6 +267,7 @@ namespace Emby.Server.Implementations.Localization
             return null;
         }
 
+        /// <inheritdoc />
         public bool HasUnicodeCategory(string value, UnicodeCategory category)
         {
             foreach (var chr in value)
@@ -290,11 +281,13 @@ namespace Emby.Server.Implementations.Localization
             return false;
         }
 
+        /// <inheritdoc />
         public string GetLocalizedString(string phrase)
         {
             return GetLocalizedString(phrase, _configurationManager.Configuration.UICulture);
         }
 
+        /// <inheritdoc />
         public string GetLocalizedString(string phrase, string culture)
         {
             if (string.IsNullOrEmpty(culture))
@@ -317,12 +310,7 @@ namespace Emby.Server.Implementations.Localization
             return phrase;
         }
 
-        private const string DefaultCulture = "en-US";
-
-        private readonly ConcurrentDictionary<string, Dictionary<string, string>> _dictionaries =
-            new ConcurrentDictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
-
-        public Dictionary<string, string> GetLocalizationDictionary(string culture)
+        private Dictionary<string, string> GetLocalizationDictionary(string culture)
         {
             if (string.IsNullOrEmpty(culture))
             {
@@ -332,8 +320,9 @@ namespace Emby.Server.Implementations.Localization
             const string prefix = "Core";
             var key = prefix + culture;
 
-            return _dictionaries.GetOrAdd(key,
-                    f => GetDictionary(prefix, culture, DefaultCulture + ".json").GetAwaiter().GetResult());
+            return _dictionaries.GetOrAdd(
+                key,
+                f => GetDictionary(prefix, culture, DefaultCulture + ".json").GetAwaiter().GetResult());
         }
 
         private async Task<Dictionary<string, string>> GetDictionary(string prefix, string culture, string baseFilename)
@@ -390,45 +379,45 @@ namespace Emby.Server.Implementations.Localization
             return culture + ".json";
         }
 
-        public LocalizationOption[] GetLocalizationOptions()
-            => new LocalizationOption[]
-            {
-                new LocalizationOption("Arabic", "ar"),
-                new LocalizationOption("Bulgarian (Bulgaria)", "bg-BG"),
-                new LocalizationOption("Catalan", "ca"),
-                new LocalizationOption("Chinese Simplified", "zh-CN"),
-                new LocalizationOption("Chinese Traditional", "zh-TW"),
-                new LocalizationOption("Croatian", "hr"),
-                new LocalizationOption("Czech", "cs"),
-                new LocalizationOption("Danish", "da"),
-                new LocalizationOption("Dutch", "nl"),
-                new LocalizationOption("English (United Kingdom)", "en-GB"),
-                new LocalizationOption("English (United States)", "en-US"),
-                new LocalizationOption("French", "fr"),
-                new LocalizationOption("French (Canada)", "fr-CA"),
-                new LocalizationOption("German", "de"),
-                new LocalizationOption("Greek", "el"),
-                new LocalizationOption("Hebrew", "he"),
-                new LocalizationOption("Hungarian", "hu"),
-                new LocalizationOption("Italian", "it"),
-                new LocalizationOption("Kazakh", "kk"),
-                new LocalizationOption("Korean", "ko"),
-                new LocalizationOption("Lithuanian", "lt-LT"),
-                new LocalizationOption("Malay", "ms"),
-                new LocalizationOption("Norwegian Bokmål", "nb"),
-                new LocalizationOption("Persian", "fa"),
-                new LocalizationOption("Polish", "pl"),
-                new LocalizationOption("Portuguese (Brazil)", "pt-BR"),
-                new LocalizationOption("Portuguese (Portugal)", "pt-PT"),
-                new LocalizationOption("Russian", "ru"),
-                new LocalizationOption("Slovak", "sk"),
-                new LocalizationOption("Slovenian (Slovenia)", "sl-SI"),
-                new LocalizationOption("Spanish", "es"),
-                new LocalizationOption("Spanish (Argentina)", "es-AR"),
-                new LocalizationOption("Spanish (Mexico)", "es-MX"),
-                new LocalizationOption("Swedish", "sv"),
-                new LocalizationOption("Swiss German", "gsw"),
-                new LocalizationOption("Turkish", "tr")
-            };
+        /// <inheritdoc />
+        public IEnumerable<LocalizationOption> GetLocalizationOptions()
+        {
+            yield return new LocalizationOption("Arabic", "ar");
+            yield return new LocalizationOption("Bulgarian (Bulgaria)", "bg-BG");
+            yield return new LocalizationOption("Catalan", "ca");
+            yield return new LocalizationOption("Chinese Simplified", "zh-CN");
+            yield return new LocalizationOption("Chinese Traditional", "zh-TW");
+            yield return new LocalizationOption("Croatian", "hr");
+            yield return new LocalizationOption("Czech", "cs");
+            yield return new LocalizationOption("Danish", "da");
+            yield return new LocalizationOption("Dutch", "nl");
+            yield return new LocalizationOption("English (United Kingdom)", "en-GB");
+            yield return new LocalizationOption("English (United States)", "en-US");
+            yield return new LocalizationOption("French", "fr");
+            yield return new LocalizationOption("French (Canada)", "fr-CA");
+            yield return new LocalizationOption("German", "de");
+            yield return new LocalizationOption("Greek", "el");
+            yield return new LocalizationOption("Hebrew", "he");
+            yield return new LocalizationOption("Hungarian", "hu");
+            yield return new LocalizationOption("Italian", "it");
+            yield return new LocalizationOption("Kazakh", "kk");
+            yield return new LocalizationOption("Korean", "ko");
+            yield return new LocalizationOption("Lithuanian", "lt-LT");
+            yield return new LocalizationOption("Malay", "ms");
+            yield return new LocalizationOption("Norwegian Bokmål", "nb");
+            yield return new LocalizationOption("Persian", "fa");
+            yield return new LocalizationOption("Polish", "pl");
+            yield return new LocalizationOption("Portuguese (Brazil)", "pt-BR");
+            yield return new LocalizationOption("Portuguese (Portugal)", "pt-PT");
+            yield return new LocalizationOption("Russian", "ru");
+            yield return new LocalizationOption("Slovak", "sk");
+            yield return new LocalizationOption("Slovenian (Slovenia)", "sl-SI");
+            yield return new LocalizationOption("Spanish", "es");
+            yield return new LocalizationOption("Spanish (Argentina)", "es-AR");
+            yield return new LocalizationOption("Spanish (Mexico)", "es-MX");
+            yield return new LocalizationOption("Swedish", "sv");
+            yield return new LocalizationOption("Swiss German", "gsw");
+            yield return new LocalizationOption("Turkish", "tr");
+        }
     }
 }

+ 2 - 2
MediaBrowser.Api/ItemUpdateService.cs

@@ -69,8 +69,8 @@ namespace MediaBrowser.Api
             {
                 ParentalRatingOptions = _localizationManager.GetParentalRatings().ToArray(),
                 ExternalIdInfos = _providerManager.GetExternalIdInfos(item).ToArray(),
-                Countries = await _localizationManager.GetCountries(),
-                Cultures = _localizationManager.GetCultures()
+                Countries = _localizationManager.GetCountries().ToArray(),
+                Cultures = _localizationManager.GetCultures().ToArray()
             };
 
             if (!item.IsVirtualItem && !(item is ICollectionFolder) && !(item is UserView) && !(item is AggregateFolder) && !(item is LiveTvChannel) && !(item is IItemByName) &&

+ 2 - 3
MediaBrowser.Api/LocalizationService.cs

@@ -1,4 +1,3 @@
-using System.Threading.Tasks;
 using MediaBrowser.Controller.Net;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Globalization;
@@ -82,9 +81,9 @@ namespace MediaBrowser.Api
         /// </summary>
         /// <param name="request">The request.</param>
         /// <returns>System.Object.</returns>
-        public async Task<object> Get(GetCountries request)
+        public object Get(GetCountries request)
         {
-            var result = await _localization.GetCountries();
+            var result = _localization.GetCountries();
 
             return ToOptimizedResult(result);
         }

+ 1 - 0
MediaBrowser.Model/Globalization/CultureDto.cs

@@ -38,6 +38,7 @@ namespace MediaBrowser.Model.Globalization
                 {
                     return vals[0];
                 }
+
                 return null;
             }
         }

+ 23 - 12
MediaBrowser.Model/Globalization/ILocalizationManager.cs

@@ -1,6 +1,5 @@
 using System.Collections.Generic;
 using System.Globalization;
-using System.Threading.Tasks;
 using MediaBrowser.Model.Entities;
 
 namespace MediaBrowser.Model.Globalization
@@ -13,23 +12,26 @@ namespace MediaBrowser.Model.Globalization
         /// <summary>
         /// Gets the cultures.
         /// </summary>
-        /// <returns>IEnumerable{CultureDto}.</returns>
-        CultureDto[] GetCultures();
+        /// <returns><see cref="IEnumerable{CultureDto}" />.</returns>
+        IEnumerable<CultureDto> GetCultures();
+
         /// <summary>
         /// Gets the countries.
         /// </summary>
-        /// <returns>IEnumerable{CountryInfo}.</returns>
-        Task<CountryInfo[]> GetCountries();
+        /// <returns><see cref="IEnumerable{CountryInfo}" />.</returns>
+        IEnumerable<CountryInfo> GetCountries();
+
         /// <summary>
         /// Gets the parental ratings.
         /// </summary>
-        /// <returns>IEnumerable{ParentalRating}.</returns>
+        /// <returns><see cref="IEnumerable{ParentalRating}" />.</returns>
         IEnumerable<ParentalRating> GetParentalRatings();
+
         /// <summary>
         /// Gets the rating level.
         /// </summary>
         /// <param name="rating">The rating.</param>
-        /// <returns>System.Int32.</returns>
+        /// <returns><see cref="int" /> or <c>null</c>.</returns>
         int? GetRatingLevel(string rating);
 
         /// <summary>
@@ -37,7 +39,7 @@ namespace MediaBrowser.Model.Globalization
         /// </summary>
         /// <param name="phrase">The phrase.</param>
         /// <param name="culture">The culture.</param>
-        /// <returns>System.String.</returns>
+        /// <returns><see cref="string" />.</returns>
         string GetLocalizedString(string phrase, string culture);
 
         /// <summary>
@@ -50,13 +52,22 @@ namespace MediaBrowser.Model.Globalization
         /// <summary>
         /// Gets the localization options.
         /// </summary>
-        /// <returns>IEnumerable{LocalizatonOption}.</returns>
-        LocalizationOption[] GetLocalizationOptions();
-
-        string NormalizeFormKD(string text);
+        /// <returns><see cref="IEnumerable{LocalizatonOption}" />.</returns>
+        IEnumerable<LocalizationOption> GetLocalizationOptions();
 
+        /// <summary>
+        /// Checks if the string contains a character with the specified unicode category.
+        /// </summary>
+        /// <param name="value">The string.</param>
+        /// <param name="category">The unicode category.</param>
+        /// <returns>Wether or not the string contains a character with the specified unicode category.</returns>
         bool HasUnicodeCategory(string value, UnicodeCategory category);
 
+        /// <summary>
+        /// Returns the correct <see cref="Cultureinfo" /> for the given language.
+        /// </summary>
+        /// <param name="language">The language.</param>
+        /// <returns>The correct <see cref="Cultureinfo" /> for the given language.</returns>
         CultureDto FindLanguageInfo(string language);
     }
 }

+ 7 - 10
MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs

@@ -285,7 +285,7 @@ namespace MediaBrowser.Providers.TV.TheTVDB
         private string GetComparableName(string name)
         {
             name = name.ToLowerInvariant();
-            name = _localizationManager.NormalizeFormKD(name);
+            name = name.Normalize(NormalizationForm.FormKD);
             var sb = new StringBuilder();
             foreach (var c in name)
             {
@@ -310,19 +310,16 @@ namespace MediaBrowser.Providers.TV.TheTVDB
                     sb.Append(c);
                 }
             }
-            name = sb.ToString();
-            name = name.Replace(", the", "");
-            name = name.Replace("the ", " ");
-            name = name.Replace(" the ", " ");
+            sb.Replace(", the", string.Empty).Replace("the ", " ").Replace(" the ", " ");
 
-            string prevName;
+            int prevLength;
             do
             {
-                prevName = name;
-                name = name.Replace("  ", " ");
-            } while (name.Length != prevName.Length);
+                prevLength = sb.Length;
+                sb.Replace("  ", " ");
+            } while (name.Length != prevLength);
 
-            return name.Trim();
+            return sb.ToString().Trim();
         }
 
         private void MapSeriesToResult(MetadataResult<Series> result, TvDbSharper.Dto.Series tvdbSeries, string metadataLanguage)