TheMovieDB.org is now used as metadata source.

Leonardo Galli 8 years ago
parent 69786b3968
commit 0715962ec5

@ -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; }
} }
} }

@ -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,12 +36,18 @@
</div> </div>
</div> </div>
<div id="movie-info"> <div id="movie-info">
<ul class="nav nav-tabs" id="myTab"> <div class="movie-tabs">
<li><a href="#movie-history" class="x-movie-history">History</a></li> <div>
<li><a href="#movie-search" class="x-movie-search">Search</a></li> <div class="movie-tabs-card">
</ul> <ul class="nav nav-tabs" id="myTab">
<div class="tab-content"> <li><a href="#movie-history" class="x-movie-history">History</a></li>
<div class="tab-pane" id="movie-history"/> <li><a href="#movie-search" class="x-movie-search">Search</a></li>
<div class="tab-pane" id="movie-search"/> </ul>
<div class="tab-content">
<div class="tab-pane" id="movie-history"/>
<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…
Cancel
Save