using MediaBrowser.Common.Net; using MediaBrowser.Controller.Channels; 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.Channels; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Providers; using MediaBrowser.Model.Serialization; using MediaBrowser.Providers.Movies; using MediaBrowser.Providers.TV; using System; using System.Collections.Generic; using System.Globalization; using System.Net; using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Providers.Omdb { public class OmdbItemProvider : IRemoteMetadataProvider, IRemoteMetadataProvider, IRemoteMetadataProvider { private readonly IJsonSerializer _jsonSerializer; private readonly IHttpClient _httpClient; private readonly ILogger _logger; private readonly ILibraryManager _libraryManager; public OmdbItemProvider(IJsonSerializer jsonSerializer, IHttpClient httpClient, ILogger logger, ILibraryManager libraryManager) { _jsonSerializer = jsonSerializer; _httpClient = httpClient; _logger = logger; _libraryManager = libraryManager; } public Task> GetSearchResults(SeriesInfo searchInfo, CancellationToken cancellationToken) { return GetSearchResults(searchInfo, "series", cancellationToken); } public Task> GetSearchResults(MovieInfo searchInfo, CancellationToken cancellationToken) { return GetSearchResults(searchInfo, "movie", cancellationToken); } public async Task> GetSearchResults(ItemLookupInfo searchInfo, string type, CancellationToken cancellationToken) { var list = new List(); var imdbId = searchInfo.GetProviderId(MetadataProviders.Imdb); if (!string.IsNullOrWhiteSpace(imdbId)) { return list; } var url = "http://www.omdbapi.com/?plot=short&r=json"; var name = searchInfo.Name; var year = searchInfo.Year; var parsedName = _libraryManager.ParseName(name); var yearInName = parsedName.Year; name = parsedName.Name; year = year ?? yearInName; if (year.HasValue) { url += "&y=" + year.Value.ToString(CultureInfo.InvariantCulture); } url += "&t=" + WebUtility.UrlEncode(name); url += "&type=" + type; using (var stream = await _httpClient.Get(new HttpRequestOptions { Url = url, ResourcePool = OmdbProvider.ResourcePool, CancellationToken = cancellationToken, CacheMode = CacheMode.Unconditional, CacheLength = TimeSpan.FromDays(7) }).ConfigureAwait(false)) { var result = _jsonSerializer.DeserializeFromStream(stream); if (string.Equals(result.Response, "true", StringComparison.OrdinalIgnoreCase)) { var item = new RemoteSearchResult(); item.SearchProviderName = Name; item.Name = result.Title; item.SetProviderId(MetadataProviders.Imdb, result.imdbID); int parsedYear; if (int.TryParse(result.Year, NumberStyles.Any, CultureInfo.InvariantCulture, out parsedYear)) { item.ProductionYear = parsedYear; } if (!string.IsNullOrWhiteSpace(result.Poster) && !string.Equals(result.Poster, "N/A", StringComparison.OrdinalIgnoreCase)) { item.ImageUrl = result.Poster; } list.Add(item); } } return list; } public Task> GetMetadata(ChannelItemLookupInfo info, CancellationToken cancellationToken) { if (info.ContentType != ChannelMediaContentType.MovieExtra || info.ExtraType != ExtraType.Trailer) { return Task.FromResult(new MetadataResult()); } return GetMovieResult(info, cancellationToken); } public Task> GetSearchResults(ChannelItemLookupInfo searchInfo, CancellationToken cancellationToken) { if (searchInfo.ContentType != ChannelMediaContentType.MovieExtra || searchInfo.ExtraType != ExtraType.Trailer) { return Task.FromResult>(new List()); } return GetSearchResults(searchInfo, "movie", cancellationToken); } public string Name { get { return "The Open Movie Database"; } } public async Task> GetMetadata(SeriesInfo info, CancellationToken cancellationToken) { var result = new MetadataResult { Item = new Series() }; var searchResult = await GetSeriesImdbId(info, cancellationToken).ConfigureAwait(false); result.Item.Name = searchResult.Item4; if (!string.IsNullOrEmpty(searchResult.Item1)) { result.Item.SetProviderId(MetadataProviders.Imdb, searchResult.Item1); } if (!string.IsNullOrEmpty(searchResult.Item2)) { result.Item.SetProviderId(MetadataProviders.Tmdb, searchResult.Item2); } if (!string.IsNullOrEmpty(searchResult.Item3)) { result.Item.SetProviderId(MetadataProviders.Tvdb, searchResult.Item3); } var imdbId = result.Item.GetProviderId(MetadataProviders.Imdb); if (!string.IsNullOrEmpty(info.GetProviderId(MetadataProviders.Imdb))) { result.Item.SetProviderId(MetadataProviders.Imdb, imdbId); result.HasMetadata = true; await new OmdbProvider(_jsonSerializer, _httpClient).Fetch(result.Item, imdbId, cancellationToken) .ConfigureAwait(false); } return result; } public Task> GetMetadata(MovieInfo info, CancellationToken cancellationToken) { return GetMovieResult(info, cancellationToken); } private async Task> GetMovieResult(ItemLookupInfo info, CancellationToken cancellationToken) where T : Video, new() { var result = new MetadataResult { Item = new T() }; var imdbId = info.GetProviderId(MetadataProviders.Imdb); var searchResult = await GetMovieImdbId(info, cancellationToken).ConfigureAwait(false); result.Item.Name = searchResult.Item3; if (string.IsNullOrEmpty(imdbId)) { imdbId = searchResult.Item1; if (!string.IsNullOrEmpty(searchResult.Item2)) { result.Item.SetProviderId(MetadataProviders.Tmdb, searchResult.Item2); } } if (!string.IsNullOrEmpty(imdbId)) { result.Item.SetProviderId(MetadataProviders.Imdb, imdbId); result.HasMetadata = true; await new OmdbProvider(_jsonSerializer, _httpClient).Fetch(result.Item, imdbId, cancellationToken) .ConfigureAwait(false); } return result; } private async Task> GetMovieImdbId(ItemLookupInfo info, CancellationToken cancellationToken) { var result = await new GenericMovieDbInfo(_logger, _jsonSerializer, _libraryManager).GetMetadata(info, cancellationToken) .ConfigureAwait(false); var imdb = result.HasMetadata ? result.Item.GetProviderId(MetadataProviders.Imdb) : null; var tmdb = result.HasMetadata ? result.Item.GetProviderId(MetadataProviders.Tmdb) : null; var name = result.HasMetadata ? result.Item.Name : null; return new Tuple(imdb, tmdb, name); } private async Task> GetSeriesImdbId(SeriesInfo info, CancellationToken cancellationToken) { //var result = await TvdbSeriesProvider.Current.GetMetadata(info, cancellationToken) // .ConfigureAwait(false); //var imdb = result.HasMetadata ? result.Item.GetProviderId(MetadataProviders.Imdb) : null; //var tvdb = result.HasMetadata ? result.Item.GetProviderId(MetadataProviders.Tvdb) : null; //var name = result.HasMetadata ? result.Item.Name : null; //return new Tuple(imdb, tvdb, name); var result = await MovieDbSeriesProvider.Current.GetMetadata(info, cancellationToken) .ConfigureAwait(false); var imdb = result.HasMetadata ? result.Item.GetProviderId(MetadataProviders.Imdb) : null; var tmdb = result.HasMetadata ? result.Item.GetProviderId(MetadataProviders.Tmdb) : null; var tvdb = result.HasMetadata ? result.Item.GetProviderId(MetadataProviders.Tvdb) : null; var name = result.HasMetadata ? result.Item.Name : null; return new Tuple(imdb, tmdb, tvdb, name); } public Task GetImageResponse(string url, CancellationToken cancellationToken) { return _httpClient.GetResponse(new HttpRequestOptions { CancellationToken = cancellationToken, Url = url, ResourcePool = OmdbProvider.ResourcePool }); } class SearchResult { public string Title { get; set; } public string Year { get; set; } public string Rated { get; set; } public string Released { 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 Type { get; set; } public string Response { get; set; } } } }