Refactor omdb providers

pull/6870/head
cvium 3 years ago
parent fa366f0099
commit 96ea865681

@ -402,8 +402,6 @@ namespace MediaBrowser.Model.Configuration
/// </summary>
public bool RequireHttps { get; set; } = false;
public bool EnableNewOmdbSupport { get; set; } = true;
/// <summary>
/// Gets or sets the filter for remote IP connectivity. Used in conjuntion with <seealso cref="IsRemoteIPFilterBlacklist"/>.
/// </summary>

@ -4,7 +4,6 @@ using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
@ -17,24 +16,17 @@ namespace MediaBrowser.Providers.Plugins.Omdb
{
public class OmdbEpisodeProvider : IRemoteMetadataProvider<Episode, EpisodeInfo>, IHasOrder
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly OmdbItemProvider _itemProvider;
private readonly IFileSystem _fileSystem;
private readonly IServerConfigurationManager _configurationManager;
private readonly IApplicationHost _appHost;
private readonly OmdbProvider _omdbProvider;
public OmdbEpisodeProvider(
IApplicationHost appHost,
IHttpClientFactory httpClientFactory,
ILibraryManager libraryManager,
IFileSystem fileSystem,
IServerConfigurationManager configurationManager)
{
_httpClientFactory = httpClientFactory;
_fileSystem = fileSystem;
_configurationManager = configurationManager;
_appHost = appHost;
_itemProvider = new OmdbItemProvider(_appHost, httpClientFactory, libraryManager, fileSystem, configurationManager);
_itemProvider = new OmdbItemProvider(httpClientFactory, libraryManager, fileSystem, configurationManager);
_omdbProvider = new OmdbProvider(httpClientFactory, fileSystem, configurationManager);
}
// After TheTvDb
@ -44,12 +36,12 @@ namespace MediaBrowser.Providers.Plugins.Omdb
public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(EpisodeInfo searchInfo, CancellationToken cancellationToken)
{
return _itemProvider.GetSearchResults(searchInfo, "episode", cancellationToken);
return _itemProvider.GetSearchResults(searchInfo, cancellationToken);
}
public async Task<MetadataResult<Episode>> GetMetadata(EpisodeInfo info, CancellationToken cancellationToken)
{
var result = new MetadataResult<Episode>()
var result = new MetadataResult<Episode>
{
Item = new Episode(),
QueriedById = true
@ -61,13 +53,20 @@ namespace MediaBrowser.Providers.Plugins.Omdb
return result;
}
if (info.SeriesProviderIds.TryGetValue(MetadataProvider.Imdb.ToString(), out string? seriesImdbId) && !string.IsNullOrEmpty(seriesImdbId))
if (info.SeriesProviderIds.TryGetValue(MetadataProvider.Imdb.ToString(), out string? seriesImdbId)
&& !string.IsNullOrEmpty(seriesImdbId)
&& info.IndexNumber.HasValue
&& info.ParentIndexNumber.HasValue)
{
if (info.IndexNumber.HasValue && info.ParentIndexNumber.HasValue)
{
result.HasMetadata = await new OmdbProvider(_httpClientFactory, _fileSystem, _configurationManager)
.FetchEpisodeData(result, info.IndexNumber.Value, info.ParentIndexNumber.Value, info.GetProviderId(MetadataProvider.Imdb), seriesImdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false);
}
result.HasMetadata = await _omdbProvider.FetchEpisodeData(
result,
info.IndexNumber.Value,
info.ParentIndexNumber.Value,
info.GetProviderId(MetadataProvider.Imdb),
seriesImdbId,
info.MetadataLanguage,
info.MetadataCountryCode,
cancellationToken).ConfigureAwait(false);
}
return result;

@ -2,8 +2,9 @@
#pragma warning disable CS1591
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
@ -22,14 +23,12 @@ namespace MediaBrowser.Providers.Plugins.Omdb
public class OmdbImageProvider : IRemoteImageProvider, IHasOrder
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly IFileSystem _fileSystem;
private readonly IServerConfigurationManager _configurationManager;
private readonly OmdbProvider _omdbProvider;
public OmdbImageProvider(IHttpClientFactory httpClientFactory, IFileSystem fileSystem, IServerConfigurationManager configurationManager)
{
_httpClientFactory = httpClientFactory;
_fileSystem = fileSystem;
_configurationManager = configurationManager;
_omdbProvider = new OmdbProvider(_httpClientFactory, fileSystem, configurationManager);
}
public string Name => "The Open Movie Database";
@ -49,38 +48,27 @@ namespace MediaBrowser.Providers.Plugins.Omdb
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
{
var imdbId = item.GetProviderId(MetadataProvider.Imdb);
if (string.IsNullOrWhiteSpace(imdbId))
{
return Enumerable.Empty<RemoteImageInfo>();
}
var list = new List<RemoteImageInfo>();
var provider = new OmdbProvider(_httpClientFactory, _fileSystem, _configurationManager);
var rootObject = await _omdbProvider.GetRootObject(imdbId, cancellationToken).ConfigureAwait(false);
if (!string.IsNullOrWhiteSpace(imdbId))
if (string.IsNullOrEmpty(rootObject.Poster) || string.Equals("N/A", rootObject.Poster, StringComparison.OrdinalIgnoreCase))
{
var rootObject = await provider.GetRootObject(imdbId, cancellationToken).ConfigureAwait(false);
return Enumerable.Empty<RemoteImageInfo>();
}
if (!string.IsNullOrEmpty(rootObject.Poster))
// the poster url is sometimes higher quality than the poster api
return new[]
{
new RemoteImageInfo
{
if (item is Episode)
{
// img.omdbapi.com is returning 404's
list.Add(new RemoteImageInfo
{
ProviderName = Name,
Url = rootObject.Poster
});
}
else
{
list.Add(new RemoteImageInfo
{
ProviderName = Name,
Url = string.Format(CultureInfo.InvariantCulture, "https://img.omdbapi.com/?i={0}&apikey=2c9d9507", imdbId)
});
}
ProviderName = Name,
Url = rootObject.Poster
}
}
return list;
};
}
public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)

@ -8,11 +8,11 @@ using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
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;
@ -31,13 +31,10 @@ namespace MediaBrowser.Providers.Plugins.Omdb
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILibraryManager _libraryManager;
private readonly IFileSystem _fileSystem;
private readonly IServerConfigurationManager _configurationManager;
private readonly IApplicationHost _appHost;
private readonly JsonSerializerOptions _jsonOptions;
private readonly OmdbProvider _omdbProvider;
public OmdbItemProvider(
IApplicationHost appHost,
IHttpClientFactory httpClientFactory,
ILibraryManager libraryManager,
IFileSystem fileSystem,
@ -45,9 +42,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
{
_httpClientFactory = httpClientFactory;
_libraryManager = libraryManager;
_fileSystem = fileSystem;
_configurationManager = configurationManager;
_appHost = appHost;
_omdbProvider = new OmdbProvider(_httpClientFactory, fileSystem, configurationManager);
_jsonOptions = new JsonSerializerOptions(JsonDefaults.Options);
_jsonOptions.Converters.Add(new JsonOmdbNotAvailableStringConverter());
@ -59,185 +54,167 @@ namespace MediaBrowser.Providers.Plugins.Omdb
// After primary option
public int Order => 2;
public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(TrailerInfo searchInfo, CancellationToken cancellationToken)
{
return GetSearchResultsInternal(searchInfo, true, cancellationToken);
}
public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(SeriesInfo searchInfo, CancellationToken cancellationToken)
{
return GetSearchResults(searchInfo, "series", cancellationToken);
return GetSearchResultsInternal(searchInfo, true, cancellationToken);
}
public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(MovieInfo searchInfo, CancellationToken cancellationToken)
{
return GetSearchResults(searchInfo, "movie", cancellationToken);
return GetSearchResultsInternal(searchInfo, true, cancellationToken);
}
public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(ItemLookupInfo searchInfo, string type, CancellationToken cancellationToken)
public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(EpisodeInfo searchInfo, CancellationToken cancellationToken)
{
return GetSearchResultsInternal(searchInfo, type, true, cancellationToken);
return GetSearchResultsInternal(searchInfo, true, cancellationToken);
}
private async Task<IEnumerable<RemoteSearchResult>> GetSearchResultsInternal(ItemLookupInfo searchInfo, string type, bool isSearch, CancellationToken cancellationToken)
private async Task<IEnumerable<RemoteSearchResult>> GetSearchResultsInternal(ItemLookupInfo searchInfo, bool isSearch, CancellationToken cancellationToken)
{
var type = searchInfo switch
{
EpisodeInfo => "episode",
SeriesInfo => "series",
_ => "movie"
};
// This is a bit hacky?
var episodeSearchInfo = searchInfo as EpisodeInfo;
var indexNumberEnd = episodeSearchInfo?.IndexNumberEnd;
var imdbId = searchInfo.GetProviderId(MetadataProvider.Imdb);
var urlQuery = "plot=full&r=json";
if (type == "episode" && episodeSearchInfo != null)
var urlQuery = new StringBuilder("plot=full&r=json");
if (episodeSearchInfo != null)
{
episodeSearchInfo.SeriesProviderIds.TryGetValue(MetadataProvider.Imdb.ToString(), out imdbId);
}
var name = searchInfo.Name;
var year = searchInfo.Year;
if (searchInfo.IndexNumber.HasValue)
{
urlQuery.AppendFormat(CultureInfo.InvariantCulture, "&Episode={0}", searchInfo.IndexNumber);
}
if (!string.IsNullOrWhiteSpace(name))
{
var parsedName = _libraryManager.ParseName(name);
var yearInName = parsedName.Year;
name = parsedName.Name;
year ??= yearInName;
if (searchInfo.ParentIndexNumber.HasValue)
{
urlQuery.AppendFormat(CultureInfo.InvariantCulture, "&Season={0}", searchInfo.ParentIndexNumber);
}
}
if (string.IsNullOrWhiteSpace(imdbId))
{
if (year.HasValue)
var name = searchInfo.Name;
var year = searchInfo.Year;
if (!string.IsNullOrWhiteSpace(name))
{
urlQuery += "&y=" + year.Value.ToString(CultureInfo.InvariantCulture);
var parsedName = _libraryManager.ParseName(name);
var yearInName = parsedName.Year;
name = parsedName.Name;
year ??= yearInName;
}
// &s means search and returns a list of results as opposed to t
if (isSearch)
{
urlQuery += "&s=" + WebUtility.UrlEncode(name);
}
else
if (year.HasValue)
{
urlQuery += "&t=" + WebUtility.UrlEncode(name);
urlQuery.Append("&y=")
.Append(year);
}
urlQuery += "&type=" + type;
// &s means search and returns a list of results as opposed to t
urlQuery.Append(isSearch ? "&s=" : "&t=");
urlQuery.Append(WebUtility.UrlEncode(name));
urlQuery.Append("&type=")
.Append(type);
}
else
{
urlQuery += "&i=" + imdbId;
urlQuery.Append("&i=")
.Append(imdbId);
isSearch = false;
}
if (type == "episode")
{
if (searchInfo.IndexNumber.HasValue)
{
urlQuery += string.Format(CultureInfo.InvariantCulture, "&Episode={0}", searchInfo.IndexNumber);
}
if (searchInfo.ParentIndexNumber.HasValue)
{
urlQuery += string.Format(CultureInfo.InvariantCulture, "&Season={0}", searchInfo.ParentIndexNumber);
}
}
var url = OmdbProvider.GetOmdbUrl(urlQuery);
var url = OmdbProvider.GetOmdbUrl(urlQuery.ToString());
using var response = await OmdbProvider.GetOmdbResponse(_httpClientFactory.CreateClient(NamedClient.Default), url, cancellationToken).ConfigureAwait(false);
using var response = await _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken).ConfigureAwait(false);
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
var resultList = new List<SearchResult>();
if (isSearch)
{
var searchResultList = await JsonSerializer.DeserializeAsync<SearchResultList>(stream, _jsonOptions, cancellationToken).ConfigureAwait(false);
if (searchResultList != null && searchResultList.Search != null)
if (searchResultList?.Search != null)
{
resultList.AddRange(searchResultList.Search);
var resultCount = searchResultList.Search.Count;
var result = new RemoteSearchResult[resultCount];
for (var i = 0; i < resultCount; i++)
{
result[i] = ResultToMetadataResult(searchResultList.Search[i], searchInfo, indexNumberEnd);
}
return result;
}
}
else
{
var result = await JsonSerializer.DeserializeAsync<SearchResult>(stream, _jsonOptions, cancellationToken).ConfigureAwait(false);
if (string.Equals(result.Response, "true", StringComparison.OrdinalIgnoreCase))
if (string.Equals(result?.Response, "true", StringComparison.OrdinalIgnoreCase))
{
resultList.Add(result);
return new[] { ResultToMetadataResult(result, searchInfo, indexNumberEnd) };
}
}
return resultList.Select(result =>
{
var item = new RemoteSearchResult
{
IndexNumber = searchInfo.IndexNumber,
Name = result.Title,
ParentIndexNumber = searchInfo.ParentIndexNumber,
SearchProviderName = Name
};
if (episodeSearchInfo != null && episodeSearchInfo.IndexNumberEnd.HasValue)
{
item.IndexNumberEnd = episodeSearchInfo.IndexNumberEnd.Value;
}
item.SetProviderId(MetadataProvider.Imdb, result.imdbID);
if (result.Year.Length > 0
&& int.TryParse(result.Year.AsSpan().Slice(0, Math.Min(result.Year.Length, 4)), NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsedYear))
{
item.ProductionYear = parsedYear;
}
if (!string.IsNullOrEmpty(result.Released)
&& DateTime.TryParse(result.Released, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out var released))
{
item.PremiereDate = released;
}
if (!string.IsNullOrWhiteSpace(result.Poster) && !string.Equals(result.Poster, "N/A", StringComparison.OrdinalIgnoreCase))
{
item.ImageUrl = result.Poster;
}
return item;
});
return Enumerable.Empty<RemoteSearchResult>();
}
public Task<MetadataResult<Trailer>> GetMetadata(TrailerInfo info, CancellationToken cancellationToken)
{
return GetMovieResult<Trailer>(info, cancellationToken);
return GetResult<Trailer>(info, cancellationToken);
}
public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(TrailerInfo searchInfo, CancellationToken cancellationToken)
public Task<MetadataResult<Series>> GetMetadata(SeriesInfo info, CancellationToken cancellationToken)
{
return GetSearchResults(searchInfo, "movie", cancellationToken);
return GetResult<Series>(info, cancellationToken);
}
public async Task<MetadataResult<Series>> GetMetadata(SeriesInfo info, CancellationToken cancellationToken)
public Task<MetadataResult<Movie>> GetMetadata(MovieInfo info, CancellationToken cancellationToken)
{
var result = new MetadataResult<Series>
return GetResult<Movie>(info, cancellationToken);
}
private RemoteSearchResult ResultToMetadataResult(SearchResult result, ItemLookupInfo searchInfo, int? indexNumberEnd)
{
var item = new RemoteSearchResult
{
Item = new Series(),
QueriedById = true
IndexNumber = searchInfo.IndexNumber,
Name = result.Title,
ParentIndexNumber = searchInfo.ParentIndexNumber,
SearchProviderName = Name,
IndexNumberEnd = indexNumberEnd
};
var imdbId = info.GetProviderId(MetadataProvider.Imdb);
if (string.IsNullOrWhiteSpace(imdbId))
item.SetProviderId(MetadataProvider.Imdb, result.imdbID);
if (OmdbProvider.TryParseYear(result.Year, out var parsedYear))
{
imdbId = await GetSeriesImdbId(info, cancellationToken).ConfigureAwait(false);
result.QueriedById = false;
item.ProductionYear = parsedYear;
}
if (!string.IsNullOrEmpty(imdbId))
if (!string.IsNullOrEmpty(result.Released)
&& DateTime.TryParse(result.Released, CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out var released))
{
result.Item.SetProviderId(MetadataProvider.Imdb, imdbId);
result.HasMetadata = true;
await new OmdbProvider(_httpClientFactory, _fileSystem, _configurationManager).Fetch(result, imdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false);
item.PremiereDate = released;
}
return result;
}
if (!string.IsNullOrWhiteSpace(result.Poster) && !string.Equals(result.Poster, "N/A", StringComparison.OrdinalIgnoreCase))
{
item.ImageUrl = result.Poster;
}
public Task<MetadataResult<Movie>> GetMetadata(MovieInfo info, CancellationToken cancellationToken)
{
return GetMovieResult<Movie>(info, cancellationToken);
return item;
}
private async Task<MetadataResult<T>> GetMovieResult<T>(ItemLookupInfo info, CancellationToken cancellationToken)
private async Task<MetadataResult<T>> GetResult<T>(ItemLookupInfo info, CancellationToken cancellationToken)
where T : BaseItem, new()
{
var result = new MetadataResult<T>
@ -249,7 +226,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
var imdbId = info.GetProviderId(MetadataProvider.Imdb);
if (string.IsNullOrWhiteSpace(imdbId))
{
imdbId = await GetMovieImdbId(info, cancellationToken).ConfigureAwait(false);
imdbId = await GetImdbId(info, cancellationToken).ConfigureAwait(false);
result.QueriedById = false;
}
@ -258,22 +235,15 @@ namespace MediaBrowser.Providers.Plugins.Omdb
result.Item.SetProviderId(MetadataProvider.Imdb, imdbId);
result.HasMetadata = true;
await new OmdbProvider(_httpClientFactory, _fileSystem, _configurationManager).Fetch(result, imdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false);
await _omdbProvider.Fetch(result, imdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false);
}
return result;
}
private async Task<string> GetMovieImdbId(ItemLookupInfo info, CancellationToken cancellationToken)
{
var results = await GetSearchResultsInternal(info, "movie", false, cancellationToken).ConfigureAwait(false);
var first = results.FirstOrDefault();
return first?.GetProviderId(MetadataProvider.Imdb);
}
private async Task<string> GetSeriesImdbId(SeriesInfo info, CancellationToken cancellationToken)
private async Task<string> GetImdbId(ItemLookupInfo info, CancellationToken cancellationToken)
{
var results = await GetSearchResultsInternal(info, "series", false, cancellationToken).ConfigureAwait(false);
var results = await GetSearchResultsInternal(info, false, cancellationToken).ConfigureAwait(false);
var first = results.FirstOrDefault();
return first?.GetProviderId(MetadataProvider.Imdb);
}

@ -4,10 +4,12 @@
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;
@ -40,8 +42,9 @@ namespace MediaBrowser.Providers.Plugins.Omdb
_configurationManager = configurationManager;
_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>
@ -64,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;
@ -75,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, CultureInfo.InvariantCulture, out var year)
&& year >= 0)
if (TryParseYear(result.Year, out var year))
{
item.ProductionYear = year;
}
@ -113,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>
@ -176,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;
@ -187,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, CultureInfo.InvariantCulture, out var year)
&& year >= 0)
if (TryParseYear(result.Year, out var year))
{
item.ProductionYear = year;
}
@ -225,7 +226,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
item.SetProviderId(MetadataProvider.Imdb, result.imdbID);
}
ParseAdditionalMetadata(itemResult, result);
ParseAdditionalMetadata(itemResult, result, isEnglishRequested);
return true;
}
@ -259,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))
@ -291,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);
@ -331,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))
@ -390,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;
}
@ -427,7 +422,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
{
var person = new PersonInfo
{
Name = result.Director.Trim(),
Name = result.Director,
Type = PersonType.Director
};
@ -438,7 +433,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb
{
var person = new PersonInfo
{
Name = result.Writer.Trim(),
Name = result.Writer,
Type = PersonType.Writer
};
@ -447,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
@ -546,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))

Loading…
Cancel
Save