2014-02-05 23:39:16 -05:00
using MediaBrowser.Controller.Entities ;
using MediaBrowser.Controller.Entities.Movies ;
2014-11-17 21:48:22 -05:00
using MediaBrowser.Controller.Library ;
2014-02-05 23:39:16 -05:00
using MediaBrowser.Controller.Providers ;
using MediaBrowser.Model.Entities ;
using MediaBrowser.Model.Logging ;
using MediaBrowser.Model.Serialization ;
using System ;
using System.Collections.Generic ;
using System.Globalization ;
using System.IO ;
using System.Linq ;
using System.Net ;
using System.Threading ;
using System.Threading.Tasks ;
2017-05-26 02:48:54 -04:00
2016-10-25 15:02:04 -04:00
using MediaBrowser.Controller.IO ;
using MediaBrowser.Model.IO ;
2016-09-18 01:52:10 -04:00
using MediaBrowser.Model.Extensions ;
2014-02-05 23:39:16 -05:00
namespace MediaBrowser.Providers.Movies
{
public class GenericMovieDbInfo < T >
2015-03-14 16:00:32 -04:00
where T : BaseItem , new ( )
2014-02-05 23:39:16 -05:00
{
private readonly ILogger _logger ;
private readonly IJsonSerializer _jsonSerializer ;
2014-11-17 21:48:22 -05:00
private readonly ILibraryManager _libraryManager ;
2016-11-01 14:28:36 -04:00
private readonly IFileSystem _fileSystem ;
2014-02-05 23:39:16 -05:00
private readonly CultureInfo _usCulture = new CultureInfo ( "en-US" ) ;
2016-11-01 14:28:36 -04:00
public GenericMovieDbInfo ( ILogger logger , IJsonSerializer jsonSerializer , ILibraryManager libraryManager , IFileSystem fileSystem )
2014-02-05 23:39:16 -05:00
{
_logger = logger ;
_jsonSerializer = jsonSerializer ;
2014-11-17 21:48:22 -05:00
_libraryManager = libraryManager ;
2016-11-01 14:28:36 -04:00
_fileSystem = fileSystem ;
2014-02-05 23:39:16 -05:00
}
2014-02-06 22:10:13 -05:00
public async Task < MetadataResult < T > > GetMetadata ( ItemLookupInfo itemId , CancellationToken cancellationToken )
2014-02-05 23:39:16 -05:00
{
var tmdbId = itemId . GetProviderId ( MetadataProviders . Tmdb ) ;
var imdbId = itemId . GetProviderId ( MetadataProviders . Imdb ) ;
// Don't search for music video id's because it is very easy to misidentify.
if ( string . IsNullOrEmpty ( tmdbId ) & & string . IsNullOrEmpty ( imdbId ) & & typeof ( T ) ! = typeof ( MusicVideo ) )
{
2014-11-17 21:48:22 -05:00
var searchResults = await new MovieDbSearch ( _logger , _jsonSerializer , _libraryManager ) . GetMovieSearchResults ( itemId , cancellationToken ) . ConfigureAwait ( false ) ;
2014-03-01 17:34:27 -05:00
var searchResult = searchResults . FirstOrDefault ( ) ;
2014-02-15 11:36:09 -05:00
if ( searchResult ! = null )
{
2014-03-02 12:09:35 -05:00
tmdbId = searchResult . GetProviderId ( MetadataProviders . Tmdb ) ;
2014-02-15 11:36:09 -05:00
}
2014-02-05 23:39:16 -05:00
}
if ( ! string . IsNullOrEmpty ( tmdbId ) | | ! string . IsNullOrEmpty ( imdbId ) )
{
cancellationToken . ThrowIfCancellationRequested ( ) ;
2015-06-28 21:10:45 -04:00
return await FetchMovieData ( tmdbId , imdbId , itemId . MetadataLanguage , itemId . MetadataCountryCode , cancellationToken ) . ConfigureAwait ( false ) ;
2014-02-05 23:39:16 -05:00
}
2015-06-28 21:10:45 -04:00
return new MetadataResult < T > ( ) ;
2014-02-05 23:39:16 -05:00
}
/// <summary>
/// Fetches the movie data.
/// </summary>
/// <param name="tmdbId">The TMDB identifier.</param>
/// <param name="imdbId">The imdb identifier.</param>
/// <param name="language">The language.</param>
/// <param name="preferredCountryCode">The preferred country code.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{`0}.</returns>
2015-06-28 21:10:45 -04:00
private async Task < MetadataResult < T > > FetchMovieData ( string tmdbId , string imdbId , string language , string preferredCountryCode , CancellationToken cancellationToken )
2014-02-05 23:39:16 -05:00
{
2015-06-28 21:10:45 -04:00
var item = new MetadataResult < T >
{
Item = new T ( )
} ;
2014-02-05 23:39:16 -05:00
string dataFilePath = null ;
MovieDbProvider . CompleteMovieData movieInfo = null ;
// Id could be ImdbId or TmdbId
if ( string . IsNullOrEmpty ( tmdbId ) )
{
2014-09-28 16:49:43 -04:00
movieInfo = await MovieDbProvider . Current . FetchMainResult ( imdbId , false , language , cancellationToken ) . ConfigureAwait ( false ) ;
2015-10-26 01:29:32 -04:00
if ( movieInfo ! = null )
{
tmdbId = movieInfo . id . ToString ( _usCulture ) ;
2014-02-05 23:39:16 -05:00
2015-10-26 01:29:32 -04:00
dataFilePath = MovieDbProvider . Current . GetDataFilePath ( tmdbId , language ) ;
2017-05-04 14:14:45 -04:00
_fileSystem . CreateDirectory ( _fileSystem . GetDirectoryName ( dataFilePath ) ) ;
2015-10-26 01:29:32 -04:00
_jsonSerializer . SerializeToFile ( movieInfo , dataFilePath ) ;
}
2014-02-05 23:39:16 -05:00
}
2015-10-26 01:29:32 -04:00
if ( ! string . IsNullOrWhiteSpace ( tmdbId ) )
{
await MovieDbProvider . Current . EnsureMovieInfo ( tmdbId , language , cancellationToken ) . ConfigureAwait ( false ) ;
2014-02-05 23:39:16 -05:00
2015-10-26 01:29:32 -04:00
dataFilePath = dataFilePath ? ? MovieDbProvider . Current . GetDataFilePath ( tmdbId , language ) ;
movieInfo = movieInfo ? ? _jsonSerializer . DeserializeFromFile < MovieDbProvider . CompleteMovieData > ( dataFilePath ) ;
2014-02-05 23:39:16 -05:00
2016-01-21 13:50:43 -05:00
var settings = await MovieDbProvider . Current . GetTmdbSettings ( cancellationToken ) . ConfigureAwait ( false ) ;
ProcessMainInfo ( item , settings , preferredCountryCode , movieInfo ) ;
2015-10-26 01:29:32 -04:00
item . HasMetadata = true ;
}
2014-02-05 23:39:16 -05:00
return item ;
}
/// <summary>
/// Processes the main info.
/// </summary>
2015-06-28 21:10:45 -04:00
/// <param name="resultItem">The result item.</param>
2016-01-21 13:50:43 -05:00
/// <param name="settings">The settings.</param>
2014-02-05 23:39:16 -05:00
/// <param name="preferredCountryCode">The preferred country code.</param>
/// <param name="movieData">The movie data.</param>
2016-01-21 13:50:43 -05:00
private void ProcessMainInfo ( MetadataResult < T > resultItem , TmdbSettingsResult settings , string preferredCountryCode , MovieDbProvider . CompleteMovieData movieData )
2014-02-05 23:39:16 -05:00
{
2015-06-28 21:10:45 -04:00
var movie = resultItem . Item ;
2015-03-09 21:30:20 -04:00
movie . Name = movieData . GetTitle ( ) ? ? movie . Name ;
2016-10-01 16:29:24 -04:00
movie . OriginalTitle = movieData . GetOriginalTitle ( ) ;
2014-02-05 23:39:16 -05:00
// Bug in Mono: WebUtility.HtmlDecode should return null if the string is null but in Mono it generate an System.ArgumentNullException.
movie . Overview = movieData . overview ! = null ? WebUtility . HtmlDecode ( movieData . overview ) : null ;
movie . Overview = movie . Overview ! = null ? movie . Overview . Replace ( "\n\n" , "\n" ) : null ;
movie . HomePageUrl = movieData . homepage ;
if ( ! string . IsNullOrEmpty ( movieData . tagline ) )
{
2016-10-08 01:57:38 -04:00
movie . Tagline = movieData . tagline ;
2014-02-05 23:39:16 -05:00
}
2014-05-16 15:16:29 -04:00
if ( movieData . production_countries ! = null )
{
2016-10-09 03:18:43 -04:00
movie . ProductionLocations = movieData
. production_countries
. Select ( i = > i . name )
. ToList ( ) ;
2014-05-16 15:16:29 -04:00
}
2014-02-05 23:39:16 -05:00
movie . SetProviderId ( MetadataProviders . Tmdb , movieData . id . ToString ( _usCulture ) ) ;
movie . SetProviderId ( MetadataProviders . Imdb , movieData . imdb_id ) ;
if ( movieData . belongs_to_collection ! = null )
{
movie . SetProviderId ( MetadataProviders . TmdbCollection ,
movieData . belongs_to_collection . id . ToString ( CultureInfo . InvariantCulture ) ) ;
var movieItem = movie as Movie ;
if ( movieItem ! = null )
{
2016-03-13 21:34:24 -04:00
movieItem . CollectionName = movieData . belongs_to_collection . name ;
2014-02-05 23:39:16 -05:00
}
}
float rating ;
string voteAvg = movieData . vote_average . ToString ( CultureInfo . InvariantCulture ) ;
if ( float . TryParse ( voteAvg , NumberStyles . AllowDecimalPoint , CultureInfo . InvariantCulture , out rating ) )
{
movie . CommunityRating = rating ;
}
2017-06-03 03:36:32 -04:00
//movie.VoteCount = movieData.vote_count;
2014-02-05 23:39:16 -05:00
//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 )
{
2015-08-19 12:43:23 -04:00
var releases = movieData . releases . countries . Where ( i = > ! string . IsNullOrWhiteSpace ( i . certification ) ) . ToList ( ) ;
2016-10-01 22:10:53 -04:00
var ourRelease = releases . FirstOrDefault ( c = > string . Equals ( c . iso_3166_1 , preferredCountryCode , StringComparison . OrdinalIgnoreCase ) ) ;
var usRelease = releases . FirstOrDefault ( c = > string . Equals ( c . iso_3166_1 , "US" , StringComparison . OrdinalIgnoreCase ) ) ;
2015-08-19 12:43:23 -04:00
if ( ourRelease ! = null )
{
var ratingPrefix = string . Equals ( preferredCountryCode , "us" , StringComparison . OrdinalIgnoreCase ) ? "" : preferredCountryCode + "-" ;
2016-09-18 01:52:10 -04:00
var newRating = ratingPrefix + ourRelease . certification ;
newRating = newRating . Replace ( "de-" , "FSK-" , StringComparison . OrdinalIgnoreCase ) ;
movie . OfficialRating = newRating ;
2015-08-19 12:43:23 -04:00
}
else if ( usRelease ! = null )
{
movie . OfficialRating = usRelease . certification ;
}
2014-02-05 23:39:16 -05:00
}
2014-03-02 13:01:46 -05:00
if ( ! string . IsNullOrWhiteSpace ( movieData . release_date ) )
2014-02-05 23:39:16 -05:00
{
2014-03-02 13:01:46 -05:00
DateTime r ;
// These dates are always in this exact format
if ( DateTime . TryParse ( movieData . release_date , _usCulture , DateTimeStyles . None , out r ) )
{
movie . PremiereDate = r . ToUniversalTime ( ) ;
movie . ProductionYear = movie . PremiereDate . Value . Year ;
}
2014-02-05 23:39:16 -05:00
}
//studios
if ( movieData . production_companies ! = null )
{
movie . Studios . Clear ( ) ;
foreach ( var studio in movieData . production_companies . Select ( c = > c . name ) )
{
movie . AddStudio ( studio ) ;
}
}
// genres
// Movies get this from imdb
var genres = movieData . genres ? ? new List < MovieDbProvider . GenreItem > ( ) ;
foreach ( var genre in genres . Select ( g = > g . name ) )
{
movie . AddGenre ( genre ) ;
}
2015-07-23 22:48:10 -04:00
resultItem . ResetPeople ( ) ;
2016-04-29 04:06:41 -04:00
var tmdbImageUrl = settings . images . secure_base_url + "original" ;
2015-08-19 12:43:23 -04:00
2014-02-05 23:39:16 -05:00
//Actors, Directors, Writers - all in People
//actors come from cast
if ( movieData . casts ! = null & & movieData . casts . cast ! = null )
{
2015-06-28 12:36:25 -04:00
foreach ( var actor in movieData . casts . cast . OrderBy ( a = > a . order ) )
{
2016-01-21 13:50:43 -05:00
var personInfo = new PersonInfo
{
Name = actor . name . Trim ( ) ,
Role = actor . character ,
Type = PersonType . Actor ,
SortOrder = actor . order
} ;
if ( ! string . IsNullOrWhiteSpace ( actor . profile_path ) )
{
personInfo . ImageUrl = tmdbImageUrl + actor . profile_path ;
}
if ( actor . id > 0 )
{
personInfo . SetProviderId ( MetadataProviders . Tmdb , actor . id . ToString ( CultureInfo . InvariantCulture ) ) ;
}
resultItem . AddPerson ( personInfo ) ;
2015-06-28 12:36:25 -04:00
}
2014-02-05 23:39:16 -05:00
}
//and the rest from crew
if ( movieData . casts ! = null & & movieData . casts . crew ! = null )
{
2017-01-31 16:20:01 -05:00
var keepTypes = new [ ]
{
PersonType . Director ,
PersonType . Writer ,
//PersonType.Producer
} ;
2016-11-01 14:28:36 -04:00
2015-06-28 12:36:25 -04:00
foreach ( var person in movieData . casts . crew )
{
2015-09-25 08:53:38 -04:00
// Normalize this
var type = person . department ;
if ( string . Equals ( type , "writing" , StringComparison . OrdinalIgnoreCase ) )
{
type = PersonType . Writer ;
}
2016-11-01 14:28:36 -04:00
if ( ! keepTypes . Contains ( type ? ? string . Empty , StringComparer . OrdinalIgnoreCase ) & &
! keepTypes . Contains ( person . job ? ? string . Empty , StringComparer . OrdinalIgnoreCase ) )
{
continue ;
}
2016-01-21 13:50:43 -05:00
var personInfo = new PersonInfo
{
Name = person . name . Trim ( ) ,
Role = person . job ,
Type = type
} ;
if ( ! string . IsNullOrWhiteSpace ( person . profile_path ) )
{
personInfo . ImageUrl = tmdbImageUrl + person . profile_path ;
}
if ( person . id > 0 )
{
personInfo . SetProviderId ( MetadataProviders . Tmdb , person . id . ToString ( CultureInfo . InvariantCulture ) ) ;
}
resultItem . AddPerson ( personInfo ) ;
2015-06-28 12:36:25 -04:00
}
2014-02-05 23:39:16 -05:00
}
2017-07-23 18:29:53 -04:00
//if (movieData.keywords != null && movieData.keywords.keywords != null)
//{
// movie.Keywords = movieData.keywords.keywords.Select(i => i.name).ToList();
//}
2014-02-05 23:39:16 -05:00
if ( movieData . trailers ! = null & & movieData . trailers . youtube ! = null & &
movieData . trailers . youtube . Count > 0 )
{
var hasTrailers = movie as IHasTrailers ;
if ( hasTrailers ! = null )
{
hasTrailers . RemoteTrailers = movieData . trailers . youtube . Select ( i = > new MediaUrl
{
2016-04-21 01:13:33 -04:00
Url = string . Format ( "https://www.youtube.com/watch?v={0}" , i . source ) ,
2016-06-17 09:06:13 -04:00
Name = i . name
2014-02-05 23:39:16 -05:00
} ) . ToList ( ) ;
}
}
}
}
}