diff --git a/MediaBrowser.Providers/Movies/MovieDbSearch.cs b/MediaBrowser.Providers/Movies/MovieDbSearch.cs index 6fb7954119..e8eeab9c53 100644 --- a/MediaBrowser.Providers/Movies/MovieDbSearch.cs +++ b/MediaBrowser.Providers/Movies/MovieDbSearch.cs @@ -125,6 +125,18 @@ namespace MediaBrowser.Providers.Movies private async Task> GetSearchResults(string name, string type, int? year, string language, string baseImageUrl, CancellationToken cancellationToken) { + switch (type) + { + case "tv": + return await GetSearchResultsTv(name, year, language, baseImageUrl, cancellationToken); + default: + return await GetSearchResultsGeneric(name, type, year, language, baseImageUrl, cancellationToken); + } + } + + private async Task> GetSearchResultsGeneric(string name, string type, int? year, string language, string baseImageUrl, CancellationToken cancellationToken) + { + var url3 = string.Format(Search3, WebUtility.UrlEncode(name), ApiKey, language, type); using (var json = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions @@ -153,7 +165,7 @@ namespace MediaBrowser.Providers.Movies Name = i.title ?? i.name ?? i.original_title, ImageUrl = string.IsNullOrWhiteSpace(i.poster_path) ? null : baseImageUrl + i.poster_path }; - + if (!string.IsNullOrWhiteSpace(i.release_date)) { DateTime r; @@ -175,6 +187,58 @@ namespace MediaBrowser.Providers.Movies } } + private async Task> GetSearchResultsTv(string name, int? year, string language, string baseImageUrl, CancellationToken cancellationToken) + { + var url3 = string.Format(Search3, WebUtility.UrlEncode(name), ApiKey, language, "tv"); + + using (var json = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions + { + Url = url3, + CancellationToken = cancellationToken, + AcceptHeader = AcceptHeader + + }).ConfigureAwait(false)) + { + var searchResults = _json.DeserializeFromStream(json); + + var results = searchResults.results ?? new List(); + + var index = 0; + var resultTuples = results.Select(result => new Tuple(result, index++)).ToList(); + + return resultTuples.OrderBy(i => GetSearchResultOrder(i.Item1, year)) + .ThenBy(i => i.Item2) + .Select(i => i.Item1) + .Select(i => + { + var remoteResult = new RemoteSearchResult + { + SearchProviderName = MovieDbProvider.Current.Name, + Name = i.name ?? i.original_name, + ImageUrl = string.IsNullOrWhiteSpace(i.poster_path) ? null : baseImageUrl + i.poster_path + }; + + if (!string.IsNullOrWhiteSpace(i.first_air_date)) + { + DateTime r; + + // These dates are always in this exact format + if (DateTime.TryParseExact(i.first_air_date, "yyyy-MM-dd", EnUs, DateTimeStyles.None, out r)) + { + remoteResult.PremiereDate = r.ToUniversalTime(); + remoteResult.ProductionYear = remoteResult.PremiereDate.Value.Year; + } + } + + remoteResult.SetProviderId(MetadataProviders.Tmdb, i.id.ToString(EnUs)); + + return remoteResult; + + }) + .ToList(); + } + } + private int GetSearchResultOrder(TmdbMovieSearchResult result, int? year) { if (year.HasValue) @@ -192,6 +256,23 @@ namespace MediaBrowser.Providers.Movies return int.MaxValue; } + private int GetSearchResultOrder(TvResult result, int? year) + { + if (year.HasValue) + { + DateTime r; + + // These dates are always in this exact format + if (DateTime.TryParseExact(result.first_air_date, "yyyy-MM-dd", EnUs, DateTimeStyles.None, out r)) + { + // Allow one year tolernace, preserve order from Tmdb + return Math.Abs(r.Year - year.Value); + } + } + + return int.MaxValue; + } + /// /// Class TmdbMovieSearchResult /// @@ -288,9 +369,9 @@ namespace MediaBrowser.Providers.Movies public class TvResult { public string backdrop_path { get; set; } + public string first_air_date { get; set; } public int id { get; set; } public string original_name { get; set; } - public string first_air_date { get; set; } public string poster_path { get; set; } public double popularity { get; set; } public string name { get; set; } @@ -298,6 +379,33 @@ namespace MediaBrowser.Providers.Movies public int vote_count { get; set; } } + /// + /// Class TmdbTvSearchResults + /// + private class TmdbTvSearchResults + { + /// + /// Gets or sets the page. + /// + /// The page. + public int page { get; set; } + /// + /// Gets or sets the results. + /// + /// The results. + public List results { get; set; } + /// + /// Gets or sets the total_pages. + /// + /// The total_pages. + public int total_pages { get; set; } + /// + /// Gets or sets the total_results. + /// + /// The total_results. + public int total_results { get; set; } + } + public class ExternalIdLookupResult { public List movie_results { get; set; } diff --git a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs index 30aa35924a..c1ec5061d6 100644 --- a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs +++ b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs @@ -133,7 +133,8 @@ namespace MediaBrowser.Providers.Omdb item.SetProviderId(MetadataProviders.Imdb, result.imdbID); int parsedYear; - if (int.TryParse(result.Year, NumberStyles.Any, CultureInfo.InvariantCulture, out parsedYear)) + if (result.Year.Length > 0 + && int.TryParse(result.Year.Substring(0, Math.Min(result.Year.Length, 4)), NumberStyles.Any, CultureInfo.InvariantCulture, out parsedYear)) { item.ProductionYear = parsedYear; } diff --git a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs index ca4c31f755..f9817af898 100644 --- a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs @@ -389,6 +389,20 @@ namespace MediaBrowser.Providers.TV } } + var airDateNode = node.SelectSingleNode("./FirstAired"); + if (airDateNode != null) + { + var val = airDateNode.InnerText; + if (!string.IsNullOrWhiteSpace(val)) + { + DateTime date; + if (DateTime.TryParse(val, out date)) + { + searchResult.ProductionYear = date.Year; + } + } + } + foreach (var title in titles) { if (string.Equals(title, comparableName, StringComparison.OrdinalIgnoreCase))