mirror of
https://github.com/lidarr/lidarr.git
synced 2025-08-20 21:43:33 -07:00
TheMovieDB.org is now used as metadata source.
This commit is contained in:
parent
69786b3968
commit
0715962ec5
18 changed files with 317 additions and 53 deletions
|
@ -73,7 +73,7 @@ namespace NzbDrone.Api.Movie
|
||||||
PostValidator.RuleFor(s => s.Path).IsValidPath().When(s => s.RootFolderPath.IsNullOrWhiteSpace());
|
PostValidator.RuleFor(s => s.Path).IsValidPath().When(s => s.RootFolderPath.IsNullOrWhiteSpace());
|
||||||
PostValidator.RuleFor(s => s.RootFolderPath).IsValidPath().When(s => s.Path.IsNullOrWhiteSpace());
|
PostValidator.RuleFor(s => s.RootFolderPath).IsValidPath().When(s => s.Path.IsNullOrWhiteSpace());
|
||||||
PostValidator.RuleFor(s => s.Title).NotEmpty();
|
PostValidator.RuleFor(s => s.Title).NotEmpty();
|
||||||
PostValidator.RuleFor(s => s.ImdbId).NotNull().NotEmpty().SetValidator(moviesExistsValidator);
|
PostValidator.RuleFor(s => s.TmdbId).NotNull().NotEmpty().SetValidator(moviesExistsValidator);
|
||||||
|
|
||||||
PutValidator.RuleFor(s => s.Path).IsValidPath();
|
PutValidator.RuleFor(s => s.Path).IsValidPath();
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ namespace NzbDrone.Api.Movie
|
||||||
public string Overview { get; set; }
|
public string Overview { get; set; }
|
||||||
public DateTime? InCinemas { get; set; }
|
public DateTime? InCinemas { get; set; }
|
||||||
public List<MediaCover> Images { get; set; }
|
public List<MediaCover> Images { get; set; }
|
||||||
|
public string Website { get; set; }
|
||||||
|
|
||||||
public string RemotePoster { get; set; }
|
public string RemotePoster { get; set; }
|
||||||
public int Year { get; set; }
|
public int Year { get; set; }
|
||||||
|
@ -42,6 +43,7 @@ namespace NzbDrone.Api.Movie
|
||||||
public DateTime? LastInfoSync { get; set; }
|
public DateTime? LastInfoSync { get; set; }
|
||||||
public string CleanTitle { get; set; }
|
public string CleanTitle { get; set; }
|
||||||
public string ImdbId { get; set; }
|
public string ImdbId { get; set; }
|
||||||
|
public int TmdbId { get; set; }
|
||||||
public string TitleSlug { get; set; }
|
public string TitleSlug { get; set; }
|
||||||
public string RootFolderPath { get; set; }
|
public string RootFolderPath { get; set; }
|
||||||
public string Certification { get; set; }
|
public string Certification { get; set; }
|
||||||
|
@ -50,6 +52,7 @@ namespace NzbDrone.Api.Movie
|
||||||
public DateTime Added { get; set; }
|
public DateTime Added { get; set; }
|
||||||
public AddMovieOptions AddOptions { get; set; }
|
public AddMovieOptions AddOptions { get; set; }
|
||||||
public Ratings Ratings { get; set; }
|
public Ratings Ratings { get; set; }
|
||||||
|
public List<string> AlternativeTitles { get; set; }
|
||||||
|
|
||||||
//TODO: Add series statistics as a property of the series (instead of individual properties)
|
//TODO: Add series statistics as a property of the series (instead of individual properties)
|
||||||
|
|
||||||
|
@ -79,7 +82,7 @@ namespace NzbDrone.Api.Movie
|
||||||
return new MovieResource
|
return new MovieResource
|
||||||
{
|
{
|
||||||
Id = model.Id,
|
Id = model.Id,
|
||||||
|
TmdbId = model.TmdbId,
|
||||||
Title = model.Title,
|
Title = model.Title,
|
||||||
//AlternateTitles
|
//AlternateTitles
|
||||||
SortTitle = model.SortTitle,
|
SortTitle = model.SortTitle,
|
||||||
|
@ -108,10 +111,12 @@ namespace NzbDrone.Api.Movie
|
||||||
TitleSlug = model.TitleSlug,
|
TitleSlug = model.TitleSlug,
|
||||||
RootFolderPath = model.RootFolderPath,
|
RootFolderPath = model.RootFolderPath,
|
||||||
Certification = model.Certification,
|
Certification = model.Certification,
|
||||||
|
Website = model.Website,
|
||||||
Genres = model.Genres,
|
Genres = model.Genres,
|
||||||
Tags = model.Tags,
|
Tags = model.Tags,
|
||||||
Added = model.Added,
|
Added = model.Added,
|
||||||
AddOptions = model.AddOptions,
|
AddOptions = model.AddOptions,
|
||||||
|
AlternativeTitles = model.AlternativeTitles,
|
||||||
Ratings = model.Ratings
|
Ratings = model.Ratings
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -123,6 +128,7 @@ namespace NzbDrone.Api.Movie
|
||||||
return new Core.Tv.Movie
|
return new Core.Tv.Movie
|
||||||
{
|
{
|
||||||
Id = resource.Id,
|
Id = resource.Id,
|
||||||
|
TmdbId = resource.TmdbId,
|
||||||
|
|
||||||
Title = resource.Title,
|
Title = resource.Title,
|
||||||
//AlternateTitles
|
//AlternateTitles
|
||||||
|
@ -151,10 +157,12 @@ namespace NzbDrone.Api.Movie
|
||||||
TitleSlug = resource.TitleSlug,
|
TitleSlug = resource.TitleSlug,
|
||||||
RootFolderPath = resource.RootFolderPath,
|
RootFolderPath = resource.RootFolderPath,
|
||||||
Certification = resource.Certification,
|
Certification = resource.Certification,
|
||||||
|
Website = resource.Website,
|
||||||
Genres = resource.Genres,
|
Genres = resource.Genres,
|
||||||
Tags = resource.Tags,
|
Tags = resource.Tags,
|
||||||
Added = resource.Added,
|
Added = resource.Added,
|
||||||
AddOptions = resource.AddOptions,
|
AddOptions = resource.AddOptions,
|
||||||
|
AlternativeTitles = resource.AlternativeTitles,
|
||||||
Ratings = resource.Ratings
|
Ratings = resource.Ratings
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -162,6 +170,7 @@ namespace NzbDrone.Api.Movie
|
||||||
public static Core.Tv.Movie ToModel(this MovieResource resource, Core.Tv.Movie movie)
|
public static Core.Tv.Movie ToModel(this MovieResource resource, Core.Tv.Movie movie)
|
||||||
{
|
{
|
||||||
movie.ImdbId = resource.ImdbId;
|
movie.ImdbId = resource.ImdbId;
|
||||||
|
movie.TmdbId = resource.TmdbId;
|
||||||
|
|
||||||
movie.Path = resource.Path;
|
movie.Path = resource.Path;
|
||||||
movie.ProfileId = resource.ProfileId;
|
movie.ProfileId = resource.ProfileId;
|
||||||
|
|
|
@ -6,6 +6,7 @@ namespace NzbDrone.Common.Cloud
|
||||||
{
|
{
|
||||||
IHttpRequestBuilderFactory Services { get; }
|
IHttpRequestBuilderFactory Services { get; }
|
||||||
IHttpRequestBuilderFactory SkyHookTvdb { get; }
|
IHttpRequestBuilderFactory SkyHookTvdb { get; }
|
||||||
|
IHttpRequestBuilderFactory TMDB { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SonarrCloudRequestBuilder : ISonarrCloudRequestBuilder
|
public class SonarrCloudRequestBuilder : ISonarrCloudRequestBuilder
|
||||||
|
@ -18,10 +19,15 @@ namespace NzbDrone.Common.Cloud
|
||||||
SkyHookTvdb = new HttpRequestBuilder("http://skyhook.sonarr.tv/v1/tvdb/{route}/{language}/")
|
SkyHookTvdb = new HttpRequestBuilder("http://skyhook.sonarr.tv/v1/tvdb/{route}/{language}/")
|
||||||
.SetSegment("language", "en")
|
.SetSegment("language", "en")
|
||||||
.CreateFactory();
|
.CreateFactory();
|
||||||
|
|
||||||
|
TMDB = new HttpRequestBuilder("https://api.themoviedb.org/3/{route}/{id}{secondaryRoute}")
|
||||||
|
.AddQueryParam("api_key", "1a7373301961d03f97f853a876dd1212")
|
||||||
|
.CreateFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IHttpRequestBuilderFactory Services { get; private set; }
|
public IHttpRequestBuilderFactory Services { get; private set; }
|
||||||
|
|
||||||
public IHttpRequestBuilderFactory SkyHookTvdb { get; private set; }
|
public IHttpRequestBuilderFactory SkyHookTvdb { get; private set; }
|
||||||
|
public IHttpRequestBuilderFactory TMDB { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
21
src/NzbDrone.Core/Datastore/Migration/106_add_tmdb_stuff.cs
Normal file
21
src/NzbDrone.Core/Datastore/Migration/106_add_tmdb_stuff.cs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
using FluentMigrator;
|
||||||
|
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migration
|
||||||
|
{
|
||||||
|
[Migration(106)]
|
||||||
|
public class add_tmdb_stuff : NzbDroneMigrationBase
|
||||||
|
{
|
||||||
|
protected override void MainDbUpgrade()
|
||||||
|
{
|
||||||
|
Alter.Table("Movies")
|
||||||
|
.AddColumn("TmdbId").AsInt32().WithDefaultValue(0);
|
||||||
|
Alter.Table("Movies")
|
||||||
|
.AddColumn("Website").AsString().Nullable();
|
||||||
|
Alter.Table("Movies")
|
||||||
|
.AlterColumn("ImdbId").AsString().Nullable();
|
||||||
|
Alter.Table("Movies")
|
||||||
|
.AddColumn("AlternativeTitles").AsString().Nullable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,5 +7,6 @@ namespace NzbDrone.Core.MetadataSource
|
||||||
public interface IProvideMovieInfo
|
public interface IProvideMovieInfo
|
||||||
{
|
{
|
||||||
Movie GetMovieInfo(string ImdbId);
|
Movie GetMovieInfo(string ImdbId);
|
||||||
|
Movie GetMovieInfo(int TmdbId);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
|
||||||
|
{
|
||||||
|
|
||||||
|
public class MovieSearchRoot
|
||||||
|
{
|
||||||
|
public int page { get; set; }
|
||||||
|
public MovieResult[] results { get; set; }
|
||||||
|
public int total_results { get; set; }
|
||||||
|
public int total_pages { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MovieResult
|
||||||
|
{
|
||||||
|
public string poster_path { get; set; }
|
||||||
|
public bool adult { get; set; }
|
||||||
|
public string overview { get; set; }
|
||||||
|
public string release_date { get; set; }
|
||||||
|
public int?[] genre_ids { get; set; }
|
||||||
|
public int id { get; set; }
|
||||||
|
public string original_title { get; set; }
|
||||||
|
public string original_language { get; set; }
|
||||||
|
public string title { get; set; }
|
||||||
|
public string backdrop_path { get; set; }
|
||||||
|
public float popularity { get; set; }
|
||||||
|
public int vote_count { get; set; }
|
||||||
|
public bool video { get; set; }
|
||||||
|
public float vote_average { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class MovieResourceRoot
|
||||||
|
{
|
||||||
|
public bool adult { get; set; }
|
||||||
|
public string backdrop_path { get; set; }
|
||||||
|
public Belongs_To_Collection belongs_to_collection { get; set; }
|
||||||
|
public int budget { get; set; }
|
||||||
|
public Genre[] genres { get; set; }
|
||||||
|
public string homepage { get; set; }
|
||||||
|
public int id { get; set; }
|
||||||
|
public string imdb_id { get; set; }
|
||||||
|
public string original_language { get; set; }
|
||||||
|
public string original_title { get; set; }
|
||||||
|
public string overview { get; set; }
|
||||||
|
public float popularity { get; set; }
|
||||||
|
public string poster_path { get; set; }
|
||||||
|
public Production_Companies[] production_companies { get; set; }
|
||||||
|
public Production_Countries[] production_countries { get; set; }
|
||||||
|
public string release_date { get; set; }
|
||||||
|
public int revenue { get; set; }
|
||||||
|
public int runtime { get; set; }
|
||||||
|
public Spoken_Languages[] spoken_languages { get; set; }
|
||||||
|
public string status { get; set; }
|
||||||
|
public string tagline { get; set; }
|
||||||
|
public string title { get; set; }
|
||||||
|
public bool video { get; set; }
|
||||||
|
public float vote_average { get; set; }
|
||||||
|
public int vote_count { get; set; }
|
||||||
|
public AlternativeTitles alternative_titles { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Belongs_To_Collection
|
||||||
|
{
|
||||||
|
public int id { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
public string poster_path { get; set; }
|
||||||
|
public string backdrop_path { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Genre
|
||||||
|
{
|
||||||
|
public int id { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Production_Companies
|
||||||
|
{
|
||||||
|
public string name { get; set; }
|
||||||
|
public int id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Production_Countries
|
||||||
|
{
|
||||||
|
public string iso_3166_1 { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Spoken_Languages
|
||||||
|
{
|
||||||
|
public string iso_639_1 { get; set; }
|
||||||
|
public string name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AlternativeTitles
|
||||||
|
{
|
||||||
|
public List<Title> titles { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Title
|
||||||
|
{
|
||||||
|
public string iso_3166_1 { get; set; }
|
||||||
|
public string title { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,11 +20,13 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
private readonly IHttpRequestBuilderFactory _requestBuilder;
|
private readonly IHttpRequestBuilderFactory _requestBuilder;
|
||||||
|
private readonly IHttpRequestBuilderFactory _movieBuilder;
|
||||||
|
|
||||||
public SkyHookProxy(IHttpClient httpClient, ISonarrCloudRequestBuilder requestBuilder, Logger logger)
|
public SkyHookProxy(IHttpClient httpClient, ISonarrCloudRequestBuilder requestBuilder, Logger logger)
|
||||||
{
|
{
|
||||||
_httpClient = httpClient;
|
_httpClient = httpClient;
|
||||||
_requestBuilder = requestBuilder.SkyHookTvdb;
|
_requestBuilder = requestBuilder.SkyHookTvdb;
|
||||||
|
_movieBuilder = requestBuilder.TMDB;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +60,65 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||||
return new Tuple<Series, List<Episode>>(series, episodes.ToList());
|
return new Tuple<Series, List<Episode>>(series, episodes.ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Movie GetMovieInfo(int TmdbId)
|
||||||
|
{
|
||||||
|
var request = _movieBuilder.Create()
|
||||||
|
.SetSegment("route", "movie")
|
||||||
|
.SetSegment("id", TmdbId.ToString())
|
||||||
|
.SetSegment("secondaryRoute", "")
|
||||||
|
.AddQueryParam("append_to_response", "alternative_titles")
|
||||||
|
.AddQueryParam("country", "US")
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
request.AllowAutoRedirect = true;
|
||||||
|
request.SuppressHttpError = true;
|
||||||
|
|
||||||
|
var response = _httpClient.Get<MovieResourceRoot>(request);
|
||||||
|
|
||||||
|
var resource = response.Resource;
|
||||||
|
|
||||||
|
var movie = new Movie();
|
||||||
|
|
||||||
|
movie.TmdbId = TmdbId;
|
||||||
|
movie.ImdbId = resource.imdb_id;
|
||||||
|
movie.Title = resource.title;
|
||||||
|
movie.TitleSlug = movie.Title.ToLower().Replace(" ", "-");
|
||||||
|
movie.CleanTitle = Parser.Parser.CleanSeriesTitle(movie.Title);
|
||||||
|
movie.Overview = resource.overview;
|
||||||
|
movie.Website = resource.homepage;
|
||||||
|
movie.InCinemas = DateTime.Parse(resource.release_date);
|
||||||
|
movie.Year = movie.InCinemas.Value.Year;
|
||||||
|
|
||||||
|
movie.Images.Add(new MediaCover.MediaCover(MediaCoverTypes.Poster, "http://image.tmdb.org/t/p/"+"w500"+resource.poster_path));//TODO: Update to load image specs from tmdb page!
|
||||||
|
movie.Images.Add(new MediaCover.MediaCover(MediaCoverTypes.Banner, "http://image.tmdb.org/t/p/" + "w1280" + resource.backdrop_path));
|
||||||
|
movie.Runtime = resource.runtime;
|
||||||
|
|
||||||
|
foreach(Title title in resource.alternative_titles.titles)
|
||||||
|
{
|
||||||
|
movie.AlternativeTitles.Add(title.title);
|
||||||
|
}
|
||||||
|
|
||||||
|
movie.Ratings = new Ratings();
|
||||||
|
movie.Ratings.Votes = resource.vote_count;
|
||||||
|
movie.Ratings.Value = (decimal)resource.vote_average;
|
||||||
|
|
||||||
|
foreach(Genre genre in resource.genres)
|
||||||
|
{
|
||||||
|
movie.Genres.Add(genre.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resource.status == "Released")
|
||||||
|
{
|
||||||
|
movie.Status = MovieStatusType.Released;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
movie.Status = MovieStatusType.Announced;
|
||||||
|
}
|
||||||
|
|
||||||
|
return movie;
|
||||||
|
}
|
||||||
|
|
||||||
public Movie GetMovieInfo(string ImdbId)
|
public Movie GetMovieInfo(string ImdbId)
|
||||||
{
|
{
|
||||||
var imdbRequest = new HttpRequest("http://www.omdbapi.com/?i=" + ImdbId + "&plot=full&r=json");
|
var imdbRequest = new HttpRequest("http://www.omdbapi.com/?i=" + ImdbId + "&plot=full&r=json");
|
||||||
|
@ -136,11 +197,22 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var searchTerm = lowerTitle.Replace("+", "_").Replace(" ", "_");
|
var searchTerm = lowerTitle.Replace("_", "+").Replace(" ", "+");
|
||||||
|
|
||||||
var firstChar = searchTerm.First();
|
var firstChar = searchTerm.First();
|
||||||
|
|
||||||
var imdbRequest = new HttpRequest("https://v2.sg.media-imdb.com/suggests/" + firstChar + "/" + searchTerm + ".json");
|
var request = _movieBuilder.Create()
|
||||||
|
.SetSegment("route", "search")
|
||||||
|
.SetSegment("id", "movie")
|
||||||
|
.SetSegment("secondaryRoute", "")
|
||||||
|
.AddQueryParam("query", searchTerm)
|
||||||
|
.AddQueryParam("include_adult", false)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
request.AllowAutoRedirect = true;
|
||||||
|
request.SuppressHttpError = true;
|
||||||
|
|
||||||
|
/*var imdbRequest = new HttpRequest("https://v2.sg.media-imdb.com/suggests/" + firstChar + "/" + searchTerm + ".json");
|
||||||
|
|
||||||
var response = _httpClient.Get(imdbRequest);
|
var response = _httpClient.Get(imdbRequest);
|
||||||
|
|
||||||
|
@ -154,31 +226,35 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
||||||
|
|
||||||
_logger.Warn("Json object: " + json);
|
_logger.Warn("Json object: " + json);
|
||||||
|
|
||||||
_logger.Warn("Crash ahead.");
|
_logger.Warn("Crash ahead.");*/
|
||||||
|
|
||||||
|
var response = _httpClient.Get<MovieSearchRoot>(request);
|
||||||
|
|
||||||
|
var movieResults = response.Resource.results;
|
||||||
|
|
||||||
var imdbMovies = new List<Movie>();
|
var imdbMovies = new List<Movie>();
|
||||||
|
|
||||||
foreach (MovieResource entry in json.d)
|
foreach (MovieResult result in movieResults)
|
||||||
{
|
{
|
||||||
var imdbMovie = new Movie();
|
var imdbMovie = new Movie();
|
||||||
imdbMovie.ImdbId = entry.id;
|
imdbMovie.TmdbId = result.id;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
imdbMovie.SortTitle = entry.l;
|
imdbMovie.SortTitle = result.title;
|
||||||
imdbMovie.Title = entry.l;
|
imdbMovie.Title = result.title;
|
||||||
string titleSlug = entry.l;
|
string titleSlug = result.title;
|
||||||
imdbMovie.TitleSlug = titleSlug.ToLower().Replace(" ", "-");
|
imdbMovie.TitleSlug = titleSlug.ToLower().Replace(" ", "-");
|
||||||
imdbMovie.Year = entry.y;
|
imdbMovie.Year = DateTime.Parse(result.release_date).Year;
|
||||||
imdbMovie.Images = new List<MediaCover.MediaCover>();
|
imdbMovie.Images = new List<MediaCover.MediaCover>();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string url = (string)entry.i[0];
|
string url = result.poster_path;
|
||||||
var imdbPoster = new MediaCover.MediaCover(MediaCoverTypes.Poster, url);
|
var imdbPoster = new MediaCover.MediaCover(MediaCoverTypes.Poster, "http://image.tmdb.org/t/p/" + "w500" + url);
|
||||||
imdbMovie.Images.Add(imdbPoster);
|
imdbMovie.Images.Add(imdbPoster);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_logger.Debug(entry);
|
_logger.Debug(result);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -183,6 +183,7 @@
|
||||||
<Compile Include="Datastore\Migration\002_remove_tvrage_imdb_unique_constraint.cs" />
|
<Compile Include="Datastore\Migration\002_remove_tvrage_imdb_unique_constraint.cs" />
|
||||||
<Compile Include="Datastore\Migration\003_remove_clean_title_from_scene_mapping.cs" />
|
<Compile Include="Datastore\Migration\003_remove_clean_title_from_scene_mapping.cs" />
|
||||||
<Compile Include="Datastore\Migration\004_updated_history.cs" />
|
<Compile Include="Datastore\Migration\004_updated_history.cs" />
|
||||||
|
<Compile Include="Datastore\Migration\106_add_tmdb_stuff.cs" />
|
||||||
<Compile Include="Datastore\Migration\105_fix_history_movieId.cs" />
|
<Compile Include="Datastore\Migration\105_fix_history_movieId.cs" />
|
||||||
<Compile Include="Datastore\Migration\005_added_eventtype_to_history.cs" />
|
<Compile Include="Datastore\Migration\005_added_eventtype_to_history.cs" />
|
||||||
<Compile Include="Datastore\Migration\006_add_index_to_log_time.cs" />
|
<Compile Include="Datastore\Migration\006_add_index_to_log_time.cs" />
|
||||||
|
@ -811,6 +812,7 @@
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\MovieResource.cs" />
|
<Compile Include="MetadataSource\SkyHook\Resource\MovieResource.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\ShowResource.cs" />
|
<Compile Include="MetadataSource\SkyHook\Resource\ShowResource.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\Resource\TimeOfDayResource.cs" />
|
<Compile Include="MetadataSource\SkyHook\Resource\TimeOfDayResource.cs" />
|
||||||
|
<Compile Include="MetadataSource\SkyHook\Resource\TMDBResources.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\SkyHookProxy.cs" />
|
<Compile Include="MetadataSource\SkyHook\SkyHookProxy.cs" />
|
||||||
<Compile Include="MetadataSource\SearchSeriesComparer.cs" />
|
<Compile Include="MetadataSource\SearchSeriesComparer.cs" />
|
||||||
<Compile Include="MetadataSource\SkyHook\SkyHookException.cs" />
|
<Compile Include="MetadataSource\SkyHook\SkyHookException.cs" />
|
||||||
|
|
|
@ -16,8 +16,9 @@ namespace NzbDrone.Core.Tv
|
||||||
Genres = new List<string>();
|
Genres = new List<string>();
|
||||||
Actors = new List<Actor>();
|
Actors = new List<Actor>();
|
||||||
Tags = new HashSet<int>();
|
Tags = new HashSet<int>();
|
||||||
|
AlternativeTitles = new List<string>();
|
||||||
}
|
}
|
||||||
|
public int TmdbId { get; set; }
|
||||||
public string ImdbId { get; set; }
|
public string ImdbId { get; set; }
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
public string CleanTitle { get; set; }
|
public string CleanTitle { get; set; }
|
||||||
|
@ -30,6 +31,7 @@ namespace NzbDrone.Core.Tv
|
||||||
public int Runtime { get; set; }
|
public int Runtime { get; set; }
|
||||||
public List<MediaCover.MediaCover> Images { get; set; }
|
public List<MediaCover.MediaCover> Images { get; set; }
|
||||||
public string TitleSlug { get; set; }
|
public string TitleSlug { get; set; }
|
||||||
|
public string Website { get; set; }
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
public int Year { get; set; }
|
public int Year { get; set; }
|
||||||
public Ratings Ratings { get; set; }
|
public Ratings Ratings { get; set; }
|
||||||
|
@ -44,7 +46,7 @@ namespace NzbDrone.Core.Tv
|
||||||
public AddMovieOptions AddOptions { get; set; }
|
public AddMovieOptions AddOptions { get; set; }
|
||||||
public LazyLoaded<MovieFile> MovieFile { get; set; }
|
public LazyLoaded<MovieFile> MovieFile { get; set; }
|
||||||
public int MovieFileId { get; set; }
|
public int MovieFileId { get; set; }
|
||||||
|
public List<string> AlternativeTitles { get; set; }
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return string.Format("[{0}][{1}]", ImdbId, Title.NullSafe());
|
return string.Format("[{0}][{1}]", ImdbId, Title.NullSafe());
|
||||||
|
|
|
@ -77,7 +77,7 @@ namespace NzbDrone.Core.Tv
|
||||||
_logger.Info("Adding Movie {0} Path: [{1}]", newMovie, newMovie.Path);
|
_logger.Info("Adding Movie {0} Path: [{1}]", newMovie, newMovie.Path);
|
||||||
|
|
||||||
newMovie.CleanTitle = newMovie.Title.CleanSeriesTitle();
|
newMovie.CleanTitle = newMovie.Title.CleanSeriesTitle();
|
||||||
newMovie.SortTitle = MovieTitleNormalizer.Normalize(newMovie.Title, newMovie.ImdbId);
|
newMovie.SortTitle = MovieTitleNormalizer.Normalize(newMovie.Title, newMovie.TmdbId);
|
||||||
newMovie.Added = DateTime.UtcNow;
|
newMovie.Added = DateTime.UtcNow;
|
||||||
|
|
||||||
_movieRepository.Insert(newMovie);
|
_movieRepository.Insert(newMovie);
|
||||||
|
|
|
@ -4,16 +4,16 @@ namespace NzbDrone.Core.Tv
|
||||||
{
|
{
|
||||||
public static class MovieTitleNormalizer
|
public static class MovieTitleNormalizer
|
||||||
{
|
{
|
||||||
private readonly static Dictionary<string, string> PreComputedTitles = new Dictionary<string, string>
|
private readonly static Dictionary<int, string> PreComputedTitles = new Dictionary<int, string>
|
||||||
{
|
{
|
||||||
{ "tt_109823457098", "a to z" },
|
{ 999999999, "a to z" },
|
||||||
};
|
};
|
||||||
|
|
||||||
public static string Normalize(string title, string imdbid)
|
public static string Normalize(string title, int tmdbid)
|
||||||
{
|
{
|
||||||
if (PreComputedTitles.ContainsKey(imdbid))
|
if (PreComputedTitles.ContainsKey(tmdbid))
|
||||||
{
|
{
|
||||||
return PreComputedTitles[imdbid];
|
return PreComputedTitles[tmdbid];
|
||||||
}
|
}
|
||||||
|
|
||||||
return Parser.Parser.NormalizeTitle(title).ToLower();
|
return Parser.Parser.NormalizeTitle(title).ToLower();
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace NzbDrone.Core.Tv
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
movieInfo = _movieInfo.GetMovieInfo(movie.ImdbId);
|
movieInfo = _movieInfo.GetMovieInfo(movie.TmdbId);
|
||||||
}
|
}
|
||||||
catch (MovieNotFoundException)
|
catch (MovieNotFoundException)
|
||||||
{
|
{
|
||||||
|
@ -59,10 +59,10 @@ namespace NzbDrone.Core.Tv
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (movie.ImdbId != movieInfo.ImdbId)
|
if (movie.TmdbId != movieInfo.TmdbId)
|
||||||
{
|
{
|
||||||
_logger.Warn("Movie '{0}' (tvdbid {1}) was replaced with '{2}' (tvdbid {3}), because the original was a duplicate.", movie.Title, movie.ImdbId, movieInfo.Title, movieInfo.ImdbId);
|
_logger.Warn("Movie '{0}' (tvdbid {1}) was replaced with '{2}' (tvdbid {3}), because the original was a duplicate.", movie.Title, movie.TmdbId, movieInfo.Title, movieInfo.TmdbId);
|
||||||
movie.ImdbId = movieInfo.ImdbId;
|
movie.TmdbId = movieInfo.TmdbId;
|
||||||
}
|
}
|
||||||
|
|
||||||
movie.Title = movieInfo.Title;
|
movie.Title = movieInfo.Title;
|
||||||
|
@ -80,6 +80,8 @@ namespace NzbDrone.Core.Tv
|
||||||
movie.Genres = movieInfo.Genres;
|
movie.Genres = movieInfo.Genres;
|
||||||
movie.Certification = movieInfo.Certification;
|
movie.Certification = movieInfo.Certification;
|
||||||
movie.InCinemas = movieInfo.InCinemas;
|
movie.InCinemas = movieInfo.InCinemas;
|
||||||
|
movie.Website = movieInfo.Website;
|
||||||
|
movie.AlternativeTitles = movieInfo.AlternativeTitles;
|
||||||
movie.Year = movieInfo.Year;
|
movie.Year = movieInfo.Year;
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
|
@ -18,9 +18,9 @@ namespace NzbDrone.Core.Validation.Paths
|
||||||
{
|
{
|
||||||
if (context.PropertyValue == null) return true;
|
if (context.PropertyValue == null) return true;
|
||||||
|
|
||||||
var imdbid = context.PropertyValue.ToString();
|
int tmdbId = (int)context.PropertyValue;
|
||||||
|
|
||||||
return (!_seriesService.GetAllMovies().Exists(s => s.ImdbId == imdbid));
|
return (!_seriesService.GetAllMovies().Exists(s => s.TmdbId == tmdbId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -33,7 +33,7 @@ Handlebars.registerHelper('remotePoster', function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Handlebars.SafeString('<img class="series-poster placeholder-image" src="{0}">'.format(placeholder));
|
return new Handlebars.SafeString('<img class="series-poster placeholder-image" src="{0}">'.format(placeholder));
|
||||||
})
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('traktUrl', function() {
|
Handlebars.registerHelper('traktUrl', function() {
|
||||||
return 'http://trakt.tv/search/tvdb/' + this.tvdbId + '?id_type=show';
|
return 'http://trakt.tv/search/tvdb/' + this.tvdbId + '?id_type=show';
|
||||||
|
@ -47,6 +47,19 @@ Handlebars.registerHelper('tvdbUrl', function() {
|
||||||
return 'http://imdb.com/title/tt' + this.imdbId;
|
return 'http://imdb.com/title/tt' + this.imdbId;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Handlebars.registerHelper('tmdbUrl', function() {
|
||||||
|
return 'https://www.themoviedb.org/movie/' + this.tmdbId;
|
||||||
|
});
|
||||||
|
|
||||||
|
Handlebars.registerHelper('homepage', function() {
|
||||||
|
return this.website;
|
||||||
|
});
|
||||||
|
|
||||||
|
Handlebars.registerHelper('alternativeTitlesString', function() {
|
||||||
|
var titles = this.alternativeTitles;
|
||||||
|
return titles.slice(0,titles.length-1).join(", ") + " and " + titles[titles.length-1];
|
||||||
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('inCinemas', function() {
|
Handlebars.registerHelper('inCinemas', function() {
|
||||||
var monthNames = ["January", "February", "March", "April", "May", "June",
|
var monthNames = ["January", "February", "March", "April", "May", "June",
|
||||||
"July", "August", "September", "October", "November", "December"
|
"July", "August", "September", "October", "November", "December"
|
||||||
|
@ -55,7 +68,7 @@ Handlebars.registerHelper('inCinemas', function() {
|
||||||
var year = cinemasDate.getFullYear();
|
var year = cinemasDate.getFullYear();
|
||||||
var month = monthNames[cinemasDate.getMonth()];
|
var month = monthNames[cinemasDate.getMonth()];
|
||||||
return "In Cinemas " + month + " " + year;
|
return "In Cinemas " + month + " " + year;
|
||||||
})
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('tvRageUrl', function() {
|
Handlebars.registerHelper('tvRageUrl', function() {
|
||||||
return 'http://www.tvrage.com/shows/id-' + this.tvRageId;
|
return 'http://www.tvrage.com/shows/id-' + this.tvRageId;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-9">
|
<div class="col-md-8">
|
||||||
{{profile profileId}}
|
{{profile profileId}}
|
||||||
|
|
||||||
{{#if network}}
|
{{#if network}}
|
||||||
|
@ -27,11 +27,13 @@
|
||||||
<span class="label label-default">Announced</span>
|
<span class="label label-default">Announced</span>
|
||||||
{{/if_eq}}
|
{{/if_eq}}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-4">
|
||||||
<span class="series-info-links">
|
<span class="series-info-links">
|
||||||
<!--<a href="{{traktUrl}}" class="label label-info">Trakt</a>
|
<!--<a href="{{traktUrl}}" class="label label-info">Trakt</a>-->
|
||||||
|
{{#if website}}
|
||||||
<a href="{{tvdbUrl}}" class="label label-info">The TVDB</a>-->
|
<a href="{{homepage}}" class="label label-info">Homepage</a>
|
||||||
|
{{/if}}
|
||||||
|
<a href="{{tmdbUrl}}" class="label label-info">The Movie DB</a>
|
||||||
|
|
||||||
{{#if imdbId}}
|
{{#if imdbId}}
|
||||||
<a href="{{imdbUrl}}" class="label label-info">IMDB</a>
|
<a href="{{imdbUrl}}" class="label label-info">IMDB</a>
|
||||||
|
@ -40,18 +42,12 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if alternateTitles}}
|
{{#if alternativeTitles}}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
{{#each alternateTitles}}
|
<span class="alternative-titles">
|
||||||
{{#if_eq seasonNumber compare="-1"}}
|
Also known as: {{alternativeTitlesString}}.
|
||||||
<span class="label label-default">{{title}}</span>
|
</span>
|
||||||
{{/if_eq}}
|
|
||||||
|
|
||||||
{{#if_eq sceneSeasonNumber compare="-1"}}
|
|
||||||
<span class="label label-default">{{title}}</span>
|
|
||||||
{{/if_eq}}
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -274,7 +274,7 @@ module.exports = Marionette.Layout.extend({
|
||||||
|
|
||||||
_showBackdrop : function () {
|
_showBackdrop : function () {
|
||||||
$('body').addClass('backdrop');
|
$('body').addClass('backdrop');
|
||||||
var fanArt = this._getImage('fanart');
|
var fanArt = this._getImage('banner');
|
||||||
|
|
||||||
if (fanArt) {
|
if (fanArt) {
|
||||||
this._backstrech = $.backstretch(fanArt);
|
this._backstrech = $.backstretch(fanArt);
|
||||||
|
|
|
@ -36,6 +36,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="movie-info">
|
<div id="movie-info">
|
||||||
|
<div class="movie-tabs">
|
||||||
|
<div>
|
||||||
|
<div class="movie-tabs-card">
|
||||||
<ul class="nav nav-tabs" id="myTab">
|
<ul class="nav nav-tabs" id="myTab">
|
||||||
<li><a href="#movie-history" class="x-movie-history">History</a></li>
|
<li><a href="#movie-history" class="x-movie-history">History</a></li>
|
||||||
<li><a href="#movie-search" class="x-movie-search">Search</a></li>
|
<li><a href="#movie-search" class="x-movie-search">Search</a></li>
|
||||||
|
@ -44,4 +47,7 @@
|
||||||
<div class="tab-pane" id="movie-history"/>
|
<div class="tab-pane" id="movie-history"/>
|
||||||
<div class="tab-pane" id="movie-search"/>
|
<div class="tab-pane" id="movie-search"/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,6 +8,22 @@
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.movie-tabs-card {
|
||||||
|
.card;
|
||||||
|
.opacity(0.9);
|
||||||
|
margin : 30px 10px;
|
||||||
|
padding : 10px 25px;
|
||||||
|
|
||||||
|
.show-hide-episodes {
|
||||||
|
.clickable();
|
||||||
|
text-align : center;
|
||||||
|
|
||||||
|
i {
|
||||||
|
.clickable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.edit-movie-modal, .delete-movie-modal {
|
.edit-movie-modal, .delete-movie-modal {
|
||||||
overflow : visible;
|
overflow : visible;
|
||||||
|
|
||||||
|
@ -253,6 +269,12 @@
|
||||||
margin-bottom : 50px;
|
margin-bottom : 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.alternative-titles {
|
||||||
|
font-size: 12px;
|
||||||
|
color: rgba(255, 255, 255, 180);
|
||||||
|
opacity: .75;
|
||||||
|
}
|
||||||
|
|
||||||
.movie-season {
|
.movie-season {
|
||||||
|
|
||||||
.episode-number-cell {
|
.episode-number-cell {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue