Merge pull request #4202 from cvium/tmdblib_migration
Migrate the TMDb providers to the TMDbLib librarypull/4276/head
commit
d47284d59f
@ -1,14 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Providers.Plugins.Tmdb.Models.General;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Collections
|
||||
{
|
||||
public class CollectionImages
|
||||
{
|
||||
public List<Backdrop> Backdrops { get; set; }
|
||||
|
||||
public List<Poster> Posters { get; set; }
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Collections
|
||||
{
|
||||
public class CollectionResult
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Overview { get; set; }
|
||||
|
||||
public string Poster_Path { get; set; }
|
||||
|
||||
public string Backdrop_Path { get; set; }
|
||||
|
||||
public List<Part> Parts { get; set; }
|
||||
|
||||
public CollectionImages Images { get; set; }
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Collections
|
||||
{
|
||||
public class Part
|
||||
{
|
||||
public string Title { get; set; }
|
||||
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Release_Date { get; set; }
|
||||
|
||||
public string Poster_Path { get; set; }
|
||||
|
||||
public string Backdrop_Path { get; set; }
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.General
|
||||
{
|
||||
public class Backdrop
|
||||
{
|
||||
public double Aspect_Ratio { get; set; }
|
||||
|
||||
public string File_Path { get; set; }
|
||||
|
||||
public int Height { get; set; }
|
||||
|
||||
public string Iso_639_1 { get; set; }
|
||||
|
||||
public double Vote_Average { get; set; }
|
||||
|
||||
public int Vote_Count { get; set; }
|
||||
|
||||
public int Width { get; set; }
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.General
|
||||
{
|
||||
public class Crew
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Credit_Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Department { get; set; }
|
||||
|
||||
public string Job { get; set; }
|
||||
|
||||
public string Profile_Path { get; set; }
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.General
|
||||
{
|
||||
public class ExternalIds
|
||||
{
|
||||
public string Imdb_Id { get; set; }
|
||||
|
||||
public object Freebase_Id { get; set; }
|
||||
|
||||
public string Freebase_Mid { get; set; }
|
||||
|
||||
public int? Tvdb_Id { get; set; }
|
||||
|
||||
public int? Tvrage_Id { get; set; }
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.General
|
||||
{
|
||||
public class Genre
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.General
|
||||
{
|
||||
public class Images
|
||||
{
|
||||
public List<Backdrop> Backdrops { get; set; }
|
||||
|
||||
public List<Poster> Posters { get; set; }
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.General
|
||||
{
|
||||
public class Keyword
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.General
|
||||
{
|
||||
public class Keywords
|
||||
{
|
||||
public List<Keyword> Results { get; set; }
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.General
|
||||
{
|
||||
public class Poster
|
||||
{
|
||||
public double Aspect_Ratio { get; set; }
|
||||
|
||||
public string File_Path { get; set; }
|
||||
|
||||
public int Height { get; set; }
|
||||
|
||||
public string Iso_639_1 { get; set; }
|
||||
|
||||
public double Vote_Average { get; set; }
|
||||
|
||||
public int Vote_Count { get; set; }
|
||||
|
||||
public int Width { get; set; }
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.General
|
||||
{
|
||||
public class Profile
|
||||
{
|
||||
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; }
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.General
|
||||
{
|
||||
public class Still
|
||||
{
|
||||
public double Aspect_Ratio { get; set; }
|
||||
|
||||
public string File_Path { get; set; }
|
||||
|
||||
public int Height { get; set; }
|
||||
|
||||
public string Id { get; set; }
|
||||
|
||||
public string Iso_639_1 { get; set; }
|
||||
|
||||
public double Vote_Average { get; set; }
|
||||
|
||||
public int Vote_Count { get; set; }
|
||||
|
||||
public int Width { get; set; }
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.General
|
||||
{
|
||||
public class StillImages
|
||||
{
|
||||
public List<Still> Stills { get; set; }
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.General
|
||||
{
|
||||
public class Video
|
||||
{
|
||||
public string Id { get; set; }
|
||||
|
||||
public string Iso_639_1 { get; set; }
|
||||
|
||||
public string Iso_3166_1 { get; set; }
|
||||
|
||||
public string Key { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Site { get; set; }
|
||||
|
||||
public string Size { get; set; }
|
||||
|
||||
public string Type { get; set; }
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.General
|
||||
{
|
||||
public class Videos
|
||||
{
|
||||
public IReadOnlyList<Video> Results { get; set; }
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Movies
|
||||
{
|
||||
public class BelongsToCollection
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Poster_Path { get; set; }
|
||||
|
||||
public string Backdrop_Path { get; set; }
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Movies
|
||||
{
|
||||
public class Cast
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Character { get; set; }
|
||||
|
||||
public int Order { get; set; }
|
||||
|
||||
public int Cast_Id { get; set; }
|
||||
|
||||
public string Profile_Path { get; set; }
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Providers.Plugins.Tmdb.Models.General;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Movies
|
||||
{
|
||||
public class Casts
|
||||
{
|
||||
public List<Cast> Cast { get; set; }
|
||||
|
||||
public List<Crew> Crew { get; set; }
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Movies
|
||||
{
|
||||
public class Country
|
||||
{
|
||||
public string Iso_3166_1 { get; set; }
|
||||
|
||||
public string Certification { get; set; }
|
||||
|
||||
public DateTime Release_Date { get; set; }
|
||||
}
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Providers.Plugins.Tmdb.Models.General;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Movies
|
||||
{
|
||||
public class MovieResult
|
||||
{
|
||||
public bool Adult { get; set; }
|
||||
|
||||
public string Backdrop_Path { get; set; }
|
||||
|
||||
public BelongsToCollection Belongs_To_Collection { get; set; }
|
||||
|
||||
public long Budget { get; set; }
|
||||
|
||||
public List<Genre> Genres { get; set; }
|
||||
|
||||
public string Homepage { get; set; }
|
||||
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Imdb_Id { get; set; }
|
||||
|
||||
public string Original_Title { get; set; }
|
||||
|
||||
public string Original_Name { get; set; }
|
||||
|
||||
public string Overview { get; set; }
|
||||
|
||||
public double Popularity { get; set; }
|
||||
|
||||
public string Poster_Path { get; set; }
|
||||
|
||||
public List<ProductionCompany> Production_Companies { get; set; }
|
||||
|
||||
public List<ProductionCountry> Production_Countries { get; set; }
|
||||
|
||||
public string Release_Date { get; set; }
|
||||
|
||||
public long Revenue { get; set; }
|
||||
|
||||
public int Runtime { get; set; }
|
||||
|
||||
public List<SpokenLanguage> Spoken_Languages { get; set; }
|
||||
|
||||
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 string GetOriginalTitle()
|
||||
{
|
||||
return Original_Name ?? Original_Title;
|
||||
}
|
||||
|
||||
public string GetTitle()
|
||||
{
|
||||
return Name ?? Title ?? GetOriginalTitle();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Movies
|
||||
{
|
||||
public class ProductionCompany
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public int Id { get; set; }
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Movies
|
||||
{
|
||||
public class ProductionCountry
|
||||
{
|
||||
public string Iso_3166_1 { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Movies
|
||||
{
|
||||
public class Releases
|
||||
{
|
||||
public List<Country> Countries { get; set; }
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Movies
|
||||
{
|
||||
public class SpokenLanguage
|
||||
{
|
||||
public string Iso_639_1 { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Movies
|
||||
{
|
||||
public class Trailers
|
||||
{
|
||||
public IReadOnlyList<Youtube> Youtube { get; set; }
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Movies
|
||||
{
|
||||
public class Youtube
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Size { get; set; }
|
||||
|
||||
public string Source { get; set; }
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Providers.Plugins.Tmdb.Models.General;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.People
|
||||
{
|
||||
public class PersonImages
|
||||
{
|
||||
public IReadOnlyList<Profile> Profiles { get; set; }
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Providers.Plugins.Tmdb.Models.General;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.People
|
||||
{
|
||||
public class PersonResult
|
||||
{
|
||||
public bool Adult { get; set; }
|
||||
|
||||
public List<string> Also_Known_As { get; set; }
|
||||
|
||||
public string Biography { get; set; }
|
||||
|
||||
public string Birthday { get; set; }
|
||||
|
||||
public string Deathday { get; set; }
|
||||
|
||||
public string Homepage { get; set; }
|
||||
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Imdb_Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Place_Of_Birth { get; set; }
|
||||
|
||||
public double Popularity { get; set; }
|
||||
|
||||
public string Profile_Path { get; set; }
|
||||
|
||||
public PersonImages Images { get; set; }
|
||||
|
||||
public ExternalIds External_Ids { get; set; }
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Search
|
||||
{
|
||||
public class ExternalIdLookupResult
|
||||
{
|
||||
public List<TvResult> Tv_Results { get; set; }
|
||||
}
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Search
|
||||
{
|
||||
public class MovieResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="MovieResult" /> is adult.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if adult; otherwise, <c>false</c>.</value>
|
||||
public bool Adult { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the backdrop_path.
|
||||
/// </summary>
|
||||
/// <value>The backdrop_path.</value>
|
||||
public string Backdrop_Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the id.
|
||||
/// </summary>
|
||||
/// <value>The id.</value>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the original_title.
|
||||
/// </summary>
|
||||
/// <value>The original_title.</value>
|
||||
public string Original_Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the original_name.
|
||||
/// </summary>
|
||||
/// <value>The original_name.</value>
|
||||
public string Original_Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the release_date.
|
||||
/// </summary>
|
||||
/// <value>The release_date.</value>
|
||||
public string Release_Date { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the poster_path.
|
||||
/// </summary>
|
||||
/// <value>The poster_path.</value>
|
||||
public string Poster_Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the popularity.
|
||||
/// </summary>
|
||||
/// <value>The popularity.</value>
|
||||
public double Popularity { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the title.
|
||||
/// </summary>
|
||||
/// <value>The title.</value>
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the vote_average.
|
||||
/// </summary>
|
||||
/// <value>The vote_average.</value>
|
||||
public double Vote_Average { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// For collection search results.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the vote_count.
|
||||
/// </summary>
|
||||
/// <value>The vote_count.</value>
|
||||
public int Vote_Count { get; set; }
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Search
|
||||
{
|
||||
public class PersonSearchResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="PersonSearchResult" /> is adult.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if adult; otherwise, <c>false</c>.</value>
|
||||
public bool Adult { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the id.
|
||||
/// </summary>
|
||||
/// <value>The id.</value>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the profile_ path.
|
||||
/// </summary>
|
||||
/// <value>The profile_ path.</value>
|
||||
public string Profile_Path { get; set; }
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Search
|
||||
{
|
||||
public class TmdbSearchResult<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the page.
|
||||
/// </summary>
|
||||
/// <value>The page.</value>
|
||||
public int Page { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the results.
|
||||
/// </summary>
|
||||
/// <value>The results.</value>
|
||||
public List<T> Results { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the total_pages.
|
||||
/// </summary>
|
||||
/// <value>The total_pages.</value>
|
||||
public int Total_Pages { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the total_results.
|
||||
/// </summary>
|
||||
/// <value>The total_results.</value>
|
||||
public int Total_Results { get; set; }
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.Search
|
||||
{
|
||||
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 Poster_Path { get; set; }
|
||||
|
||||
public double Popularity { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public double Vote_Average { get; set; }
|
||||
|
||||
public int Vote_Count { get; set; }
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.TV
|
||||
{
|
||||
public class Cast
|
||||
{
|
||||
public string Character { get; set; }
|
||||
|
||||
public string Credit_Id { get; set; }
|
||||
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Profile_Path { get; set; }
|
||||
|
||||
public int Order { get; set; }
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.TV
|
||||
{
|
||||
public class ContentRating
|
||||
{
|
||||
public string Iso_3166_1 { get; set; }
|
||||
|
||||
public string Rating { get; set; }
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.TV
|
||||
{
|
||||
public class ContentRatings
|
||||
{
|
||||
public List<ContentRating> Results { get; set; }
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.TV
|
||||
{
|
||||
public class CreatedBy
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Profile_Path { get; set; }
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Providers.Plugins.Tmdb.Models.General;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.TV
|
||||
{
|
||||
public class Credits
|
||||
{
|
||||
public List<Cast> Cast { get; set; }
|
||||
|
||||
public List<Crew> Crew { get; set; }
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.TV
|
||||
{
|
||||
public class Episode
|
||||
{
|
||||
public string Air_Date { get; set; }
|
||||
|
||||
public int Episode_Number { get; set; }
|
||||
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Overview { get; set; }
|
||||
|
||||
public string Still_Path { get; set; }
|
||||
|
||||
public double Vote_Average { get; set; }
|
||||
|
||||
public int Vote_Count { get; set; }
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Providers.Plugins.Tmdb.Models.General;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.TV
|
||||
{
|
||||
public class EpisodeCredits
|
||||
{
|
||||
public List<Cast> Cast { get; set; }
|
||||
|
||||
public List<Crew> Crew { get; set; }
|
||||
|
||||
public List<GuestStar> Guest_Stars { get; set; }
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using MediaBrowser.Providers.Plugins.Tmdb.Models.General;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.TV
|
||||
{
|
||||
public class EpisodeResult
|
||||
{
|
||||
public DateTime Air_Date { get; set; }
|
||||
|
||||
public int Episode_Number { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Overview { get; set; }
|
||||
|
||||
public int Id { get; set; }
|
||||
|
||||
public object Production_Code { get; set; }
|
||||
|
||||
public int Season_Number { get; set; }
|
||||
|
||||
public string Still_Path { get; set; }
|
||||
|
||||
public double Vote_Average { get; set; }
|
||||
|
||||
public int Vote_Count { get; set; }
|
||||
|
||||
public StillImages Images { get; set; }
|
||||
|
||||
public ExternalIds External_Ids { get; set; }
|
||||
|
||||
public EpisodeCredits Credits { get; set; }
|
||||
|
||||
public Tmdb.Models.General.Videos Videos { get; set; }
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.TV
|
||||
{
|
||||
public class GuestStar
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Credit_Id { get; set; }
|
||||
|
||||
public string Character { get; set; }
|
||||
|
||||
public int Order { get; set; }
|
||||
|
||||
public string Profile_Path { get; set; }
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.TV
|
||||
{
|
||||
public class Network
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.TV
|
||||
{
|
||||
public class Season
|
||||
{
|
||||
public string Air_Date { get; set; }
|
||||
|
||||
public int Episode_Count { get; set; }
|
||||
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Poster_Path { get; set; }
|
||||
|
||||
public int Season_Number { get; set; }
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Providers.Plugins.Tmdb.Models.General;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.TV
|
||||
{
|
||||
public class SeasonImages
|
||||
{
|
||||
public List<Poster> Posters { get; set; }
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Providers.Plugins.Tmdb.Models.General;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.TV
|
||||
{
|
||||
public class SeasonResult
|
||||
{
|
||||
public DateTime Air_Date { get; set; }
|
||||
|
||||
public List<Episode> Episodes { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Overview { get; set; }
|
||||
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Poster_Path { get; set; }
|
||||
|
||||
public int Season_Number { get; set; }
|
||||
|
||||
public Credits Credits { get; set; }
|
||||
|
||||
public SeasonImages Images { get; set; }
|
||||
|
||||
public ExternalIds External_Ids { get; set; }
|
||||
|
||||
public General.Videos Videos { get; set; }
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Providers.Plugins.Tmdb.Models.General;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Models.TV
|
||||
{
|
||||
public class SeriesResult
|
||||
{
|
||||
public string Backdrop_Path { get; set; }
|
||||
|
||||
public List<CreatedBy> Created_By { get; set; }
|
||||
|
||||
public List<int> Episode_Run_Time { get; set; }
|
||||
|
||||
public DateTime First_Air_Date { get; set; }
|
||||
|
||||
public List<Genre> Genres { get; set; }
|
||||
|
||||
public string Homepage { get; set; }
|
||||
|
||||
public int Id { get; set; }
|
||||
|
||||
public bool In_Production { get; set; }
|
||||
|
||||
public List<string> Languages { get; set; }
|
||||
|
||||
public DateTime Last_Air_Date { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public List<Network> Networks { get; set; }
|
||||
|
||||
public int Number_Of_Episodes { get; set; }
|
||||
|
||||
public int Number_Of_Seasons { get; set; }
|
||||
|
||||
public string Original_Name { get; set; }
|
||||
|
||||
public List<string> Origin_Country { get; set; }
|
||||
|
||||
public string Overview { get; set; }
|
||||
|
||||
public string Popularity { get; set; }
|
||||
|
||||
public string Poster_Path { get; set; }
|
||||
|
||||
public List<Season> Seasons { get; set; }
|
||||
|
||||
public string Status { get; set; }
|
||||
|
||||
public double Vote_Average { get; set; }
|
||||
|
||||
public int Vote_Count { get; set; }
|
||||
|
||||
public Credits Credits { get; set; }
|
||||
|
||||
public Images Images { get; set; }
|
||||
|
||||
public Keywords Keywords { get; set; }
|
||||
|
||||
public ExternalIds External_Ids { get; set; }
|
||||
|
||||
public General.Videos Videos { get; set; }
|
||||
|
||||
public ContentRatings Content_Ratings { get; set; }
|
||||
|
||||
public string ResultLanguage { get; set; }
|
||||
}
|
||||
}
|
@ -1,309 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
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;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using MediaBrowser.Providers.Plugins.Tmdb.Models.Movies;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
|
||||
{
|
||||
public class GenericTmdbMovieInfo<T>
|
||||
where T : BaseItem, new()
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
||||
|
||||
public GenericTmdbMovieInfo(ILogger logger, IJsonSerializer jsonSerializer, ILibraryManager libraryManager, IFileSystem fileSystem)
|
||||
{
|
||||
_logger = logger;
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_libraryManager = libraryManager;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
public async Task<MetadataResult<T>> GetMetadata(ItemLookupInfo itemId, CancellationToken cancellationToken)
|
||||
{
|
||||
var tmdbId = itemId.GetProviderId(MetadataProvider.Tmdb);
|
||||
var imdbId = itemId.GetProviderId(MetadataProvider.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))
|
||||
{
|
||||
var searchResults = await new TmdbSearch(_logger, _jsonSerializer, _libraryManager).GetMovieSearchResults(itemId, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var searchResult = searchResults.FirstOrDefault();
|
||||
|
||||
if (searchResult != null)
|
||||
{
|
||||
tmdbId = searchResult.GetProviderId(MetadataProvider.Tmdb);
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(tmdbId) || !string.IsNullOrEmpty(imdbId))
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
return await FetchMovieData(tmdbId, imdbId, itemId.MetadataLanguage, itemId.MetadataCountryCode, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return new MetadataResult<T>();
|
||||
}
|
||||
|
||||
/// <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>
|
||||
private async Task<MetadataResult<T>> FetchMovieData(string tmdbId, string imdbId, string language, string preferredCountryCode, CancellationToken cancellationToken)
|
||||
{
|
||||
var item = new MetadataResult<T>
|
||||
{
|
||||
Item = new T()
|
||||
};
|
||||
|
||||
string dataFilePath = null;
|
||||
MovieResult movieInfo = null;
|
||||
|
||||
// Id could be ImdbId or TmdbId
|
||||
if (string.IsNullOrEmpty(tmdbId))
|
||||
{
|
||||
movieInfo = await TmdbMovieProvider.Current.FetchMainResult(imdbId, false, language, cancellationToken).ConfigureAwait(false);
|
||||
if (movieInfo != null)
|
||||
{
|
||||
tmdbId = movieInfo.Id.ToString(_usCulture);
|
||||
|
||||
dataFilePath = TmdbMovieProvider.Current.GetDataFilePath(tmdbId, language);
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(dataFilePath));
|
||||
_jsonSerializer.SerializeToFile(movieInfo, dataFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(tmdbId))
|
||||
{
|
||||
await TmdbMovieProvider.Current.EnsureMovieInfo(tmdbId, language, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
dataFilePath = dataFilePath ?? TmdbMovieProvider.Current.GetDataFilePath(tmdbId, language);
|
||||
movieInfo = movieInfo ?? _jsonSerializer.DeserializeFromFile<MovieResult>(dataFilePath);
|
||||
|
||||
var settings = await TmdbMovieProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
ProcessMainInfo(item, settings, preferredCountryCode, movieInfo);
|
||||
item.HasMetadata = true;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes the main info.
|
||||
/// </summary>
|
||||
/// <param name="resultItem">The result item.</param>
|
||||
/// <param name="settings">The settings.</param>
|
||||
/// <param name="preferredCountryCode">The preferred country code.</param>
|
||||
/// <param name="movieData">The movie data.</param>
|
||||
private void ProcessMainInfo(MetadataResult<T> resultItem, TmdbSettingsResult settings, string preferredCountryCode, MovieResult movieData)
|
||||
{
|
||||
var movie = resultItem.Item;
|
||||
|
||||
movie.Name = movieData.GetTitle() ?? movie.Name;
|
||||
|
||||
movie.OriginalTitle = movieData.GetOriginalTitle();
|
||||
|
||||
movie.Overview = string.IsNullOrWhiteSpace(movieData.Overview) ? null : WebUtility.HtmlDecode(movieData.Overview);
|
||||
movie.Overview = movie.Overview != null ? movie.Overview.Replace("\n\n", "\n") : null;
|
||||
|
||||
// movie.HomePageUrl = movieData.homepage;
|
||||
|
||||
if (!string.IsNullOrEmpty(movieData.Tagline))
|
||||
{
|
||||
movie.Tagline = movieData.Tagline;
|
||||
}
|
||||
|
||||
if (movieData.Production_Countries != null)
|
||||
{
|
||||
movie.ProductionLocations = movieData
|
||||
.Production_Countries
|
||||
.Select(i => i.Name)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
movie.SetProviderId(MetadataProvider.Tmdb, movieData.Id.ToString(_usCulture));
|
||||
movie.SetProviderId(MetadataProvider.Imdb, movieData.Imdb_Id);
|
||||
|
||||
if (movieData.Belongs_To_Collection != null)
|
||||
{
|
||||
movie.SetProviderId(MetadataProvider.TmdbCollection,
|
||||
movieData.Belongs_To_Collection.Id.ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
if (movie is Movie movieItem)
|
||||
{
|
||||
movieItem.CollectionName = movieData.Belongs_To_Collection.Name;
|
||||
}
|
||||
}
|
||||
|
||||
string voteAvg = movieData.Vote_Average.ToString(CultureInfo.InvariantCulture);
|
||||
|
||||
if (float.TryParse(voteAvg, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var rating))
|
||||
{
|
||||
movie.CommunityRating = rating;
|
||||
}
|
||||
|
||||
// movie.VoteCount = movieData.vote_count;
|
||||
|
||||
if (movieData.Releases != null && movieData.Releases.Countries != null)
|
||||
{
|
||||
var releases = movieData.Releases.Countries.Where(i => !string.IsNullOrWhiteSpace(i.Certification)).ToList();
|
||||
|
||||
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));
|
||||
|
||||
if (ourRelease != null)
|
||||
{
|
||||
var ratingPrefix = string.Equals(preferredCountryCode, "us", StringComparison.OrdinalIgnoreCase) ? "" : preferredCountryCode + "-";
|
||||
var newRating = ratingPrefix + ourRelease.Certification;
|
||||
|
||||
newRating = newRating.Replace("de-", "FSK-", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
movie.OfficialRating = newRating;
|
||||
}
|
||||
else if (usRelease != null)
|
||||
{
|
||||
movie.OfficialRating = usRelease.Certification;
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(movieData.Release_Date))
|
||||
{
|
||||
// These dates are always in this exact format
|
||||
if (DateTime.TryParse(movieData.Release_Date, _usCulture, DateTimeStyles.None, out var r))
|
||||
{
|
||||
movie.PremiereDate = r.ToUniversalTime();
|
||||
movie.ProductionYear = movie.PremiereDate.Value.Year;
|
||||
}
|
||||
}
|
||||
|
||||
// studios
|
||||
if (movieData.Production_Companies != null)
|
||||
{
|
||||
movie.SetStudios(movieData.Production_Companies.Select(c => c.Name));
|
||||
}
|
||||
|
||||
// genres
|
||||
// Movies get this from imdb
|
||||
var genres = movieData.Genres ?? new List<Tmdb.Models.General.Genre>();
|
||||
|
||||
foreach (var genre in genres.Select(g => g.Name))
|
||||
{
|
||||
movie.AddGenre(genre);
|
||||
}
|
||||
|
||||
resultItem.ResetPeople();
|
||||
var tmdbImageUrl = settings.images.GetImageUrl("original");
|
||||
|
||||
// Actors, Directors, Writers - all in People
|
||||
// actors come from cast
|
||||
if (movieData.Casts != null && movieData.Casts.Cast != null)
|
||||
{
|
||||
foreach (var actor in movieData.Casts.Cast.OrderBy(a => a.Order))
|
||||
{
|
||||
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(MetadataProvider.Tmdb, actor.Id.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
resultItem.AddPerson(personInfo);
|
||||
}
|
||||
}
|
||||
|
||||
// and the rest from crew
|
||||
if (movieData.Casts?.Crew != null)
|
||||
{
|
||||
var keepTypes = new[]
|
||||
{
|
||||
PersonType.Director,
|
||||
PersonType.Writer,
|
||||
PersonType.Producer
|
||||
};
|
||||
|
||||
foreach (var person in movieData.Casts.Crew)
|
||||
{
|
||||
// Normalize this
|
||||
var type = TmdbUtils.MapCrewToPersonType(person);
|
||||
|
||||
if (!keepTypes.Contains(type, StringComparer.OrdinalIgnoreCase) &&
|
||||
!keepTypes.Contains(person.Job ?? string.Empty, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
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(MetadataProvider.Tmdb, person.Id.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
resultItem.AddPerson(personInfo);
|
||||
}
|
||||
}
|
||||
|
||||
// if (movieData.keywords != null && movieData.keywords.keywords != null)
|
||||
//{
|
||||
// movie.Keywords = movieData.keywords.keywords.Select(i => i.name).ToList();
|
||||
//}
|
||||
|
||||
if (movieData.Trailers != null && movieData.Trailers.Youtube != null)
|
||||
{
|
||||
movie.RemoteTrailers = movieData.Trailers.Youtube.Select(i => new MediaUrl
|
||||
{
|
||||
Url = string.Format(CultureInfo.InvariantCulture, "https://www.youtube.com/watch?v={0}", i.Source),
|
||||
Name = i.Name
|
||||
}).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,212 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using MediaBrowser.Providers.Plugins.Tmdb.Models.General;
|
||||
using MediaBrowser.Providers.Plugins.Tmdb.Models.Movies;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
|
||||
{
|
||||
public class TmdbImageProvider : IRemoteImageProvider, IHasOrder
|
||||
{
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
|
||||
public TmdbImageProvider(IJsonSerializer jsonSerializer, IHttpClientFactory httpClientFactory, IFileSystem fileSystem)
|
||||
{
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
public string Name => ProviderName;
|
||||
|
||||
public static string ProviderName => TmdbUtils.ProviderName;
|
||||
|
||||
/// <inheritdoc />
|
||||
public int Order => 0;
|
||||
|
||||
public bool Supports(BaseItem item)
|
||||
{
|
||||
return item is Movie || item is MusicVideo || item is Trailer;
|
||||
}
|
||||
|
||||
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
|
||||
{
|
||||
return new List<ImageType>
|
||||
{
|
||||
ImageType.Primary,
|
||||
ImageType.Backdrop
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
|
||||
{
|
||||
var list = new List<RemoteImageInfo>();
|
||||
|
||||
var language = item.GetPreferredMetadataLanguage();
|
||||
|
||||
var results = await FetchImages(item, null, _jsonSerializer, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (results == null)
|
||||
{
|
||||
return list;
|
||||
}
|
||||
|
||||
var tmdbSettings = await TmdbMovieProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var tmdbImageUrl = tmdbSettings.images.GetImageUrl("original");
|
||||
|
||||
var supportedImages = GetSupportedImages(item).ToList();
|
||||
|
||||
if (supportedImages.Contains(ImageType.Primary))
|
||||
{
|
||||
list.AddRange(GetPosters(results).Select(i => new RemoteImageInfo
|
||||
{
|
||||
Url = tmdbImageUrl + i.File_Path,
|
||||
CommunityRating = i.Vote_Average,
|
||||
VoteCount = i.Vote_Count,
|
||||
Width = i.Width,
|
||||
Height = i.Height,
|
||||
Language = TmdbMovieProvider.AdjustImageLanguage(i.Iso_639_1, language),
|
||||
ProviderName = Name,
|
||||
Type = ImageType.Primary,
|
||||
RatingType = RatingType.Score
|
||||
}));
|
||||
}
|
||||
|
||||
if (supportedImages.Contains(ImageType.Backdrop))
|
||||
{
|
||||
list.AddRange(GetBackdrops(results).Select(i => new RemoteImageInfo
|
||||
{
|
||||
Url = tmdbImageUrl + i.File_Path,
|
||||
CommunityRating = i.Vote_Average,
|
||||
VoteCount = i.Vote_Count,
|
||||
Width = i.Width,
|
||||
Height = i.Height,
|
||||
ProviderName = Name,
|
||||
Type = ImageType.Backdrop,
|
||||
RatingType = RatingType.Score
|
||||
}));
|
||||
}
|
||||
|
||||
var isLanguageEn = string.Equals(language, "en", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
return list.OrderByDescending(i =>
|
||||
{
|
||||
if (string.Equals(language, i.Language, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (!isLanguageEn)
|
||||
{
|
||||
if (string.Equals("en", i.Language, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(i.Language))
|
||||
{
|
||||
return isLanguageEn ? 3 : 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
})
|
||||
.ThenByDescending(i => i.CommunityRating ?? 0)
|
||||
.ThenByDescending(i => i.VoteCount ?? 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the posters.
|
||||
/// </summary>
|
||||
/// <param name="images">The images.</param>
|
||||
/// <returns>IEnumerable{MovieDbProvider.Poster}.</returns>
|
||||
private IEnumerable<Poster> GetPosters(Images images)
|
||||
{
|
||||
return images.Posters ?? new List<Poster>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the backdrops.
|
||||
/// </summary>
|
||||
/// <param name="images">The images.</param>
|
||||
/// <returns>IEnumerable{MovieDbProvider.Backdrop}.</returns>
|
||||
private IEnumerable<Backdrop> GetBackdrops(Images images)
|
||||
{
|
||||
var eligibleBackdrops = images.Backdrops == null ? new List<Backdrop>() :
|
||||
images.Backdrops;
|
||||
|
||||
return eligibleBackdrops.OrderByDescending(i => i.Vote_Average)
|
||||
.ThenByDescending(i => i.Vote_Count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches the images.
|
||||
/// </summary>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="language">The language.</param>
|
||||
/// <param name="jsonSerializer">The json serializer.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>Task{MovieImages}.</returns>
|
||||
private async Task<Images> FetchImages(BaseItem item, string language, IJsonSerializer jsonSerializer, CancellationToken cancellationToken)
|
||||
{
|
||||
var tmdbId = item.GetProviderId(MetadataProvider.Tmdb);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(tmdbId))
|
||||
{
|
||||
var imdbId = item.GetProviderId(MetadataProvider.Imdb);
|
||||
if (!string.IsNullOrWhiteSpace(imdbId))
|
||||
{
|
||||
var movieInfo = await TmdbMovieProvider.Current.FetchMainResult(imdbId, false, language, cancellationToken).ConfigureAwait(false);
|
||||
if (movieInfo != null)
|
||||
{
|
||||
tmdbId = movieInfo.Id.ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(tmdbId))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
await TmdbMovieProvider.Current.EnsureMovieInfo(tmdbId, language, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var path = TmdbMovieProvider.Current.GetDataFilePath(tmdbId, language);
|
||||
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
var fileInfo = _fileSystem.GetFileInfo(path);
|
||||
|
||||
if (fileInfo.Exists)
|
||||
{
|
||||
return jsonSerializer.DeserializeFromFile<MovieResult>(path).Images;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
|
||||
{
|
||||
return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
|
||||
{
|
||||
internal class TmdbImageSettings
|
||||
{
|
||||
public IReadOnlyList<string> backdrop_sizes { get; set; }
|
||||
|
||||
public string secure_base_url { get; set; }
|
||||
|
||||
public IReadOnlyList<string> poster_sizes { get; set; }
|
||||
|
||||
public IReadOnlyList<string> profile_sizes { get; set; }
|
||||
|
||||
public string GetImageUrl(string image)
|
||||
{
|
||||
return secure_base_url + image;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Extensions;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using TMDbLib.Objects.Find;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
|
||||
{
|
||||
public class TmdbMovieImageProvider : IRemoteImageProvider, IHasOrder
|
||||
{
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly TmdbClientManager _tmdbClientManager;
|
||||
|
||||
public TmdbMovieImageProvider(IHttpClientFactory httpClientFactory, TmdbClientManager tmdbClientManager)
|
||||
{
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_tmdbClientManager = tmdbClientManager;
|
||||
}
|
||||
|
||||
public int Order => 0;
|
||||
|
||||
public string Name => TmdbUtils.ProviderName;
|
||||
|
||||
public bool Supports(BaseItem item)
|
||||
{
|
||||
return item is Movie || item is Trailer;
|
||||
}
|
||||
|
||||
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
|
||||
{
|
||||
return new List<ImageType>
|
||||
{
|
||||
ImageType.Primary,
|
||||
ImageType.Backdrop
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
|
||||
{
|
||||
var language = item.GetPreferredMetadataLanguage();
|
||||
|
||||
var movieTmdbId = Convert.ToInt32(item.GetProviderId(MetadataProvider.Tmdb), CultureInfo.InvariantCulture);
|
||||
if (movieTmdbId <= 0)
|
||||
{
|
||||
var movieImdbId = item.GetProviderId(MetadataProvider.Imdb);
|
||||
if (string.IsNullOrEmpty(movieImdbId))
|
||||
{
|
||||
return Enumerable.Empty<RemoteImageInfo>();
|
||||
}
|
||||
|
||||
var movieResult = await _tmdbClientManager.FindByExternalIdAsync(movieImdbId, FindExternalSource.Imdb, language, cancellationToken).ConfigureAwait(false);
|
||||
if (movieResult?.MovieResults != null && movieResult.MovieResults.Count > 0)
|
||||
{
|
||||
movieTmdbId = movieResult.MovieResults[0].Id;
|
||||
}
|
||||
}
|
||||
|
||||
if (movieTmdbId <= 0)
|
||||
{
|
||||
return Enumerable.Empty<RemoteImageInfo>();
|
||||
}
|
||||
|
||||
var movie = await _tmdbClientManager
|
||||
.GetMovieAsync(movieTmdbId, language, TmdbUtils.GetImageLanguagesParam(language), cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (movie?.Images == null)
|
||||
{
|
||||
return Enumerable.Empty<RemoteImageInfo>();
|
||||
}
|
||||
|
||||
var remoteImages = new List<RemoteImageInfo>();
|
||||
|
||||
for (var i = 0; i < movie.Images.Posters.Count; i++)
|
||||
{
|
||||
var poster = movie.Images.Posters[i];
|
||||
remoteImages.Add(new RemoteImageInfo
|
||||
{
|
||||
Url = _tmdbClientManager.GetPosterUrl(poster.FilePath),
|
||||
CommunityRating = poster.VoteAverage,
|
||||
VoteCount = poster.VoteCount,
|
||||
Width = poster.Width,
|
||||
Height = poster.Height,
|
||||
Language = TmdbUtils.AdjustImageLanguage(poster.Iso_639_1, language),
|
||||
ProviderName = Name,
|
||||
Type = ImageType.Primary,
|
||||
RatingType = RatingType.Score
|
||||
});
|
||||
}
|
||||
|
||||
for (var i = 0; i < movie.Images.Backdrops.Count; i++)
|
||||
{
|
||||
var backdrop = movie.Images.Backdrops[i];
|
||||
remoteImages.Add(new RemoteImageInfo
|
||||
{
|
||||
Url = _tmdbClientManager.GetPosterUrl(backdrop.FilePath),
|
||||
CommunityRating = backdrop.VoteAverage,
|
||||
VoteCount = backdrop.VoteCount,
|
||||
Width = backdrop.Width,
|
||||
Height = backdrop.Height,
|
||||
ProviderName = Name,
|
||||
Type = ImageType.Backdrop,
|
||||
RatingType = RatingType.Score
|
||||
});
|
||||
}
|
||||
|
||||
return remoteImages.OrderByLanguageDescending(language);
|
||||
}
|
||||
|
||||
public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
|
||||
{
|
||||
return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,302 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using MediaBrowser.Providers.Plugins.Tmdb.Models.Search;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
|
||||
{
|
||||
public class TmdbSearch
|
||||
{
|
||||
private const string SearchUrl = TmdbUtils.BaseTmdbApiUrl + @"3/search/{3}?api_key={1}&query={0}&language={2}";
|
||||
private const string SearchUrlTvWithYear = TmdbUtils.BaseTmdbApiUrl + @"3/search/tv?api_key={1}&query={0}&language={2}&first_air_date_year={3}";
|
||||
private const string SearchUrlMovieWithYear = TmdbUtils.BaseTmdbApiUrl + @"3/search/movie?api_key={1}&query={0}&language={2}&primary_release_year={3}";
|
||||
|
||||
private static readonly CultureInfo _usCulture = new CultureInfo("en-US");
|
||||
|
||||
private static readonly Regex _cleanEnclosed = new Regex(@"\p{Ps}.*\p{Pe}", RegexOptions.Compiled);
|
||||
private static readonly Regex _cleanNonWord = new Regex(@"[\W_]+", RegexOptions.Compiled);
|
||||
private static readonly Regex _cleanStopWords = new Regex(
|
||||
@"\b( # Start at word boundary
|
||||
19[0-9]{2}|20[0-9]{2}| # 1900-2099
|
||||
S[0-9]{2}| # Season
|
||||
E[0-9]{2}| # Episode
|
||||
(2160|1080|720|576|480)[ip]?| # Resolution
|
||||
[xh]?264| # Encoding
|
||||
(web|dvd|bd|hdtv|hd)rip| # *Rip
|
||||
web|hdtv|mp4|bluray|ktr|dl|single|imageset|internal|doku|dubbed|retail|xxx|flac
|
||||
).* # Match rest of string",
|
||||
RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase);
|
||||
|
||||
private readonly ILogger _logger;
|
||||
private readonly IJsonSerializer _json;
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
|
||||
public TmdbSearch(ILogger logger, IJsonSerializer json, ILibraryManager libraryManager)
|
||||
{
|
||||
_logger = logger;
|
||||
_json = json;
|
||||
_libraryManager = libraryManager;
|
||||
}
|
||||
|
||||
public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(SeriesInfo idInfo, CancellationToken cancellationToken)
|
||||
{
|
||||
return GetSearchResults(idInfo, "tv", cancellationToken);
|
||||
}
|
||||
|
||||
public Task<IEnumerable<RemoteSearchResult>> GetMovieSearchResults(ItemLookupInfo idInfo, CancellationToken cancellationToken)
|
||||
{
|
||||
return GetSearchResults(idInfo, "movie", cancellationToken);
|
||||
}
|
||||
|
||||
public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(BoxSetInfo idInfo, CancellationToken cancellationToken)
|
||||
{
|
||||
return GetSearchResults(idInfo, "collection", cancellationToken);
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(ItemLookupInfo idInfo, string searchType, CancellationToken cancellationToken)
|
||||
{
|
||||
var name = idInfo.Name;
|
||||
var year = idInfo.Year;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
return new List<RemoteSearchResult>();
|
||||
}
|
||||
|
||||
var tmdbSettings = await TmdbMovieProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var tmdbImageUrl = tmdbSettings.images.GetImageUrl("original");
|
||||
|
||||
// ParseName is required here.
|
||||
// Caller provides the filename with extension stripped and NOT the parsed filename
|
||||
var parsedName = _libraryManager.ParseName(name);
|
||||
var yearInName = parsedName.Year;
|
||||
name = parsedName.Name;
|
||||
year ??= yearInName;
|
||||
|
||||
var language = idInfo.MetadataLanguage.ToLowerInvariant();
|
||||
|
||||
// Replace sequences of non-word characters with space
|
||||
// TMDB expects a space separated list of words make sure that is the case
|
||||
name = _cleanNonWord.Replace(name, " ").Trim();
|
||||
|
||||
_logger.LogInformation("TmdbSearch: Finding id for item: {0} ({1})", name, year);
|
||||
var results = await GetSearchResults(name, searchType, year, language, tmdbImageUrl, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (results.Count == 0)
|
||||
{
|
||||
// try in english if wasn't before
|
||||
if (!string.Equals(language, "en", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
results = await GetSearchResults(name, searchType, year, "en", tmdbImageUrl, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: retrying alternatives should be done outside the search
|
||||
// provider so that the retry logic can be common for all search
|
||||
// providers
|
||||
if (results.Count == 0)
|
||||
{
|
||||
var name2 = parsedName.Name;
|
||||
|
||||
// Remove things enclosed in []{}() etc
|
||||
name2 = _cleanEnclosed.Replace(name2, string.Empty);
|
||||
|
||||
// Replace sequences of non-word characters with space
|
||||
name2 = _cleanNonWord.Replace(name2, " ");
|
||||
|
||||
// Clean based on common stop words / tokens
|
||||
name2 = _cleanStopWords.Replace(name2, string.Empty);
|
||||
|
||||
// Trim whitespace
|
||||
name2 = name2.Trim();
|
||||
|
||||
// Search again if the new name is different
|
||||
if (!string.Equals(name2, name, StringComparison.Ordinal) && !string.IsNullOrWhiteSpace(name2))
|
||||
{
|
||||
_logger.LogInformation("TmdbSearch: Finding id for item: {0} ({1})", name2, year);
|
||||
results = await GetSearchResults(name2, searchType, year, language, tmdbImageUrl, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (results.Count == 0 && !string.Equals(language, "en", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// one more time, in english
|
||||
results = await GetSearchResults(name2, searchType, year, "en", tmdbImageUrl, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results.Where(i =>
|
||||
{
|
||||
if (year.HasValue && i.ProductionYear.HasValue)
|
||||
{
|
||||
// Allow one year tolerance
|
||||
return Math.Abs(year.Value - i.ProductionYear.Value) <= 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private Task<List<RemoteSearchResult>> GetSearchResults(string name, string type, int? year, string language, string baseImageUrl, CancellationToken cancellationToken)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case "tv":
|
||||
return GetSearchResultsTv(name, year, language, baseImageUrl, cancellationToken);
|
||||
default:
|
||||
return GetSearchResultsGeneric(name, type, year, language, baseImageUrl, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<List<RemoteSearchResult>> GetSearchResultsGeneric(string name, string type, int? year, string language, string baseImageUrl, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
throw new ArgumentException("String can't be null or empty.", nameof(name));
|
||||
}
|
||||
|
||||
string url3;
|
||||
if (year != null && string.Equals(type, "movie", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
url3 = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
SearchUrlMovieWithYear,
|
||||
WebUtility.UrlEncode(name),
|
||||
TmdbUtils.ApiKey,
|
||||
language,
|
||||
year);
|
||||
}
|
||||
else
|
||||
{
|
||||
url3 = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
SearchUrl,
|
||||
WebUtility.UrlEncode(name),
|
||||
TmdbUtils.ApiKey,
|
||||
language,
|
||||
type);
|
||||
}
|
||||
|
||||
using var requestMessage = new HttpRequestMessage(HttpMethod.Get, url3);
|
||||
foreach (var header in TmdbUtils.AcceptHeaders)
|
||||
{
|
||||
requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(header));
|
||||
}
|
||||
|
||||
using var response = await TmdbMovieProvider.Current.GetMovieDbResponse(requestMessage, cancellationToken).ConfigureAwait(false);
|
||||
await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
|
||||
var searchResults = await _json.DeserializeFromStreamAsync<TmdbSearchResult<MovieResult>>(stream).ConfigureAwait(false);
|
||||
|
||||
var results = searchResults.Results ?? new List<MovieResult>();
|
||||
|
||||
return results
|
||||
.Select(i =>
|
||||
{
|
||||
var remoteResult = new RemoteSearchResult
|
||||
{
|
||||
SearchProviderName = TmdbMovieProvider.Current.Name,
|
||||
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))
|
||||
{
|
||||
// These dates are always in this exact format
|
||||
if (DateTime.TryParseExact(i.Release_Date, "yyyy-MM-dd", _usCulture, DateTimeStyles.None, out var r))
|
||||
{
|
||||
remoteResult.PremiereDate = r.ToUniversalTime();
|
||||
remoteResult.ProductionYear = remoteResult.PremiereDate.Value.Year;
|
||||
}
|
||||
}
|
||||
|
||||
remoteResult.SetProviderId(MetadataProvider.Tmdb, i.Id.ToString(_usCulture));
|
||||
|
||||
return remoteResult;
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private async Task<List<RemoteSearchResult>> GetSearchResultsTv(string name, int? year, string language, string baseImageUrl, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
throw new ArgumentException("String can't be null or empty.", nameof(name));
|
||||
}
|
||||
|
||||
string url3;
|
||||
if (year == null)
|
||||
{
|
||||
url3 = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
SearchUrl,
|
||||
WebUtility.UrlEncode(name),
|
||||
TmdbUtils.ApiKey,
|
||||
language,
|
||||
"tv");
|
||||
}
|
||||
else
|
||||
{
|
||||
url3 = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
SearchUrlTvWithYear,
|
||||
WebUtility.UrlEncode(name),
|
||||
TmdbUtils.ApiKey,
|
||||
language,
|
||||
year);
|
||||
}
|
||||
|
||||
using var requestMessage = new HttpRequestMessage(HttpMethod.Get, url3);
|
||||
foreach (var header in TmdbUtils.AcceptHeaders)
|
||||
{
|
||||
requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(header));
|
||||
}
|
||||
|
||||
using var response = await TmdbMovieProvider.Current.GetMovieDbResponse(requestMessage, cancellationToken).ConfigureAwait(false);
|
||||
await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
|
||||
var searchResults = await _json.DeserializeFromStreamAsync<TmdbSearchResult<TvResult>>(stream).ConfigureAwait(false);
|
||||
|
||||
var results = searchResults.Results ?? new List<TvResult>();
|
||||
|
||||
return results
|
||||
.Select(i =>
|
||||
{
|
||||
var remoteResult = new RemoteSearchResult
|
||||
{
|
||||
SearchProviderName = TmdbMovieProvider.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))
|
||||
{
|
||||
// These dates are always in this exact format
|
||||
if (DateTime.TryParseExact(i.First_Air_Date, "yyyy-MM-dd", _usCulture, DateTimeStyles.None, out var r))
|
||||
{
|
||||
remoteResult.PremiereDate = r.ToUniversalTime();
|
||||
remoteResult.ProductionYear = remoteResult.PremiereDate.Value.Year;
|
||||
}
|
||||
}
|
||||
|
||||
remoteResult.SetProviderId(MetadataProvider.Tmdb, i.Id.ToString(_usCulture));
|
||||
|
||||
return remoteResult;
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Movies
|
||||
{
|
||||
internal class TmdbSettingsResult
|
||||
{
|
||||
public TmdbImageSettings images { get; set; }
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using MediaBrowser.Providers.Plugins.Tmdb.Movies;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Music
|
||||
{
|
||||
public class TmdbMusicVideoProvider : IRemoteMetadataProvider<MusicVideo, MusicVideoInfo>
|
||||
{
|
||||
public string Name => TmdbMovieProvider.Current.Name;
|
||||
|
||||
public Task<MetadataResult<MusicVideo>> GetMetadata(MusicVideoInfo info, CancellationToken cancellationToken)
|
||||
{
|
||||
return TmdbMovieProvider.Current.GetItemMetadata<MusicVideo>(info, cancellationToken);
|
||||
}
|
||||
|
||||
public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(MusicVideoInfo searchInfo, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult((IEnumerable<RemoteSearchResult>)new List<RemoteSearchResult>());
|
||||
}
|
||||
|
||||
public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,156 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Model.Globalization;
|
||||
using MediaBrowser.Model.IO;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using MediaBrowser.Providers.Plugins.Tmdb.Models.TV;
|
||||
using MediaBrowser.Providers.Plugins.Tmdb.Movies;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.TV
|
||||
{
|
||||
public abstract class TmdbEpisodeProviderBase
|
||||
{
|
||||
private const string EpisodeUrlPattern = TmdbUtils.BaseTmdbApiUrl + @"3/tv/{0}/season/{1}/episode/{2}?api_key={3}&append_to_response=images,external_ids,credits,videos";
|
||||
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly IServerConfigurationManager _configurationManager;
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly ILogger<TmdbEpisodeProviderBase> _logger;
|
||||
|
||||
protected TmdbEpisodeProviderBase(IHttpClientFactory httpClientFactory, IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IFileSystem fileSystem, ILocalizationManager localization, ILoggerFactory loggerFactory)
|
||||
{
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_configurationManager = configurationManager;
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_fileSystem = fileSystem;
|
||||
_logger = loggerFactory.CreateLogger<TmdbEpisodeProviderBase>();
|
||||
}
|
||||
|
||||
protected ILogger Logger => _logger;
|
||||
|
||||
protected async Task<EpisodeResult> GetEpisodeInfo(
|
||||
string seriesTmdbId,
|
||||
int season,
|
||||
int episodeNumber,
|
||||
string preferredMetadataLanguage,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
await EnsureEpisodeInfo(seriesTmdbId, season, episodeNumber, preferredMetadataLanguage, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var dataFilePath = GetDataFilePath(seriesTmdbId, season, episodeNumber, preferredMetadataLanguage);
|
||||
|
||||
return _jsonSerializer.DeserializeFromFile<EpisodeResult>(dataFilePath);
|
||||
}
|
||||
|
||||
internal Task EnsureEpisodeInfo(string tmdbId, int seasonNumber, int episodeNumber, string language, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrEmpty(tmdbId))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(tmdbId));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(language))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(language));
|
||||
}
|
||||
|
||||
var path = GetDataFilePath(tmdbId, seasonNumber, episodeNumber, language);
|
||||
|
||||
var fileInfo = _fileSystem.GetFileSystemInfo(path);
|
||||
|
||||
if (fileInfo.Exists)
|
||||
{
|
||||
// If it's recent or automatic updates are enabled, don't re-download
|
||||
if ((DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 2)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
return DownloadEpisodeInfo(tmdbId, seasonNumber, episodeNumber, language, cancellationToken);
|
||||
}
|
||||
|
||||
internal string GetDataFilePath(string tmdbId, int seasonNumber, int episodeNumber, string preferredLanguage)
|
||||
{
|
||||
if (string.IsNullOrEmpty(tmdbId))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(tmdbId));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(preferredLanguage))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(preferredLanguage));
|
||||
}
|
||||
|
||||
var path = TmdbSeriesProvider.GetSeriesDataPath(_configurationManager.ApplicationPaths, tmdbId);
|
||||
|
||||
var filename = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"season-{0}-episode-{1}-{2}.json",
|
||||
seasonNumber.ToString(CultureInfo.InvariantCulture),
|
||||
episodeNumber.ToString(CultureInfo.InvariantCulture),
|
||||
preferredLanguage);
|
||||
|
||||
return Path.Combine(path, filename);
|
||||
}
|
||||
|
||||
internal async Task DownloadEpisodeInfo(string id, int seasonNumber, int episodeNumber, string preferredMetadataLanguage, CancellationToken cancellationToken)
|
||||
{
|
||||
var mainResult = await FetchMainResult(EpisodeUrlPattern, id, seasonNumber, episodeNumber, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var dataFilePath = GetDataFilePath(id, seasonNumber, episodeNumber, preferredMetadataLanguage);
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(dataFilePath));
|
||||
_jsonSerializer.SerializeToFile(mainResult, dataFilePath);
|
||||
}
|
||||
|
||||
internal async Task<EpisodeResult> FetchMainResult(string urlPattern, string id, int seasonNumber, int episodeNumber, string language, CancellationToken cancellationToken)
|
||||
{
|
||||
var url = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
urlPattern,
|
||||
id,
|
||||
seasonNumber.ToString(CultureInfo.InvariantCulture),
|
||||
episodeNumber,
|
||||
TmdbUtils.ApiKey);
|
||||
|
||||
if (!string.IsNullOrEmpty(language))
|
||||
{
|
||||
url += string.Format(CultureInfo.InvariantCulture, "&language={0}", language);
|
||||
}
|
||||
|
||||
var includeImageLanguageParam = TmdbMovieProvider.GetImageLanguagesParam(language);
|
||||
// Get images in english and with no language
|
||||
url += "&include_image_language=" + includeImageLanguageParam;
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
using var requestMessage = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
foreach (var header in TmdbUtils.AcceptHeaders)
|
||||
{
|
||||
requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(header));
|
||||
}
|
||||
|
||||
using var response = await TmdbMovieProvider.Current.GetMovieDbResponse(requestMessage, cancellationToken).ConfigureAwait(false);
|
||||
await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
|
||||
return await _jsonSerializer.DeserializeFromStreamAsync<EpisodeResult>(stream).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
protected Task<HttpResponseMessage> GetResponse(string url, CancellationToken cancellationToken)
|
||||
{
|
||||
return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
#pragma warning disable CS1591
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using MediaBrowser.Providers.Plugins.Tmdb.Movies;
|
||||
|
||||
namespace MediaBrowser.Providers.Plugins.Tmdb.Trailers
|
||||
{
|
||||
public class TmdbTrailerProvider : IHasOrder, IRemoteMetadataProvider<Trailer, TrailerInfo>
|
||||
{
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
|
||||
public TmdbTrailerProvider(IHttpClientFactory httpClientFactory)
|
||||
{
|
||||
_httpClientFactory = httpClientFactory;
|
||||
}
|
||||
|
||||
public string Name => TmdbMovieProvider.Current.Name;
|
||||
|
||||
public int Order => 0;
|
||||
|
||||
public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(TrailerInfo searchInfo, CancellationToken cancellationToken)
|
||||
{
|
||||
return TmdbMovieProvider.Current.GetMovieSearchResults(searchInfo, cancellationToken);
|
||||
}
|
||||
|
||||
public Task<MetadataResult<Trailer>> GetMetadata(TrailerInfo info, CancellationToken cancellationToken)
|
||||
{
|
||||
return TmdbMovieProvider.Current.GetItemMetadata<Trailer>(info, cancellationToken);
|
||||
}
|
||||
|
||||
public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
|
||||
{
|
||||
return _httpClientFactory.CreateClient(NamedClient.Default).GetAsync(url, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in new issue