diff options
Diffstat (limited to 'MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs')
| -rw-r--r-- | MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs | 143 |
1 files changed, 70 insertions, 73 deletions
diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs index 479ae0f39..12ea2d55b 100644 --- a/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs +++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbProvider.cs @@ -1,16 +1,19 @@ +#nullable disable + #pragma warning disable CS159, SA1300 using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; using System.Net.Http; +using System.Net.Http.Json; using System.Text.Json; using System.Threading; using System.Threading.Tasks; using Jellyfin.Extensions.Json; -using MediaBrowser.Common; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; @@ -26,25 +29,22 @@ namespace MediaBrowser.Providers.Plugins.Omdb private readonly IFileSystem _fileSystem; private readonly IServerConfigurationManager _configurationManager; private readonly IHttpClientFactory _httpClientFactory; - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - private readonly IApplicationHost _appHost; private readonly JsonSerializerOptions _jsonOptions; /// <summary>Initializes a new instance of the <see cref="OmdbProvider"/> class.</summary> /// <param name="httpClientFactory">HttpClientFactory to use for calls to OMDB service.</param> /// <param name="fileSystem">IFileSystem to use for store OMDB data.</param> - /// <param name="appHost">IApplicationHost to use.</param> /// <param name="configurationManager">IServerConfigurationManager to use.</param> - public OmdbProvider(IHttpClientFactory httpClientFactory, IFileSystem fileSystem, IApplicationHost appHost, IServerConfigurationManager configurationManager) + public OmdbProvider(IHttpClientFactory httpClientFactory, IFileSystem fileSystem, IServerConfigurationManager configurationManager) { _httpClientFactory = httpClientFactory; _fileSystem = fileSystem; _configurationManager = configurationManager; - _appHost = appHost; _jsonOptions = new JsonSerializerOptions(JsonDefaults.Options); - _jsonOptions.Converters.Add(new JsonOmdbNotAvailableStringConverter()); - _jsonOptions.Converters.Add(new JsonOmdbNotAvailableInt32Converter()); + // These converters need to take priority + _jsonOptions.Converters.Insert(0, new JsonOmdbNotAvailableStringConverter()); + _jsonOptions.Converters.Insert(0, new JsonOmdbNotAvailableInt32Converter()); } /// <summary>Fetches data from OMDB service.</summary> @@ -67,8 +67,9 @@ namespace MediaBrowser.Providers.Plugins.Omdb var result = await GetRootObject(imdbId, cancellationToken).ConfigureAwait(false); + var isEnglishRequested = IsConfiguredForEnglish(item, language); // Only take the name and rating if the user's language is set to English, since Omdb has no localization - if (string.Equals(language, "en", StringComparison.OrdinalIgnoreCase) || _configurationManager.Configuration.EnableNewOmdbSupport) + if (isEnglishRequested) { item.Name = result.Title; @@ -78,9 +79,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb } } - if (!string.IsNullOrEmpty(result.Year) && result.Year.Length >= 4 - && int.TryParse(result.Year.AsSpan().Slice(0, 4), NumberStyles.Number, _usCulture, out var year) - && year >= 0) + if (TryParseYear(result.Year, out var year)) { item.ProductionYear = year; } @@ -93,14 +92,14 @@ namespace MediaBrowser.Providers.Plugins.Omdb } if (!string.IsNullOrEmpty(result.imdbVotes) - && int.TryParse(result.imdbVotes, NumberStyles.Number, _usCulture, out var voteCount) + && int.TryParse(result.imdbVotes, NumberStyles.Number, CultureInfo.InvariantCulture, out var voteCount) && voteCount >= 0) { // item.VoteCount = voteCount; } if (!string.IsNullOrEmpty(result.imdbRating) - && float.TryParse(result.imdbRating, NumberStyles.Any, _usCulture, out var imdbRating) + && float.TryParse(result.imdbRating, NumberStyles.Any, CultureInfo.InvariantCulture, out var imdbRating) && imdbRating >= 0) { item.CommunityRating = imdbRating; @@ -116,7 +115,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb item.SetProviderId(MetadataProvider.Imdb, result.imdbID); } - ParseAdditionalMetadata(itemResult, result); + ParseAdditionalMetadata(itemResult, result, isEnglishRequested); } /// <summary>Gets data about an episode.</summary> @@ -179,8 +178,9 @@ namespace MediaBrowser.Providers.Plugins.Omdb return false; } + var isEnglishRequested = IsConfiguredForEnglish(item, language); // Only take the name and rating if the user's language is set to English, since Omdb has no localization - if (string.Equals(language, "en", StringComparison.OrdinalIgnoreCase) || _configurationManager.Configuration.EnableNewOmdbSupport) + if (isEnglishRequested) { item.Name = result.Title; @@ -190,9 +190,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb } } - if (!string.IsNullOrEmpty(result.Year) && result.Year.Length >= 4 - && int.TryParse(result.Year.AsSpan().Slice(0, 4), NumberStyles.Number, _usCulture, out var year) - && year >= 0) + if (TryParseYear(result.Year, out var year)) { item.ProductionYear = year; } @@ -205,14 +203,14 @@ namespace MediaBrowser.Providers.Plugins.Omdb } if (!string.IsNullOrEmpty(result.imdbVotes) - && int.TryParse(result.imdbVotes, NumberStyles.Number, _usCulture, out var voteCount) + && int.TryParse(result.imdbVotes, NumberStyles.Number, CultureInfo.InvariantCulture, out var voteCount) && voteCount >= 0) { // item.VoteCount = voteCount; } if (!string.IsNullOrEmpty(result.imdbRating) - && float.TryParse(result.imdbRating, NumberStyles.Any, _usCulture, out var imdbRating) + && float.TryParse(result.imdbRating, NumberStyles.Any, CultureInfo.InvariantCulture, out var imdbRating) && imdbRating >= 0) { item.CommunityRating = imdbRating; @@ -228,7 +226,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb item.SetProviderId(MetadataProvider.Imdb, result.imdbID); } - ParseAdditionalMetadata(itemResult, result); + ParseAdditionalMetadata(itemResult, result, isEnglishRequested); return true; } @@ -262,6 +260,30 @@ namespace MediaBrowser.Providers.Plugins.Omdb return Url + "&" + query; } + /// <summary> + /// Extract the year from a string. + /// </summary> + /// <param name="input">The input string.</param> + /// <param name="year">The year.</param> + /// <returns>A value indicating whether the input could successfully be parsed as a year.</returns> + public static bool TryParseYear(string input, [NotNullWhen(true)] out int? year) + { + if (string.IsNullOrEmpty(input)) + { + year = 0; + return false; + } + + if (int.TryParse(input.AsSpan(0, 4), NumberStyles.Number, CultureInfo.InvariantCulture, out var result)) + { + year = result; + return true; + } + + year = 0; + return false; + } + private async Task<string> EnsureItemInfo(string imdbId, CancellationToken cancellationToken) { if (string.IsNullOrWhiteSpace(imdbId)) @@ -294,7 +316,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb "i={0}&plot=short&tomatoes=true&r=json", imdbParam)); - var rootObject = await GetDeserializedOmdbResponse<RootObject>(_httpClientFactory.CreateClient(NamedClient.Default), url, cancellationToken).ConfigureAwait(false); + var rootObject = await _httpClientFactory.CreateClient(NamedClient.Default).GetFromJsonAsync<RootObject>(url, _jsonOptions, cancellationToken).ConfigureAwait(false); await using FileStream jsonFileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous); await JsonSerializer.SerializeAsync(jsonFileStream, rootObject, _jsonOptions, cancellationToken).ConfigureAwait(false); @@ -334,37 +356,13 @@ namespace MediaBrowser.Providers.Plugins.Omdb imdbParam, seasonId)); - var rootObject = await GetDeserializedOmdbResponse<SeasonRootObject>(_httpClientFactory.CreateClient(NamedClient.Default), url, cancellationToken).ConfigureAwait(false); + var rootObject = await _httpClientFactory.CreateClient(NamedClient.Default).GetFromJsonAsync<SeasonRootObject>(url, _jsonOptions, cancellationToken).ConfigureAwait(false); await using FileStream jsonFileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, IODefaults.FileStreamBufferSize, FileOptions.Asynchronous); await JsonSerializer.SerializeAsync(jsonFileStream, rootObject, _jsonOptions, cancellationToken).ConfigureAwait(false); return path; } - /// <summary>Gets response from OMDB service as type T.</summary> - /// <param name="httpClient">HttpClient instance to use for service call.</param> - /// <param name="url">Http URL to use for service call.</param> - /// <param name="cancellationToken">CancellationToken to use for service call.</param> - /// <typeparam name="T">The first generic type parameter.</typeparam> - /// <returns>OMDB service response as type T.</returns> - public async Task<T> GetDeserializedOmdbResponse<T>(HttpClient httpClient, string url, CancellationToken cancellationToken) - { - using var response = await GetOmdbResponse(httpClient, url, cancellationToken).ConfigureAwait(false); - await using Stream content = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); - - return await JsonSerializer.DeserializeAsync<T>(content, _jsonOptions, cancellationToken).ConfigureAwait(false); - } - - /// <summary>Gets response from OMDB service.</summary> - /// <param name="httpClient">HttpClient instance to use for service call.</param> - /// <param name="url">Http URL to use for service call.</param> - /// <param name="cancellationToken">CancellationToken to use for service call.</param> - /// <returns>OMDB service response as HttpResponseMessage.</returns> - public static Task<HttpResponseMessage> GetOmdbResponse(HttpClient httpClient, string url, CancellationToken cancellationToken) - { - return httpClient.GetAsync(url, cancellationToken); - } - internal string GetDataFilePath(string imdbId) { if (string.IsNullOrEmpty(imdbId)) @@ -393,31 +391,25 @@ namespace MediaBrowser.Providers.Plugins.Omdb return Path.Combine(dataPath, filename); } - private void ParseAdditionalMetadata<T>(MetadataResult<T> itemResult, RootObject result) + private static void ParseAdditionalMetadata<T>(MetadataResult<T> itemResult, RootObject result, bool isEnglishRequested) where T : BaseItem { var item = itemResult.Item; - var isConfiguredForEnglish = IsConfiguredForEnglish(item) || _configurationManager.Configuration.EnableNewOmdbSupport; - // Grab series genres because IMDb data is better than TVDB. Leave movies alone // But only do it if English is the preferred language because this data will not be localized - if (isConfiguredForEnglish && !string.IsNullOrWhiteSpace(result.Genre)) + if (isEnglishRequested && !string.IsNullOrWhiteSpace(result.Genre)) { item.Genres = Array.Empty<string>(); - foreach (var genre in result.Genre - .Split(',', StringSplitOptions.RemoveEmptyEntries) - .Select(i => i.Trim()) - .Where(i => !string.IsNullOrWhiteSpace(i))) + foreach (var genre in result.Genre.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)) { item.AddGenre(genre); } } - if (isConfiguredForEnglish) + if (isEnglishRequested) { - // Omdb is currently English only, so for other languages skip this and let secondary providers fill it in item.Overview = result.Plot; } @@ -430,7 +422,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb { var person = new PersonInfo { - Name = result.Director.Trim(), + Name = result.Director, Type = PersonType.Director }; @@ -441,7 +433,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb { var person = new PersonInfo { - Name = result.Writer.Trim(), + Name = result.Writer, Type = PersonType.Writer }; @@ -450,29 +442,34 @@ namespace MediaBrowser.Providers.Plugins.Omdb if (!string.IsNullOrWhiteSpace(result.Actors)) { - var actorList = result.Actors.Split(','); + var actorList = result.Actors.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); foreach (var actor in actorList) { - if (!string.IsNullOrWhiteSpace(actor)) + if (string.IsNullOrWhiteSpace(actor)) { - var person = new PersonInfo - { - Name = actor.Trim(), - Type = PersonType.Actor - }; - - itemResult.AddPerson(person); + continue; } + + var person = new PersonInfo + { + Name = actor, + Type = PersonType.Actor + }; + + itemResult.AddPerson(person); } } } - private bool IsConfiguredForEnglish(BaseItem item) + private static bool IsConfiguredForEnglish(BaseItem item, string language) { - var lang = item.GetPreferredMetadataLanguage(); + if (string.IsNullOrEmpty(language)) + { + language = item.GetPreferredMetadataLanguage(); + } // The data isn't localized and so can only be used for English users - return string.Equals(lang, "en", StringComparison.OrdinalIgnoreCase); + return string.Equals(language, "en", StringComparison.OrdinalIgnoreCase); } internal class SeasonRootObject @@ -549,7 +546,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb if (Ratings != null) { var rating = Ratings.FirstOrDefault(i => string.Equals(i.Source, "Rotten Tomatoes", StringComparison.OrdinalIgnoreCase)); - if (rating != null && rating.Value != null) + if (rating?.Value != null) { var value = rating.Value.TrimEnd('%'); if (float.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var score)) |
