diff --git a/MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs b/MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs index b5d3443377..3c001b8c29 100644 --- a/MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbImagesProvider.cs @@ -9,6 +9,7 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -142,6 +143,23 @@ namespace MediaBrowser.Providers.Movies return base.NeedsRefreshInternal(item, providerInfo); } + protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo) + { + var path = MovieDbProvider.Current.GetDataFilePath(item, "default"); + + if (!string.IsNullOrEmpty(path)) + { + var fileInfo = new FileInfo(path); + + if (fileInfo.Exists) + { + return fileInfo.LastWriteTimeUtc > providerInfo.LastRefreshed; + } + } + + return false; + } + /// /// Fetches metadata and returns true or false indicating if any work that requires persistence was done /// @@ -151,18 +169,15 @@ namespace MediaBrowser.Providers.Movies /// Task{System.Boolean}. public override async Task FetchAsync(BaseItem item, bool force, CancellationToken cancellationToken) { - BaseProviderInfo data; + var images = FetchImages(item, item.GetProviderId(MetadataProviders.Tmdb), cancellationToken); + + var status = ProviderRefreshStatus.Success; - if (!item.ProviderData.TryGetValue(Id, out data)) + if (images != null) { - data = new BaseProviderInfo(); - item.ProviderData[Id] = data; + status = await ProcessImages(item, images, cancellationToken).ConfigureAwait(false); } - var images = await FetchImages(item, item.GetProviderId(MetadataProviders.Tmdb), cancellationToken).ConfigureAwait(false); - - var status = await ProcessImages(item, images, cancellationToken).ConfigureAwait(false); - SetLastRefreshed(item, DateTime.UtcNow, status); return true; } @@ -174,18 +189,21 @@ namespace MediaBrowser.Providers.Movies /// The id. /// The cancellation token. /// Task{MovieImages}. - private async Task FetchImages(BaseItem item, string id, CancellationToken cancellationToken) + private MovieDbProvider.Images FetchImages(BaseItem item, string id, CancellationToken cancellationToken) { - using (var json = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions - { - Url = string.Format(GetImages, id, MovieDbProvider.ApiKey, item is BoxSet ? "collection" : "movie"), - CancellationToken = cancellationToken, - AcceptHeader = MovieDbProvider.AcceptHeader + var path = MovieDbProvider.Current.GetDataFilePath(item, "default"); - }).ConfigureAwait(false)) + if (!string.IsNullOrEmpty(path)) { - return _jsonSerializer.DeserializeFromStream(json); + var fileInfo = new FileInfo(path); + + if (fileInfo.Exists) + { + return _jsonSerializer.DeserializeFromFile(path).images; + } } + + return null; } /// @@ -195,14 +213,14 @@ namespace MediaBrowser.Providers.Movies /// The images. /// The cancellation token /// Task. - protected virtual async Task ProcessImages(BaseItem item, MovieImages images, CancellationToken cancellationToken) + private async Task ProcessImages(BaseItem item, MovieDbProvider.Images images, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var status = ProviderRefreshStatus.Success; var eligiblePosters = images.posters == null ? - new List() : + new List() : images.posters.Where(i => i.width >= ConfigurationManager.Configuration.MinMoviePosterWidth) .ToList(); @@ -255,7 +273,7 @@ namespace MediaBrowser.Providers.Movies cancellationToken.ThrowIfCancellationRequested(); - var eligibleBackdrops = images.backdrops == null ? new List() : + var eligibleBackdrops = images.backdrops == null ? new List() : images.backdrops.Where(i => i.width >= ConfigurationManager.Configuration.MinMovieBackdropWidth) .ToList(); @@ -294,107 +312,5 @@ namespace MediaBrowser.Providers.Movies return status; } - - /// - /// Class Backdrop - /// - protected class Backdrop - { - /// - /// Gets or sets the file_path. - /// - /// The file_path. - public string file_path { get; set; } - /// - /// Gets or sets the width. - /// - /// The width. - public int width { get; set; } - /// - /// Gets or sets the height. - /// - /// The height. - public int height { get; set; } - /// - /// Gets or sets the iso_639_1. - /// - /// The iso_639_1. - public string iso_639_1 { get; set; } - /// - /// Gets or sets the aspect_ratio. - /// - /// The aspect_ratio. - public double aspect_ratio { get; set; } - /// - /// Gets or sets the vote_average. - /// - /// The vote_average. - public double vote_average { get; set; } - /// - /// Gets or sets the vote_count. - /// - /// The vote_count. - public int vote_count { get; set; } - } - - /// - /// Class Poster - /// - protected class Poster - { - /// - /// Gets or sets the file_path. - /// - /// The file_path. - public string file_path { get; set; } - /// - /// Gets or sets the width. - /// - /// The width. - public int width { get; set; } - /// - /// Gets or sets the height. - /// - /// The height. - public int height { get; set; } - /// - /// Gets or sets the iso_639_1. - /// - /// The iso_639_1. - public string iso_639_1 { get; set; } - /// - /// Gets or sets the aspect_ratio. - /// - /// The aspect_ratio. - public double aspect_ratio { get; set; } - /// - /// Gets or sets the vote_average. - /// - /// The vote_average. - public double vote_average { get; set; } - /// - /// Gets or sets the vote_count. - /// - /// The vote_count. - public int vote_count { get; set; } - } - - /// - /// Class MovieImages - /// - protected class MovieImages - { - /// - /// Gets or sets the backdrops. - /// - /// The backdrops. - public List backdrops { get; set; } - /// - /// Gets or sets the posters. - /// - /// The posters. - public List posters { get; set; } - } - } } diff --git a/MediaBrowser.Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Providers/Movies/MovieDbProvider.cs index 6d467fc6c9..e23b53dfce 100644 --- a/MediaBrowser.Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Providers/Movies/MovieDbProvider.cs @@ -181,8 +181,8 @@ namespace MediaBrowser.Providers.Movies private const string TmdbConfigUrl = "http://api.themoviedb.org/3/configuration?api_key={0}"; private const string Search3 = @"http://api.themoviedb.org/3/search/{3}?api_key={1}&query={0}&language={2}"; - private const string GetMovieInfo3 = @"http://api.themoviedb.org/3/movie/{0}?api_key={1}&language={2}&append_to_response=casts,releases,images,keywords,trailers"; - private const string GetBoxSetInfo3 = @"http://api.themoviedb.org/3/collection/{0}?api_key={1}&language={2}&append_to_response=images"; + private const string GetMovieInfo3 = @"http://api.themoviedb.org/3/movie/{0}?api_key={1}&append_to_response=casts,releases,images,keywords,trailers"; + private const string GetBoxSetInfo3 = @"http://api.themoviedb.org/3/collection/{0}?api_key={1}&append_to_response=images"; internal static string ApiKey = "f6bd687ffa63cd282b6ff2c6877f2669"; internal static string AcceptHeader = "application/json,image/*"; @@ -517,15 +517,22 @@ namespace MediaBrowser.Providers.Movies if (mainResult == null) return; - var path = GetMovieDataPath(ConfigurationManager.ApplicationPaths, isBoxSet, mainResult.id.ToString(_usCulture)); + var movieDataPath = GetMovieDataPath(ConfigurationManager.ApplicationPaths, isBoxSet, mainResult.id.ToString(_usCulture)); - dataFilePath = Path.Combine(path, language + ".json"); + dataFilePath = Path.Combine(movieDataPath, language + ".json"); var directory = Path.GetDirectoryName(dataFilePath); Directory.CreateDirectory(directory); JsonSerializer.SerializeToFile(mainResult, dataFilePath); + + // Now get the language-less version + mainResult = await FetchMainResult(id, isBoxSet, null, cancellationToken).ConfigureAwait(false); + + dataFilePath = Path.Combine(movieDataPath, "default.json"); + + JsonSerializer.SerializeToFile(mainResult, dataFilePath); } if (isForcedRefresh || ConfigurationManager.Configuration.EnableTmdbUpdates || !hasAltMeta) @@ -559,6 +566,13 @@ namespace MediaBrowser.Providers.Movies Directory.CreateDirectory(dataPath); JsonSerializer.SerializeToFile(mainResult, dataFilePath); + + // Now get the language-less version + mainResult = await FetchMainResult(id, isBoxSet, null, cancellationToken).ConfigureAwait(false); + + dataFilePath = Path.Combine(dataPath, "default.json"); + + JsonSerializer.SerializeToFile(mainResult, dataFilePath); } /// @@ -567,7 +581,7 @@ namespace MediaBrowser.Providers.Movies /// The item. /// The language. /// System.String. - private string GetDataFilePath(BaseItem item, string language) + internal string GetDataFilePath(BaseItem item, string language) { var id = item.GetProviderId(MetadataProviders.Tmdb); @@ -591,11 +605,17 @@ namespace MediaBrowser.Providers.Movies /// The language. /// The cancellation token /// Task{CompleteMovieData}. - protected async Task FetchMainResult(string id, bool isBoxSet, string language, CancellationToken cancellationToken) + private async Task FetchMainResult(string id, bool isBoxSet, string language, CancellationToken cancellationToken) { var baseUrl = isBoxSet ? GetBoxSetInfo3 : GetMovieInfo3; - string url = string.Format(baseUrl, id, ApiKey, language); + var url = string.Format(baseUrl, id, ApiKey); + + if (!string.IsNullOrEmpty(language)) + { + url += "&language=" + language; + } + CompleteMovieData mainResult; cancellationToken.ThrowIfCancellationRequested(); @@ -615,7 +635,7 @@ namespace MediaBrowser.Providers.Movies if (mainResult != null && string.IsNullOrEmpty(mainResult.overview)) { - if (language.ToLower() != "en") + if (!string.IsNullOrEmpty(language) && !string.Equals(language, "en", StringComparison.OrdinalIgnoreCase)) { Logger.Info("MovieDbProvider couldn't find meta for language " + language + ". Trying English..."); @@ -647,7 +667,7 @@ namespace MediaBrowser.Providers.Movies /// /// The movie. /// The movie data. - protected virtual void ProcessMainInfo(BaseItem movie, CompleteMovieData movieData) + private void ProcessMainInfo(BaseItem movie, CompleteMovieData movieData) { if (movie != null && movieData != null) { @@ -871,13 +891,15 @@ namespace MediaBrowser.Providers.Movies } } - #region Result Objects - + public void Dispose() + { + Dispose(true); + } /// /// Class TmdbTitle /// - protected class TmdbTitle + internal class TmdbTitle { /// /// Gets or sets the iso_3166_1. @@ -894,7 +916,7 @@ namespace MediaBrowser.Providers.Movies /// /// Class TmdbAltTitleResults /// - protected class TmdbAltTitleResults + internal class TmdbAltTitleResults { /// /// Gets or sets the id. @@ -911,7 +933,7 @@ namespace MediaBrowser.Providers.Movies /// /// Class TmdbMovieSearchResult /// - protected class TmdbMovieSearchResult + internal class TmdbMovieSearchResult { /// /// Gets or sets a value indicating whether this is adult. @@ -972,7 +994,7 @@ namespace MediaBrowser.Providers.Movies /// /// Class TmdbMovieSearchResults /// - protected class TmdbMovieSearchResults + internal class TmdbMovieSearchResults { /// /// Gets or sets the page. @@ -996,7 +1018,7 @@ namespace MediaBrowser.Providers.Movies public int total_results { get; set; } } - protected class BelongsToCollection + internal class BelongsToCollection { public int id { get; set; } public string name { get; set; } @@ -1004,31 +1026,31 @@ namespace MediaBrowser.Providers.Movies public string backdrop_path { get; set; } } - protected class GenreItem + internal class GenreItem { public int id { get; set; } public string name { get; set; } } - protected class ProductionCompany + internal class ProductionCompany { public string name { get; set; } public int id { get; set; } } - protected class ProductionCountry + internal class ProductionCountry { public string iso_3166_1 { get; set; } public string name { get; set; } } - protected class SpokenLanguage + internal class SpokenLanguage { public string iso_639_1 { get; set; } public string name { get; set; } } - protected class Cast + internal class Cast { public int id { get; set; } public string name { get; set; } @@ -1038,7 +1060,7 @@ namespace MediaBrowser.Providers.Movies public string profile_path { get; set; } } - protected class Crew + internal class Crew { public int id { get; set; } public string name { get; set; } @@ -1047,36 +1069,77 @@ namespace MediaBrowser.Providers.Movies public string profile_path { get; set; } } - protected class Casts + internal class Casts { public List cast { get; set; } public List crew { get; set; } } - protected class Country + internal class Country { public string iso_3166_1 { get; set; } public string certification { get; set; } public DateTime release_date { get; set; } } - protected class Releases + internal class Releases { public List countries { get; set; } } - protected class Keyword + internal class Backdrop + { + public string file_path { get; set; } + public int width { get; set; } + public int height { get; set; } + public object iso_639_1 { get; set; } + public double aspect_ratio { get; set; } + public double vote_average { get; set; } + public int vote_count { get; set; } + } + + internal class Poster + { + public string file_path { get; set; } + public int width { get; set; } + public int height { get; set; } + public string iso_639_1 { get; set; } + public double aspect_ratio { get; set; } + public double vote_average { get; set; } + public int vote_count { get; set; } + } + + internal class Images + { + public List backdrops { get; set; } + public List posters { get; set; } + } + + internal class Keyword { public int id { get; set; } public string name { get; set; } } - protected class Keywords + internal class Keywords { public List keywords { get; set; } } - protected class CompleteMovieData + internal class Youtube + { + public string name { get; set; } + public string size { get; set; } + public string source { get; set; } + } + + internal class Trailers + { + public List quicktime { get; set; } + public List youtube { get; set; } + } + + internal class CompleteMovieData { public bool adult { get; set; } public string backdrop_path { get; set; } @@ -1086,7 +1149,6 @@ namespace MediaBrowser.Providers.Movies public string homepage { get; set; } public int id { get; set; } public string imdb_id { get; set; } - public string name { get; set; } public string original_title { get; set; } public string overview { get; set; } public double popularity { get; set; } @@ -1100,27 +1162,17 @@ namespace MediaBrowser.Providers.Movies public string status { get; set; } public string tagline { get; set; } public string title { get; set; } + public string name { get; set; } public double vote_average { get; set; } public int vote_count { get; set; } public Casts casts { get; set; } public Releases releases { get; set; } + public Images images { get; set; } public Keywords keywords { get; set; } public Trailers trailers { get; set; } } - public class Trailers - { - public List youtube { get; set; } - } - - public class Youtube - { - public string name { get; set; } - public string size { get; set; } - public string source { get; set; } - } - - public class TmdbImageSettings + internal class TmdbImageSettings { public List backdrop_sizes { get; set; } public string base_url { get; set; } @@ -1128,15 +1180,9 @@ namespace MediaBrowser.Providers.Movies public List profile_sizes { get; set; } } - public class TmdbSettingsResult + internal class TmdbSettingsResult { public TmdbImageSettings images { get; set; } } - #endregion - - public void Dispose() - { - Dispose(true); - } } } diff --git a/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs b/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs index 51d31cd338..7d46d7060d 100644 --- a/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs +++ b/MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs @@ -97,6 +97,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators var sources = additionalBackdrops .Select(musicArtist.GetImageSourceInfo) + .Where(i => i != null) .ToList(); foreach (var path in additionalBackdrops)