using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Localization; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Globalization; using MoreLinq; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Threading.Tasks; namespace MediaBrowser.Server.Implementations.Localization { /// /// Class LocalizationManager /// public class LocalizationManager : ILocalizationManager { /// /// The _configuration manager /// private readonly IServerConfigurationManager _configurationManager; /// /// The us culture /// private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); private readonly ConcurrentDictionary> _allParentalRatings = new ConcurrentDictionary>(StringComparer.OrdinalIgnoreCase); /// /// Initializes a new instance of the class. /// /// The configuration manager. public LocalizationManager(IServerConfigurationManager configurationManager) { _configurationManager = configurationManager; } /// /// Gets the localization path. /// /// The localization path. public string LocalizationPath { get { return Path.Combine(_configurationManager.ApplicationPaths.ProgramDataPath, "localization"); } } /// /// Gets the cultures. /// /// IEnumerable{CultureDto}. public IEnumerable GetCultures() { return CultureInfo.GetCultures(CultureTypes.AllCultures) .OrderBy(c => c.DisplayName) .DistinctBy(c => c.TwoLetterISOLanguageName + c.ThreeLetterISOLanguageName) .Select(c => new CultureDto { Name = c.Name, DisplayName = c.DisplayName, ThreeLetterISOLanguageName = c.ThreeLetterISOLanguageName, TwoLetterISOLanguageName = c.TwoLetterISOLanguageName }); } /// /// Gets the countries. /// /// IEnumerable{CountryInfo}. public IEnumerable GetCountries() { return CultureInfo.GetCultures(CultureTypes.SpecificCultures) .Select(c => new RegionInfo(c.LCID)) .OrderBy(c => c.DisplayName) .DistinctBy(c => c.TwoLetterISORegionName) .Select(c => new CountryInfo { Name = c.Name, DisplayName = c.DisplayName, TwoLetterISORegionName = c.TwoLetterISORegionName, ThreeLetterISORegionName = c.ThreeLetterISORegionName }); } /// /// Gets the parental ratings. /// /// IEnumerable{ParentalRating}. public IEnumerable GetParentalRatings() { return GetParentalRatingsDictionary().Values.ToList(); } /// /// Gets the parental ratings dictionary. /// /// Dictionary{System.StringParentalRating}. private Dictionary GetParentalRatingsDictionary() { var countryCode = _configurationManager.Configuration.MetadataCountryCode; if (string.IsNullOrEmpty(countryCode)) { countryCode = "us"; } var ratings = GetRatings(countryCode); if (ratings == null) { ratings = GetRatings("us"); } return ratings; } /// /// Gets the ratings. /// /// The country code. private Dictionary GetRatings(string countryCode) { Dictionary value; if (!_allParentalRatings.TryGetValue(countryCode, out value)) { value = LoadRatings(countryCode); if (value != null) { _allParentalRatings.TryAdd(countryCode, value); } } return value; } /// /// Loads the ratings. /// /// The country code. private Dictionary LoadRatings(string countryCode) { var path = GetRatingsFilePath(countryCode); if (string.IsNullOrEmpty(path)) { return null; } return File.ReadAllLines(path).Select(i => { if (!string.IsNullOrWhiteSpace(i)) { var parts = i.Split(','); if (parts.Length == 2) { int value; if (int.TryParse(parts[1], NumberStyles.Integer, UsCulture, out value)) { return new ParentalRating { Name = parts[0], Value = value }; } } } return null; }) .Where(i => i != null) .ToDictionary(i => i.Name); } /// /// Gets the ratings file. /// /// The country code. private string GetRatingsFilePath(string countryCode) { countryCode = countryCode.ToLower(); var path = Path.Combine(LocalizationPath, "ratings-" + countryCode + ".txt"); if (!File.Exists(path)) { // Extract embedded resource var type = GetType(); var resourcePath = type.Namespace + ".Ratings." + countryCode + ".txt"; using (var stream = type.Assembly.GetManifestResourceStream(resourcePath)) { if (stream == null) { return null; } var parentPath = Path.GetDirectoryName(path); if (!Directory.Exists(parentPath)) { Directory.CreateDirectory(parentPath); } using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read)) { stream.CopyTo(fs); } } } return path; } /// /// Gets the rating level. /// public int? GetRatingLevel(string rating) { if (string.IsNullOrEmpty(rating)) { throw new ArgumentNullException("rating"); } var ratingsDictionary = GetParentalRatingsDictionary(); ParentalRating value; if (!ratingsDictionary.TryGetValue(rating, out value)) { var stripped = StripCountry(rating); ratingsDictionary.TryGetValue(stripped, out value); } return value == null ? (int?)null : value.Value; } /// /// Strips the country. /// /// The rating. /// System.String. private static string StripCountry(string rating) { int start = rating.IndexOf('-'); return start > 0 ? rating.Substring(start + 1) : rating; } } }