diff options
Diffstat (limited to 'MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs')
| -rw-r--r-- | MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs new file mode 100644 index 000000000..3aadda5d0 --- /dev/null +++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs @@ -0,0 +1,317 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Net; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Common; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Movies; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Providers; +using MediaBrowser.Model.Serialization; +using Microsoft.Extensions.Logging; + +namespace MediaBrowser.Providers.Plugins.Omdb +{ + public class OmdbItemProvider : IRemoteMetadataProvider<Series, SeriesInfo>, + IRemoteMetadataProvider<Movie, MovieInfo>, IRemoteMetadataProvider<Trailer, TrailerInfo>, IHasOrder + { + private readonly IJsonSerializer _jsonSerializer; + private readonly IHttpClient _httpClient; + private readonly ILogger _logger; + private readonly ILibraryManager _libraryManager; + private readonly IFileSystem _fileSystem; + private readonly IServerConfigurationManager _configurationManager; + private readonly IApplicationHost _appHost; + + public OmdbItemProvider(IJsonSerializer jsonSerializer, IApplicationHost appHost, IHttpClient httpClient, ILogger logger, ILibraryManager libraryManager, IFileSystem fileSystem, IServerConfigurationManager configurationManager) + { + _jsonSerializer = jsonSerializer; + _httpClient = httpClient; + _logger = logger; + _libraryManager = libraryManager; + _fileSystem = fileSystem; + _configurationManager = configurationManager; + _appHost = appHost; + } + // After primary option + public int Order => 2; + + public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(SeriesInfo searchInfo, CancellationToken cancellationToken) + { + return GetSearchResults(searchInfo, "series", cancellationToken); + } + + public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(MovieInfo searchInfo, CancellationToken cancellationToken) + { + return GetSearchResults(searchInfo, "movie", cancellationToken); + } + + public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(ItemLookupInfo searchInfo, string type, CancellationToken cancellationToken) + { + return GetSearchResultsInternal(searchInfo, type, true, cancellationToken); + } + + private async Task<IEnumerable<RemoteSearchResult>> GetSearchResultsInternal(ItemLookupInfo searchInfo, string type, bool isSearch, CancellationToken cancellationToken) + { + var episodeSearchInfo = searchInfo as EpisodeInfo; + + var imdbId = searchInfo.GetProviderId(MetadataProviders.Imdb); + + var urlQuery = "plot=full&r=json"; + if (type == "episode" && episodeSearchInfo != null) + { + episodeSearchInfo.SeriesProviderIds.TryGetValue(MetadataProviders.Imdb.ToString(), out imdbId); + } + + var name = searchInfo.Name; + var year = searchInfo.Year; + + if (!string.IsNullOrWhiteSpace(name)) + { + var parsedName = _libraryManager.ParseName(name); + var yearInName = parsedName.Year; + name = parsedName.Name; + year = year ?? yearInName; + } + + if (string.IsNullOrWhiteSpace(imdbId)) + { + if (year.HasValue) + { + urlQuery += "&y=" + year.Value.ToString(CultureInfo.InvariantCulture); + } + + // &s means search and returns a list of results as opposed to t + if (isSearch) + { + urlQuery += "&s=" + WebUtility.UrlEncode(name); + } + else + { + urlQuery += "&t=" + WebUtility.UrlEncode(name); + } + urlQuery += "&type=" + type; + } + else + { + urlQuery += "&i=" + 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, _appHost, cancellationToken); + + using (var response = await OmdbProvider.GetOmdbResponse(_httpClient, url, cancellationToken).ConfigureAwait(false)) + { + using (var stream = response.Content) + { + var resultList = new List<SearchResult>(); + + if (isSearch) + { + var searchResultList = await _jsonSerializer.DeserializeFromStreamAsync<SearchResultList>(stream).ConfigureAwait(false); + if (searchResultList != null && searchResultList.Search != null) + { + resultList.AddRange(searchResultList.Search); + } + } + else + { + var result = await _jsonSerializer.DeserializeFromStreamAsync<SearchResult>(stream).ConfigureAwait(false); + if (string.Equals(result.Response, "true", StringComparison.OrdinalIgnoreCase)) + { + resultList.Add(result); + } + } + + 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(MetadataProviders.Imdb, result.imdbID); + + if (result.Year.Length > 0 + && int.TryParse(result.Year.Substring(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; + }); + } + } + } + + public Task<MetadataResult<Trailer>> GetMetadata(TrailerInfo info, CancellationToken cancellationToken) + { + return GetMovieResult<Trailer>(info, cancellationToken); + } + + public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(TrailerInfo searchInfo, CancellationToken cancellationToken) + { + return GetSearchResults(searchInfo, "movie", cancellationToken); + } + + public string Name => "The Open Movie Database"; + + public async Task<MetadataResult<Series>> GetMetadata(SeriesInfo info, CancellationToken cancellationToken) + { + var result = new MetadataResult<Series> + { + Item = new Series(), + QueriedById = true + }; + + var imdbId = info.GetProviderId(MetadataProviders.Imdb); + if (string.IsNullOrWhiteSpace(imdbId)) + { + imdbId = await GetSeriesImdbId(info, cancellationToken).ConfigureAwait(false); + result.QueriedById = false; + } + + if (!string.IsNullOrEmpty(imdbId)) + { + result.Item.SetProviderId(MetadataProviders.Imdb, imdbId); + result.HasMetadata = true; + + await new OmdbProvider(_jsonSerializer, _httpClient, _fileSystem, _appHost, _configurationManager).Fetch(result, imdbId, info.MetadataLanguage, info.MetadataCountryCode, cancellationToken).ConfigureAwait(false); + } + + return result; + } + + public Task<MetadataResult<Movie>> GetMetadata(MovieInfo info, CancellationToken cancellationToken) + { + return GetMovieResult<Movie>(info, cancellationToken); + } + + private async Task<MetadataResult<T>> GetMovieResult<T>(ItemLookupInfo info, CancellationToken cancellationToken) + where T : BaseItem, new() + { + var result = new MetadataResult<T> + { + Item = new T(), + QueriedById = true + }; + + var imdbId = info.GetProviderId(MetadataProviders.Imdb); + if (string.IsNullOrWhiteSpace(imdbId)) + { + imdbId = await GetMovieImdbId(info, cancellationToken).ConfigureAwait(false); + result.QueriedById = false; + } + + if (!string.IsNullOrEmpty(imdbId)) + { + result.Item.SetProviderId(MetadataProviders.Imdb, imdbId); + result.HasMetadata = true; + + await new OmdbProvider(_jsonSerializer, _httpClient, _fileSystem, _appHost, _configurationManager).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 == null ? null : first.GetProviderId(MetadataProviders.Imdb); + } + + private async Task<string> GetSeriesImdbId(SeriesInfo info, CancellationToken cancellationToken) + { + var results = await GetSearchResultsInternal(info, "series", false, cancellationToken).ConfigureAwait(false); + var first = results.FirstOrDefault(); + return first == null ? null : first.GetProviderId(MetadataProviders.Imdb); + } + + public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken) + { + return _httpClient.GetResponse(new HttpRequestOptions + { + CancellationToken = cancellationToken, + Url = url + }); + } + + class SearchResult + { + public string Title { get; set; } + public string Year { get; set; } + public string Rated { get; set; } + public string Released { get; set; } + public string Season { get; set; } + public string Episode { get; set; } + public string Runtime { get; set; } + public string Genre { get; set; } + public string Director { get; set; } + public string Writer { get; set; } + public string Actors { get; set; } + public string Plot { get; set; } + public string Language { get; set; } + public string Country { get; set; } + public string Awards { get; set; } + public string Poster { get; set; } + public string Metascore { get; set; } + public string imdbRating { get; set; } + public string imdbVotes { get; set; } + public string imdbID { get; set; } + public string seriesID { get; set; } + public string Type { get; set; } + public string Response { get; set; } + } + + private class SearchResultList + { + /// <summary> + /// Gets or sets the results. + /// </summary> + /// <value>The results.</value> + public List<SearchResult> Search { get; set; } + } + + } +} |
