@ -1,4 +1,5 @@
using MediaBrowser.Common.Net ;
using MediaBrowser.Common.Configuration ;
using MediaBrowser.Common.Net ;
using MediaBrowser.Controller.Configuration ;
using MediaBrowser.Controller.Entities ;
using MediaBrowser.Controller.Entities.Movies ;
@ -193,7 +194,7 @@ namespace MediaBrowser.Providers.Movies
protected override bool NeedsRefreshInternal ( BaseItem item , BaseProviderInfo providerInfo )
{
if ( HasAltMeta ( item ) )
if ( HasAltMeta ( item ) & & ! ConfigurationManager . Configuration . EnableTmdbUpdates )
return false ;
// Boxsets require two passes because we need the children to be refreshed
@ -205,54 +206,64 @@ namespace MediaBrowser.Providers.Movies
return base . NeedsRefreshInternal ( item , providerInfo ) ;
}
/// <summary>
/// Fetches metadata and returns true or false indicating if any work that requires persistence was done
/// </summary>
/// <param name="item">The item.</param>
/// <param name="force">if set to <c>true</c> [force].</param>
/// <param name="cancellationToken">The cancellation token</param>
/// <returns>Task{System.Boolean}.</returns>
public override async Task < bool > FetchAsync ( BaseItem item , bool force , CancellationToken cancellationToken )
protected override bool NeedsRefreshBasedOnCompareDate ( BaseItem item , BaseProviderInfo providerInfo )
{
cancellationToken . ThrowIfCancellationRequested ( ) ;
var language = ConfigurationManager . Configuration . PreferredMetadataLanguage ;
await FetchMovieData ( item , cancellationToken ) . ConfigureAwait ( fals e) ;
var path = GetDataFilePath ( item , language ) ;
SetLastRefreshed ( item , DateTime . UtcNow ) ;
return true ;
if ( ! string . IsNullOrEmpty ( path ) )
{
var fileInfo = new FileInfo ( path ) ;
if ( fileInfo . Exists )
{
return fileInfo . LastWriteTimeUtc > providerInfo . LastRefreshed ;
}
}
return base . NeedsRefreshBasedOnCompareDate ( item , providerInfo ) ;
}
/// <summary>
/// Determines whether [has alt meta] [the specified item].
/// Gets the movie data path .
/// </summary>
/// <param name="item">The item.</param>
/// <returns><c>true</c> if [has alt meta] [the specified item]; otherwise, <c>false</c>.</returns>
internal static bool HasAltMeta ( BaseItem item )
{
if ( item is BoxSet )
/// <param name=" appPaths">The app paths .</param>
/// < param name="isBoxSet">if set to <c>true</c> [is box set].</param >
/// <param name="tmdbId">The TMDB id.</param>
/// <returns>System.String.</returns>
internal static string GetMovieDataPath ( IApplicationPaths appPaths , bool isBoxSet , string tmdbId )
{
return item . LocationType = = LocationType . FileSystem & & item . ResolveArgs . ContainsMetaFileByName ( "collection.xml" ) ;
}
var dataPath = isBoxSet ? GetBoxSetsDataPath ( appPaths ) : GetMoviesDataPath ( appPaths ) ;
var path = MovieXmlSaver . GetMovieSavePath ( item ) ;
return Path . Combine ( dataPath , tmdbId ) ;
}
if ( item . LocationType = = LocationType . FileSystem )
internal static string GetMoviesDataPath ( IApplicationPaths appPaths )
{
// If mixed with multiple movies in one folder, resolve args won't have the file system children
return item . ResolveArgs . ContainsMetaFileByName ( Path . GetFileName ( path ) ) | | File . Exists ( path ) ;
var dataPath = Path . Combine ( appPaths . DataPath , "tmdb-movies" ) ;
return dataPath ;
}
return false ;
internal static string GetBoxSetsDataPath ( IApplicationPaths appPaths )
{
var dataPath = Path . Combine ( appPaths . DataPath , "tmdb-collections" ) ;
return dataPath ;
}
/// <summary>
/// Fetches the movie data.
/// Fetches metadata and returns true or false indicating if any work that requires persistence was done
/// </summary>
/// <param name="item">The item.</param>
/// <param name="cancellationToken"></param>
/// <returns>Task.</returns>
private async Task FetchMovieData ( BaseItem item , CancellationToken cancellationToken )
/// <param name="force">if set to <c>true</c> [force].</param>
/// <param name="cancellationToken">The cancellation token</param>
/// <returns>Task{System.Boolean}.</returns>
public override async Task < bool > FetchAsync ( BaseItem item , bool force , CancellationToken cancellationToken )
{
cancellationToken . ThrowIfCancellationRequested ( ) ;
var id = item . GetProviderId ( MetadataProviders . Tmdb ) ;
if ( string . IsNullOrEmpty ( id ) )
@ -263,20 +274,45 @@ namespace MediaBrowser.Providers.Movies
if ( string . IsNullOrEmpty ( id ) )
{
id = await FindId ( item , cancellationToken ) . ConfigureAwait ( false ) ;
}
if ( ! string . IsNullOrEmpty ( id ) )
{
Logger . Debug ( "MovieDbProvider - getting movie info with id: " + id ) ;
item . SetProviderId ( MetadataProviders . Tmdb , id ) ;
}
}
if ( ! string . IsNullOrEmpty ( id ) )
{
cancellationToken . ThrowIfCancellationRequested ( ) ;
await FetchMovieData ( item , id , cancellationToken) . ConfigureAwait ( false ) ;
await FetchMovieData ( item , id , force, cancellationToken) . ConfigureAwait ( false ) ;
}
else
SetLastRefreshed ( item , DateTime . UtcNow ) ;
return true ;
}
/// <summary>
/// Determines whether [has alt meta] [the specified item].
/// </summary>
/// <param name="item">The item.</param>
/// <returns><c>true</c> if [has alt meta] [the specified item]; otherwise, <c>false</c>.</returns>
internal static bool HasAltMeta ( BaseItem item )
{
if ( item is BoxSet )
{
return item . LocationType = = LocationType . FileSystem & & item . ResolveArgs . ContainsMetaFileByName ( "collection.xml" ) ;
}
var path = MovieXmlSaver . GetMovieSavePath ( item ) ;
if ( item . LocationType = = LocationType . FileSystem )
{
Logger . Info ( "MovieDBProvider could not find " + item . Name + ". Check name on themoviedb.org." ) ;
// If mixed with multiple movies in one folder, resolve args won't have the file system children
return item . ResolveArgs . ContainsMetaFileByName ( Path . GetFileName ( path ) ) | | File . Exists ( path ) ;
}
return false ;
}
/// <summary>
@ -453,42 +489,114 @@ namespace MediaBrowser.Providers.Movies
return WebUtility . UrlEncode ( name ) ;
}
private readonly CultureInfo _usCulture = new CultureInfo ( "en-US" ) ;
/// <summary>
/// Fetches the movie data.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="id">The id.</param>
/// <param name="isForcedRefresh">if set to <c>true</c> [is forced refresh].</param>
/// <param name="cancellationToken">The cancellation token</param>
/// <returns>Task.</returns>
pr otected async Task FetchMovieData ( BaseItem item , string id , CancellationToken cancellationToken )
pr ivate async Task FetchMovieData ( BaseItem item , string id , bool isForcedRefresh , CancellationToken cancellationToken )
{
cancellationToken . ThrowIfCancellationRequested ( ) ;
// Id could be ImdbId or TmdbId
var language = ConfigurationManager . Configuration . PreferredMetadataLanguage ;
var dataFilePath = GetDataFilePath ( item , language ) ;
if ( String . IsNullOrEmpty ( id ) )
var hasAltMeta = HasAltMeta ( item ) ;
var isRefreshingDueToTmdbUpdate = hasAltMeta & & ! isForcedRefresh ;
if ( string . IsNullOrEmpty ( dataFilePath ) | | ! File . Exists ( dataFilePath ) )
{
Logger . Info ( "MoviedbProvider: Ignoring " + item . Name + " because ID forced blank." ) ;
return ;
var isBoxSet = item is BoxSet ;
var mainResult = await FetchMainResult ( id , isBoxSet , cancellationToken ) . ConfigureAwait ( false ) ;
if ( mainResult = = null ) return ;
var path = GetMovieDataPath ( ConfigurationManager . ApplicationPaths , isBoxSet , mainResult . id . ToString ( _usCulture ) ) ;
dataFilePath = Path . Combine ( path , language + ".json" ) ;
var directory = Path . GetDirectoryName ( dataFilePath ) ;
Directory . CreateDirectory ( directory ) ;
JsonSerializer . SerializeToFile ( mainResult , dataFilePath ) ;
isRefreshingDueToTmdbUpdate = false ;
}
item . SetProviderId ( MetadataProviders . Tmdb , id ) ;
if ( isForcedRefresh | | ConfigurationManager . Configuration . EnableTmdbUpdates | | ! hasAltMeta )
{
dataFilePath = GetDataFilePath ( item , language ) ;
var mainResult = JsonSerializer . DeserializeFromFile < CompleteMovieData > ( dataFilePath ) ;
var mainResult = await FetchMainResult ( item , id , cancellationToken ) . ConfigureAwait ( false ) ;
ProcessMainInfo ( item , mainResult , isRefreshingDueToTmdbUpdate ) ;
}
}
/// <summary>
/// Downloads the movie info.
/// </summary>
/// <param name="id">The id.</param>
/// <param name="isBoxSet">if set to <c>true</c> [is box set].</param>
/// <param name="dataPath">The data path.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
internal async Task DownloadMovieInfo ( string id , bool isBoxSet , string dataPath , CancellationToken cancellationToken )
{
var language = ConfigurationManager . Configuration . PreferredMetadataLanguage ;
var mainResult = await FetchMainResult ( id , isBoxSet , cancellationToken ) . ConfigureAwait ( false ) ;
if ( mainResult = = null ) return ;
ProcessMainInfo ( item , mainResult ) ;
var dataFilePath = Path . Combine ( dataPath , language + ".json" ) ;
Directory . CreateDirectory ( dataPath ) ;
JsonSerializer . SerializeToFile ( mainResult , dataFilePath ) ;
}
/// <summary>
/// Fetches the main result.
/// Gets the data file path .
/// </summary>
/// <param name="item">The item.</param>
/// <param name="language">The language.</param>
/// <returns>System.String.</returns>
private string GetDataFilePath ( BaseItem item , string language )
{
var id = item . GetProviderId ( MetadataProviders . Tmdb ) ;
if ( string . IsNullOrEmpty ( id ) )
{
return null ;
}
var path = GetMovieDataPath ( ConfigurationManager . ApplicationPaths , item is BoxSet , id ) ;
path = Path . Combine ( path , language + ".json" ) ;
return path ;
}
/// <summary>
/// Fetches the main result.
/// </summary>
/// <param name="id">The id.</param>
/// <param name="isBoxSet">if set to <c>true</c> [is box set].</param>
/// <param name="cancellationToken">The cancellation token</param>
/// <returns>Task{CompleteMovieData}.</returns>
protected async Task < CompleteMovieData > FetchMainResult ( BaseItem item , string id , CancellationToken cancellationToken )
protected async Task < CompleteMovieData > FetchMainResult ( string id , bool isBoxSet , CancellationToken cancellationToken )
{
var baseUrl = item is BoxSet ? GetBoxSetInfo3 : GetMovieInfo3 ;
var baseUrl = i sBoxSet ? GetBoxSetInfo3 : GetMovieInfo3 ;
string url = string . Format ( baseUrl , id , ApiKey , ConfigurationManager . Configuration . PreferredMetadataLanguage ) ;
CompleteMovieData mainResult ;
@ -529,7 +637,7 @@ namespace MediaBrowser.Providers.Movies
if ( String . IsNullOrEmpty ( mainResult . overview ) )
{
Logger . Error ( "MovieDbProvider - Unable to find information for " + item . Name + " (id:" + id + ")" ) ;
Logger . Error ( "MovieDbProvider - Unable to find information for (id:" + id + ")" ) ;
return null ;
}
}
@ -542,7 +650,8 @@ namespace MediaBrowser.Providers.Movies
/// </summary>
/// <param name="movie">The movie.</param>
/// <param name="movieData">The movie data.</param>
protected virtual void ProcessMainInfo ( BaseItem movie , CompleteMovieData movieData )
/// <param name="isRefreshingDueToTmdbUpdate">if set to <c>true</c> [is refreshing due to TMDB update].</param>
protected virtual void ProcessMainInfo ( BaseItem movie , CompleteMovieData movieData , bool isRefreshingDueToTmdbUpdate )
{
if ( movie ! = null & & movieData ! = null )
{
@ -582,10 +691,17 @@ namespace MediaBrowser.Providers.Movies
// tmdb appears to have unified their numbers to always report "7.3" regardless of country
// so I removed the culture-specific processing here because it was not working for other countries -ebr
if ( float . TryParse ( voteAvg , NumberStyles . AllowDecimalPoint , CultureInfo . InvariantCulture , out rating ) )
// Don't import this when responding to tmdb updates because we don't want to blow away imdb data
if ( ! isRefreshingDueToTmdbUpdate & & float . TryParse ( voteAvg , NumberStyles . AllowDecimalPoint , CultureInfo . InvariantCulture , out rating ) )
{
movie . CommunityRating = rating ;
}
// Don't import this when responding to tmdb updates because we don't want to blow away imdb data
if ( ! isRefreshingDueToTmdbUpdate )
{
movie . VoteCount = movieData . vote_count ;
}
//release date and certification are retrieved based on configured country and we fall back on US if not there and to minimun release date if still no match
if ( movieData . releases ! = null & & movieData . releases . countries ! = null )
@ -668,7 +784,8 @@ namespace MediaBrowser.Providers.Movies
}
// genres
if ( movieData . genres ! = null & & ! movie . LockedFields . Contains ( MetadataFields . Genres ) )
// Don't import this when responding to tmdb updates because we don't want to blow away imdb data
if ( movieData . genres ! = null & & ! movie . LockedFields . Contains ( MetadataFields . Genres ) & & ! isRefreshingDueToTmdbUpdate )
{
movie . Genres . Clear ( ) ;