aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/Localization/LocalizationManager.cs
diff options
context:
space:
mode:
authorCody Robibero <cody@robibe.ro>2023-02-23 07:04:44 -0700
committerGitHub <noreply@github.com>2023-02-23 07:04:44 -0700
commitecb5c48538fb46b4aab744d165bd525bd8a53cd3 (patch)
treef2fedbedf3556cc1c3c1036ea14fd373f52c15d1 /Emby.Server.Implementations/Localization/LocalizationManager.cs
parenteb3d187f27c34112689d37c50a1f734835a33ef3 (diff)
parent6300d01fcceba56932741251443f5b2aa4f76de2 (diff)
Merge pull request #8526 from Shadowghost/rating-overhaul
Diffstat (limited to 'Emby.Server.Implementations/Localization/LocalizationManager.cs')
-rw-r--r--Emby.Server.Implementations/Localization/LocalizationManager.cs80
1 files changed, 65 insertions, 15 deletions
diff --git a/Emby.Server.Implementations/Localization/LocalizationManager.cs b/Emby.Server.Implementations/Localization/LocalizationManager.cs
index b418c7877..6e2a33fd5 100644
--- a/Emby.Server.Implementations/Localization/LocalizationManager.cs
+++ b/Emby.Server.Implementations/Localization/LocalizationManager.cs
@@ -3,6 +3,7 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
+using System.Linq;
using System.Reflection;
using System.Text.Json;
using System.Threading.Tasks;
@@ -25,7 +26,7 @@ namespace Emby.Server.Implementations.Localization
private const string CulturesPath = "Emby.Server.Implementations.Localization.iso6392.txt";
private const string CountriesPath = "Emby.Server.Implementations.Localization.countries.json";
private static readonly Assembly _assembly = typeof(LocalizationManager).Assembly;
- private static readonly string[] _unratedValues = { "n/a", "unrated", "not rated" };
+ private static readonly string[] _unratedValues = { "n/a", "unrated", "not rated", "nr" };
private readonly IServerConfigurationManager _configurationManager;
private readonly ILogger<LocalizationManager> _logger;
@@ -86,12 +87,10 @@ namespace Emby.Server.Implementations.Localization
var name = parts[0];
dict.Add(name, new ParentalRating(name, value));
}
-#if DEBUG
else
{
_logger.LogWarning("Malformed line in ratings file for country {CountryCode}", countryCode);
}
-#endif
}
_allParentalRatings[countryCode] = dict;
@@ -184,7 +183,56 @@ namespace Emby.Server.Implementations.Localization
/// <inheritdoc />
public IEnumerable<ParentalRating> GetParentalRatings()
- => GetParentalRatingsDictionary().Values;
+ {
+ var ratings = GetParentalRatingsDictionary().Values.ToList();
+
+ // Add common ratings to ensure them being available for selection.
+ // Based on the US rating system due to it being the main source of rating in the metadata providers
+ // Minimum rating possible
+ if (!ratings.Any(x => x.Value == 0))
+ {
+ ratings.Add(new ParentalRating("Approved", 0));
+ }
+
+ // Matches PG (this has different age restrictions depending on country)
+ if (!ratings.Any(x => x.Value == 10))
+ {
+ ratings.Add(new ParentalRating("10", 10));
+ }
+
+ // Matches PG-13
+ if (!ratings.Any(x => x.Value == 13))
+ {
+ ratings.Add(new ParentalRating("13", 13));
+ }
+
+ // Matches TV-14
+ if (!ratings.Any(x => x.Value == 14))
+ {
+ ratings.Add(new ParentalRating("14", 14));
+ }
+
+ // Catchall if max rating of country is less than 21
+ // Using 21 instead of 18 to be sure to allow access to all rated content except adult and banned
+ if (!ratings.Any(x => x.Value >= 21))
+ {
+ ratings.Add(new ParentalRating("21", 21));
+ }
+
+ // A lot of countries don't excplicitly have a seperate rating for adult content
+ if (!ratings.Any(x => x.Value == 1000))
+ {
+ ratings.Add(new ParentalRating("XXX", 1000));
+ }
+
+ // A lot of countries don't excplicitly have a seperate rating for banned content
+ if (!ratings.Any(x => x.Value == 1001))
+ {
+ ratings.Add(new ParentalRating("Banned", 1001));
+ }
+
+ return ratings.OrderBy(r => r.Value);
+ }
/// <summary>
/// Gets the parental ratings dictionary.
@@ -194,6 +242,7 @@ namespace Emby.Server.Implementations.Localization
{
var countryCode = _configurationManager.Configuration.MetadataCountryCode;
+ // Fall back to US ratings if no country code is specified or country code does not exist.
if (string.IsNullOrEmpty(countryCode))
{
countryCode = "us";
@@ -205,15 +254,15 @@ namespace Emby.Server.Implementations.Localization
}
/// <summary>
- /// Gets the ratings.
+ /// Gets the ratings for a country.
/// </summary>
/// <param name="countryCode">The country code.</param>
/// <returns>The ratings.</returns>
private Dictionary<string, ParentalRating>? GetRatings(string countryCode)
{
- _allParentalRatings.TryGetValue(countryCode, out var value);
+ _allParentalRatings.TryGetValue(countryCode, out var countryValue);
- return value;
+ return countryValue;
}
/// <inheritdoc />
@@ -221,12 +270,14 @@ namespace Emby.Server.Implementations.Localization
{
ArgumentException.ThrowIfNullOrEmpty(rating);
+ // Handle unrated content
if (_unratedValues.Contains(rating.AsSpan(), StringComparison.OrdinalIgnoreCase))
{
return null;
}
// Fairly common for some users to have "Rated R" in their rating field
+ rating = rating.Replace("Rated :", string.Empty, StringComparison.OrdinalIgnoreCase);
rating = rating.Replace("Rated ", string.Empty, StringComparison.OrdinalIgnoreCase);
var ratingsDictionary = GetParentalRatingsDictionary();
@@ -246,18 +297,17 @@ namespace Emby.Server.Implementations.Localization
}
// Try splitting by : to handle "Germany: FSK 18"
- var index = rating.IndexOf(':', StringComparison.Ordinal);
- if (index != -1)
+ if (rating.Contains(':', StringComparison.OrdinalIgnoreCase))
{
- var trimmedRating = rating.AsSpan(index).TrimStart(':').Trim();
+ return GetRatingLevel(rating.AsSpan().RightPart(':').ToString());
+ }
- if (!trimmedRating.IsEmpty)
- {
- return GetRatingLevel(trimmedRating.ToString());
- }
+ // Remove prefix country code to handle "DE-18"
+ if (rating.Contains('-', StringComparison.OrdinalIgnoreCase))
+ {
+ return GetRatingLevel(rating.AsSpan().RightPart('-').ToString());
}
- // TODO: Further improve by normalizing out all spaces and dashes
return null;
}