New: Scrape Cast/Crew/Collection Data on Movie Refresh

pull/4072/head
Qstick 5 years ago
parent dec0e3eec3
commit d76423a305

@ -28,7 +28,7 @@ namespace NzbDrone.Api.Movies
int tmdbId = -1; int tmdbId = -1;
if (int.TryParse(Request.Query.tmdbId, out tmdbId)) if (int.TryParse(Request.Query.tmdbId, out tmdbId))
{ {
var result = _movieInfo.GetMovieInfo(tmdbId, null, true); var result = _movieInfo.GetMovieInfo(tmdbId, null, true).Item1;
return result.ToResource(); return result.ToResource();
} }

@ -22,7 +22,7 @@ namespace NzbDrone.Core.Test.MetadataSource.SkyHook
[TestCase(70981, "Prometheus")] [TestCase(70981, "Prometheus")]
public void should_be_able_to_get_movie_detail(int tmdbId, string title) public void should_be_able_to_get_movie_detail(int tmdbId, string title)
{ {
var details = Subject.GetMovieInfo(tmdbId); var details = Subject.GetMovieInfo(tmdbId, null, false).Item1;
ValidateMovie(details); ValidateMovie(details);

@ -0,0 +1,99 @@
using System.Collections.Generic;
using System.Linq;
using FizzWare.NBuilder;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Movies.Credits;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.MovieTests.AlternativeTitleServiceTests
{
[TestFixture]
public class CreditServiceFixture : CoreTest<CreditService>
{
private Credit _credit1;
private Credit _credit2;
private Credit _credit3;
private Movie _movie;
[SetUp]
public void Setup()
{
var credits = Builder<Credit>.CreateListOfSize(3)
.All()
.With(t => t.MovieId = 0).Build();
_credit1 = credits[0];
_credit2 = credits[1];
_credit3 = credits[2];
_movie = Builder<Movie>.CreateNew().With(m => m.Id = 1).Build();
}
private void GivenExistingCredits(params Credit[] credits)
{
Mocker.GetMock<ICreditRepository>().Setup(r => r.FindByMovieId(_movie.Id))
.Returns(credits.ToList());
}
[Test]
public void should_update_insert_remove_titles()
{
var titles = new List<Credit> { _credit2, _credit3 };
var updates = new List<Credit> { _credit2 };
var deletes = new List<Credit> { _credit1 };
var inserts = new List<Credit> { _credit3 };
GivenExistingCredits(_credit1, _credit2);
Subject.UpdateCredits(titles, _movie);
Mocker.GetMock<ICreditRepository>().Verify(r => r.InsertMany(inserts), Times.Once());
Mocker.GetMock<ICreditRepository>().Verify(r => r.UpdateMany(updates), Times.Once());
Mocker.GetMock<ICreditRepository>().Verify(r => r.DeleteMany(deletes), Times.Once());
}
[Test]
public void should_not_insert_duplicates()
{
GivenExistingCredits();
var credits = new List<Credit> { _credit1, _credit1 };
var inserts = new List<Credit> { _credit1 };
Subject.UpdateCredits(credits, _movie);
Mocker.GetMock<ICreditRepository>().Verify(r => r.InsertMany(inserts), Times.Once());
}
[Test]
public void should_update_movie_id()
{
GivenExistingCredits();
var titles = new List<Credit> { _credit1, _credit2 };
Subject.UpdateCredits(titles, _movie);
_credit1.MovieId.Should().Be(_movie.Id);
_credit2.MovieId.Should().Be(_movie.Id);
}
[Test]
public void should_update_with_correct_id()
{
var existingCredit = Builder<Credit>.CreateNew().With(t => t.Id = 2).Build();
GivenExistingCredits(existingCredit);
var updateCredit = existingCredit.JsonClone();
updateCredit.Id = 0;
Subject.UpdateCredits(new List<Credit> { updateCredit }, _movie);
Mocker.GetMock<ICreditRepository>().Verify(r => r.UpdateMany(It.Is<IList<Credit>>(list => list.First().Id == existingCredit.Id)), Times.Once());
}
}
}

@ -19,7 +19,7 @@
<ProjectReference Include="..\NzbDrone.Core\Radarr.Core.csproj" /> <ProjectReference Include="..\NzbDrone.Core\Radarr.Core.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<RuntimeFiles Include="..\Runtimes\$(RuntimeIdentifier)\*"/> <RuntimeFiles Include="..\Runtimes\$(RuntimeIdentifier)\*" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\..\Logo\1024.png"> <None Include="..\..\Logo\1024.png">
@ -30,10 +30,10 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
</ItemGroup> </ItemGroup>
<Target Name="CopyRuntimeFilesOnBuild" AfterTargets="AfterBuild" > <Target Name="CopyRuntimeFilesOnBuild" AfterTargets="AfterBuild">
<Copy SourceFiles="@(RuntimeFiles)" DestinationFolder="$(OutDir)" /> <Copy SourceFiles="@(RuntimeFiles)" DestinationFolder="$(OutDir)" />
</Target> </Target>
<Target Name="CopyRuntimeFilesOnPublish" AfterTargets="Publish" > <Target Name="CopyRuntimeFilesOnPublish" AfterTargets="Publish">
<Copy SourceFiles="@(RuntimeFiles)" DestinationFolder="$(PublishDir)" /> <Copy SourceFiles="@(RuntimeFiles)" DestinationFolder="$(PublishDir)" />
</Target> </Target>
</Project> </Project>

@ -0,0 +1,28 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(164)]
public class movie_collections_crew : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("Movies").AddColumn("Collection").AsString().Nullable();
Delete.Column("Actors").FromTable("Movies");
Create.TableForModel("Credits").WithColumn("MovieId").AsInt32()
.WithColumn("CreditTmdbId").AsString().Unique()
.WithColumn("PersonTmdbId").AsInt32()
.WithColumn("Name").AsString()
.WithColumn("Images").AsString()
.WithColumn("Character").AsString().Nullable()
.WithColumn("Order").AsInt32()
.WithColumn("Job").AsString().Nullable()
.WithColumn("Department").AsString().Nullable()
.WithColumn("Type").AsInt32();
Create.Index().OnTable("Credits").OnColumn("MovieId");
}
}
}

@ -22,6 +22,7 @@ using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Messaging.Commands; using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Movies; using NzbDrone.Core.Movies;
using NzbDrone.Core.Movies.AlternativeTitles; using NzbDrone.Core.Movies.AlternativeTitles;
using NzbDrone.Core.Movies.Credits;
using NzbDrone.Core.NetImport; using NzbDrone.Core.NetImport;
using NzbDrone.Core.NetImport.ImportExclusions; using NzbDrone.Core.NetImport.ImportExclusions;
using NzbDrone.Core.Notifications; using NzbDrone.Core.Notifications;
@ -96,11 +97,12 @@ namespace NzbDrone.Core.Datastore
.Ignore(f => f.Path); .Ignore(f => f.Path);
Mapper.Entity<Movie>("Movies").RegisterModel() Mapper.Entity<Movie>("Movies").RegisterModel()
.Ignore(s => s.RootFolderPath) .Ignore(s => s.RootFolderPath);
.Ignore(m => m.Actors);
Mapper.Entity<AlternativeTitle>("AlternativeTitles").RegisterModel(); Mapper.Entity<AlternativeTitle>("AlternativeTitles").RegisterModel();
Mapper.Entity<Credit>("Credits").RegisterModel();
Mapper.Entity<ImportExclusion>("ImportExclusions").RegisterModel(); Mapper.Entity<ImportExclusion>("ImportExclusions").RegisterModel();
Mapper.Entity<QualityDefinition>("QualityDefinitions").RegisterModel() Mapper.Entity<QualityDefinition>("QualityDefinitions").RegisterModel()

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using NzbDrone.Core.Movies; using NzbDrone.Core.Movies;
using NzbDrone.Core.Movies.Credits;
using NzbDrone.Core.Profiles; using NzbDrone.Core.Profiles;
namespace NzbDrone.Core.MetadataSource namespace NzbDrone.Core.MetadataSource
@ -8,7 +9,7 @@ namespace NzbDrone.Core.MetadataSource
public interface IProvideMovieInfo public interface IProvideMovieInfo
{ {
Movie GetMovieInfo(string imdbId); Movie GetMovieInfo(string imdbId);
Movie GetMovieInfo(int tmdbId, Profile profile, bool hasPreDBEntry); Tuple<Movie, List<Credit>> GetMovieInfo(int tmdbId, Profile profile, bool hasPreDBEntry);
HashSet<int> GetChangedMovies(DateTime startTime); HashSet<int> GetChangedMovies(DateTime startTime);
} }
} }

@ -1,9 +0,0 @@
namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
{
public class ActorResource
{
public string Name { get; set; }
public string Character { get; set; }
public string Image { get; set; }
}
}

@ -41,7 +41,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
{ {
public bool adult { get; set; } public bool adult { get; set; }
public string backdrop_path { get; set; } public string backdrop_path { get; set; }
public Belongs_To_Collection belongs_to_collection { get; set; } public CollectionResource belongs_to_collection { get; set; }
public int? status_code { get; set; } public int? status_code { get; set; }
public string status_message { get; set; } public string status_message { get; set; }
public int budget { get; set; } public int budget { get; set; }
@ -69,6 +69,8 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
public AlternativeTitles alternative_titles { get; set; } public AlternativeTitles alternative_titles { get; set; }
public ReleaseDatesResource release_dates { get; set; } public ReleaseDatesResource release_dates { get; set; }
public VideosResource videos { get; set; } public VideosResource videos { get; set; }
public CreditsResource credits { get; set; }
} }
public class ReleaseDatesResource public class ReleaseDatesResource
@ -76,6 +78,12 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
public List<ReleaseDates> results { get; set; } public List<ReleaseDates> results { get; set; }
} }
public class CreditsResource
{
public List<CastResource> Cast { get; set; }
public List<CrewResource> Crew { get; set; }
}
public class ReleaseDate public class ReleaseDate
{ {
public string certification { get; set; } public string certification { get; set; }
@ -91,7 +99,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
public List<ReleaseDate> release_dates { get; set; } public List<ReleaseDate> release_dates { get; set; }
} }
public class Belongs_To_Collection public class CollectionResource
{ {
public int id { get; set; } public int id { get; set; }
public string name { get; set; } public string name { get; set; }
@ -139,6 +147,26 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
public List<Video> results { get; set; } public List<Video> results { get; set; }
} }
public class CrewResource
{
public string Name { get; set; }
public string Department { get; set; }
public string Job { get; set; }
public string Credit_Id { get; set; }
public int Id { get; set; }
public string Profile_Path { get; set; }
}
public class CastResource
{
public string Name { get; set; }
public string Character { get; set; }
public string Credit_Id { get; set; }
public int Id { get; set; }
public int Order { get; set; }
public string Profile_Path { get; set; }
}
public class Video public class Video
{ {
public string id { get; set; } public string id { get; set; }

@ -16,6 +16,7 @@ using NzbDrone.Core.MetadataSource.RadarrAPI;
using NzbDrone.Core.MetadataSource.SkyHook.Resource; using NzbDrone.Core.MetadataSource.SkyHook.Resource;
using NzbDrone.Core.Movies; using NzbDrone.Core.Movies;
using NzbDrone.Core.Movies.AlternativeTitles; using NzbDrone.Core.Movies.AlternativeTitles;
using NzbDrone.Core.Movies.Credits;
using NzbDrone.Core.NetImport.ImportExclusions; using NzbDrone.Core.NetImport.ImportExclusions;
using NzbDrone.Core.Parser; using NzbDrone.Core.Parser;
using NzbDrone.Core.Profiles; using NzbDrone.Core.Profiles;
@ -76,7 +77,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
return new HashSet<int>(response.Resource.results.Select(c => c.id)); return new HashSet<int>(response.Resource.results.Select(c => c.id));
} }
public Movie GetMovieInfo(int tmdbId, Profile profile = null, bool hasPreDBEntry = false) public Tuple<Movie, List<Credit>> GetMovieInfo(int tmdbId, Profile profile, bool hasPreDBEntry)
{ {
var langCode = profile != null ? IsoLanguages.Get(profile.Language)?.TwoLetterCode ?? "en" : "en"; var langCode = profile != null ? IsoLanguages.Get(profile.Language)?.TwoLetterCode ?? "en" : "en";
@ -84,7 +85,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
.SetSegment("route", "movie") .SetSegment("route", "movie")
.SetSegment("id", tmdbId.ToString()) .SetSegment("id", tmdbId.ToString())
.SetSegment("secondaryRoute", "") .SetSegment("secondaryRoute", "")
.AddQueryParam("append_to_response", "alternative_titles,release_dates,videos") .AddQueryParam("append_to_response", "alternative_titles,release_dates,videos,credits")
.AddQueryParam("language", langCode.ToUpper()) .AddQueryParam("language", langCode.ToUpper())
// .AddQueryParam("country", "US") // .AddQueryParam("country", "US")
@ -309,7 +310,20 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
movie.AlternativeTitles.AddRange(altTitles); movie.AlternativeTitles.AddRange(altTitles);
return movie; var people = new List<Credit>();
people.AddRange(resource.credits.Cast.Select(MapCast).ToList());
people.AddRange(resource.credits.Crew.Select(MapCrew).ToList());
if (resource.belongs_to_collection != null)
{
movie.Collection = MapCollection(resource.belongs_to_collection);
movie.Collection.Images.Add(_configService.GetCoverForURL(resource.belongs_to_collection.poster_path, MediaCoverTypes.Poster));
movie.Collection.Images.Add(_configService.GetCoverForURL(resource.belongs_to_collection.backdrop_path, MediaCoverTypes.Fanart));
}
return new Tuple<Movie, List<Credit>>(movie, people);
} }
public Movie GetMovieInfo(string imdbId) public Movie GetMovieInfo(string imdbId)
@ -477,7 +491,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
try try
{ {
return new List<Movie> { GetMovieInfo(tmdbid) }; return new List<Movie> { GetMovieInfo(tmdbid, null, false).Item1 };
} }
catch (MovieNotFoundException) catch (MovieNotFoundException)
{ {
@ -628,61 +642,61 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
return null; return null;
} }
private static Actor MapActors(ActorResource arg) private static Credit MapCast(CastResource arg)
{ {
var newActor = new Actor var newActor = new Credit
{ {
Name = arg.Name, Name = arg.Name,
Character = arg.Character Character = arg.Character,
Order = arg.Order,
CreditTmdbId = arg.Credit_Id,
PersonTmdbId = arg.Id,
Type = CreditType.Cast
}; };
if (arg.Image != null) if (arg.Profile_Path != null)
{ {
newActor.Images = new List<MediaCover.MediaCover> newActor.Images = new List<MediaCover.MediaCover>
{ {
new MediaCover.MediaCover(MediaCoverTypes.Headshot, arg.Image) new MediaCover.MediaCover(MediaCoverTypes.Headshot, "https://image.tmdb.org/t/p/original" + arg.Profile_Path)
}; };
} }
return newActor; return newActor;
} }
private static Ratings MapRatings(RatingResource rating) private static Credit MapCrew(CrewResource arg)
{ {
if (rating == null) var newActor = new Credit
{ {
return new Ratings(); Name = arg.Name,
} Department = arg.Department,
Job = arg.Job,
CreditTmdbId = arg.Credit_Id,
PersonTmdbId = arg.Id,
Type = CreditType.Crew
};
return new Ratings if (arg.Profile_Path != null)
{ {
Votes = rating.Count, newActor.Images = new List<MediaCover.MediaCover>
Value = rating.Value {
}; new MediaCover.MediaCover(MediaCoverTypes.Headshot, "https://image.tmdb.org/t/p/original" + arg.Profile_Path)
};
}
return newActor;
} }
private static MediaCover.MediaCover MapImage(ImageResource arg) private static MovieCollection MapCollection(CollectionResource arg)
{ {
return new MediaCover.MediaCover var newCollection = new MovieCollection
{ {
Url = arg.Url, Name = arg.name,
CoverType = MapCoverType(arg.CoverType) TmdbId = arg.id,
}; };
}
private static MediaCoverTypes MapCoverType(string coverType) return newCollection;
{
switch (coverType.ToLower())
{
case "poster":
return MediaCoverTypes.Poster;
case "banner":
return MediaCoverTypes.Banner;
case "fanart":
return MediaCoverTypes.Fanart;
default:
return MediaCoverTypes.Unknown;
}
} }
public Movie MapMovieToTmdbMovie(Movie movie) public Movie MapMovieToTmdbMovie(Movie movie)
@ -692,7 +706,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
Movie newMovie = movie; Movie newMovie = movie;
if (movie.TmdbId > 0) if (movie.TmdbId > 0)
{ {
newMovie = GetMovieInfo(movie.TmdbId); newMovie = GetMovieInfo(movie.TmdbId, null, false).Item1;
} }
else if (movie.ImdbId.IsNotNullOrWhiteSpace()) else if (movie.ImdbId.IsNotNullOrWhiteSpace())
{ {

@ -0,0 +1,30 @@
using System.Collections.Generic;
using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.Movies.Credits
{
public class Credit : ModelBase
{
public Credit()
{
Images = new List<MediaCover.MediaCover>();
}
public string Name { get; set; }
public string CreditTmdbId { get; set; }
public int PersonTmdbId { get; set; }
public int MovieId { get; set; }
public List<MediaCover.MediaCover> Images { get; set; }
public string Department { get; set; }
public string Job { get; set; }
public string Character { get; set; }
public int Order { get; set; }
public CreditType Type { get; set; }
}
public enum CreditType
{
Cast,
Crew
}
}

@ -0,0 +1,24 @@
using System.Collections.Generic;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Messaging.Events;
namespace NzbDrone.Core.Movies.Credits
{
public interface ICreditRepository : IBasicRepository<Credit>
{
List<Credit> FindByMovieId(int movieId);
}
public class CreditRepository : BasicRepository<Credit>, ICreditRepository
{
public CreditRepository(IMainDatabase database, IEventAggregator eventAggregator)
: base(database, eventAggregator)
{
}
public List<Credit> FindByMovieId(int movieId)
{
return Query(x => x.MovieId == movieId);
}
}
}

@ -0,0 +1,90 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Movies.Events;
namespace NzbDrone.Core.Movies.Credits
{
public interface ICreditService
{
List<Credit> GetAllCreditsForMovie(int movieId);
Credit AddCredit(Credit credit, Movie movie);
List<Credit> AddCredits(List<Credit> credits, Movie movie);
Credit GetById(int id);
List<Credit> GetAllCredits();
List<Credit> UpdateCredits(List<Credit> credits, Movie movie);
}
public class CreditService : ICreditService, IHandleAsync<MovieDeletedEvent>
{
private readonly ICreditRepository _creditRepo;
public CreditService(ICreditRepository creditRepo)
{
_creditRepo = creditRepo;
}
public List<Credit> GetAllCreditsForMovie(int movieId)
{
return _creditRepo.FindByMovieId(movieId).ToList();
}
public Credit AddCredit(Credit credit, Movie movie)
{
credit.MovieId = movie.Id;
return _creditRepo.Insert(credit);
}
public List<Credit> AddCredits(List<Credit> credits, Movie movie)
{
credits.ForEach(t => t.MovieId = movie.Id);
_creditRepo.InsertMany(credits);
return credits;
}
public Credit GetById(int id)
{
return _creditRepo.Get(id);
}
public List<Credit> GetAllCredits()
{
return _creditRepo.All().ToList();
}
public void RemoveTitle(Credit credit)
{
_creditRepo.Delete(credit);
}
public List<Credit> UpdateCredits(List<Credit> credits, Movie movie)
{
int movieId = movie.Id;
// First update the movie ids so we can correlate them later.
credits.ForEach(t => t.MovieId = movieId);
// Now find credits to delete, update and insert.
var existingCredits = _creditRepo.FindByMovieId(movieId);
// Should never have multiple credits with same credit_id, but check to ensure incase TMDB is on fritz
var dupeFreeCredits = credits.DistinctBy(m => m.CreditTmdbId).ToList();
var insert = dupeFreeCredits.Where(t => !existingCredits.Any(c => c.CreditTmdbId == t.CreditTmdbId)).ToList();
var update = existingCredits.Where(t => dupeFreeCredits.Any(c => c.CreditTmdbId == t.CreditTmdbId)).ToList();
var delete = existingCredits.Where(t => !dupeFreeCredits.Any(c => c.CreditTmdbId == t.CreditTmdbId)).ToList();
_creditRepo.DeleteMany(delete);
_creditRepo.UpdateMany(update);
_creditRepo.InsertMany(insert);
return credits;
}
public void HandleAsync(MovieDeletedEvent message)
{
_creditRepo.DeleteMany(GetAllCreditsForMovie(message.Movie.Id));
}
}
}

@ -14,7 +14,6 @@ namespace NzbDrone.Core.Movies
{ {
Images = new List<MediaCover.MediaCover>(); Images = new List<MediaCover.MediaCover>();
Genres = new List<string>(); Genres = new List<string>();
Actors = new List<Actor>();
Tags = new HashSet<int>(); Tags = new HashSet<int>();
AlternativeTitles = new List<AlternativeTitle>(); AlternativeTitles = new List<AlternativeTitle>();
} }
@ -38,7 +37,9 @@ namespace NzbDrone.Core.Movies
public int Year { get; set; } public int Year { get; set; }
public Ratings Ratings { get; set; } public Ratings Ratings { get; set; }
public List<string> Genres { get; set; } public List<string> Genres { get; set; }
public List<Actor> Actors { get; set; }
public MovieCollection Collection { get; set; }
public string Certification { get; set; } public string Certification { get; set; }
public string RootFolderPath { get; set; } public string RootFolderPath { get; set; }
public MoviePathState PathState { get; set; } public MoviePathState PathState { get; set; }

@ -1,17 +1,17 @@
using System.Collections.Generic; using System.Collections.Generic;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.Movies namespace NzbDrone.Core.Movies
{ {
public class Actor : IEmbeddedDocument public class MovieCollection : IEmbeddedDocument
{ {
public Actor() public MovieCollection()
{ {
Images = new List<MediaCover.MediaCover>(); Images = new List<MediaCover.MediaCover>();
} }
public string Name { get; set; } public string Name { get; set; }
public string Character { get; set; } public int TmdbId { get; set; }
public List<MediaCover.MediaCover> Images { get; set; } public List<MediaCover.MediaCover> Images { get; set; }
} }
} }

@ -5,8 +5,6 @@ using System.Linq;
using NLog; using NLog;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Common.Instrumentation.Extensions; using NzbDrone.Common.Instrumentation.Extensions;
//using NzbDrone.Core.DataAugmentation.DailyMovie;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.Exceptions; using NzbDrone.Core.Exceptions;
using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles;
@ -16,6 +14,7 @@ using NzbDrone.Core.MetadataSource;
using NzbDrone.Core.MetadataSource.RadarrAPI; using NzbDrone.Core.MetadataSource.RadarrAPI;
using NzbDrone.Core.Movies.AlternativeTitles; using NzbDrone.Core.Movies.AlternativeTitles;
using NzbDrone.Core.Movies.Commands; using NzbDrone.Core.Movies.Commands;
using NzbDrone.Core.Movies.Credits;
using NzbDrone.Core.Movies.Events; using NzbDrone.Core.Movies.Events;
namespace NzbDrone.Core.Movies namespace NzbDrone.Core.Movies
@ -25,6 +24,7 @@ namespace NzbDrone.Core.Movies
private readonly IProvideMovieInfo _movieInfo; private readonly IProvideMovieInfo _movieInfo;
private readonly IMovieService _movieService; private readonly IMovieService _movieService;
private readonly IAlternativeTitleService _titleService; private readonly IAlternativeTitleService _titleService;
private readonly ICreditService _creditService;
private readonly IEventAggregator _eventAggregator; private readonly IEventAggregator _eventAggregator;
private readonly IManageCommandQueue _commandQueueManager; private readonly IManageCommandQueue _commandQueueManager;
private readonly IDiskScanService _diskScanService; private readonly IDiskScanService _diskScanService;
@ -37,6 +37,7 @@ namespace NzbDrone.Core.Movies
public RefreshMovieService(IProvideMovieInfo movieInfo, public RefreshMovieService(IProvideMovieInfo movieInfo,
IMovieService movieService, IMovieService movieService,
IAlternativeTitleService titleService, IAlternativeTitleService titleService,
ICreditService creditService,
IEventAggregator eventAggregator, IEventAggregator eventAggregator,
IDiskScanService diskScanService, IDiskScanService diskScanService,
IRadarrAPIClient apiClient, IRadarrAPIClient apiClient,
@ -48,6 +49,7 @@ namespace NzbDrone.Core.Movies
_movieInfo = movieInfo; _movieInfo = movieInfo;
_movieService = movieService; _movieService = movieService;
_titleService = titleService; _titleService = titleService;
_creditService = creditService;
_eventAggregator = eventAggregator; _eventAggregator = eventAggregator;
_apiClient = apiClient; _apiClient = apiClient;
_commandQueueManager = commandQueue; _commandQueueManager = commandQueue;
@ -61,9 +63,9 @@ namespace NzbDrone.Core.Movies
{ {
_logger.ProgressInfo("Updating Info for {0}", movie.Title); _logger.ProgressInfo("Updating Info for {0}", movie.Title);
Movie movieInfo; var tuple = _movieInfo.GetMovieInfo(movie.TmdbId, movie.Profile, movie.HasPreDBEntry);
movieInfo = _movieInfo.GetMovieInfo(movie.TmdbId, movie.Profile, movie.HasPreDBEntry); var movieInfo = tuple.Item1;
if (movie.TmdbId != movieInfo.TmdbId) if (movie.TmdbId != movieInfo.TmdbId)
{ {
@ -82,7 +84,7 @@ namespace NzbDrone.Core.Movies
movie.Runtime = movieInfo.Runtime; movie.Runtime = movieInfo.Runtime;
movie.Images = movieInfo.Images; movie.Images = movieInfo.Images;
movie.Ratings = movieInfo.Ratings; movie.Ratings = movieInfo.Ratings;
movie.Actors = movieInfo.Actors; movie.Collection = movieInfo.Collection;
movie.Genres = movieInfo.Genres; movie.Genres = movieInfo.Genres;
movie.Certification = movieInfo.Certification; movie.Certification = movieInfo.Certification;
movie.InCinemas = movieInfo.InCinemas; movie.InCinemas = movieInfo.InCinemas;
@ -137,6 +139,7 @@ namespace NzbDrone.Core.Movies
} }
_movieService.UpdateMovie(new List<Movie> { movie }); _movieService.UpdateMovie(new List<Movie> { movie });
_creditService.UpdateCredits(tuple.Item2, movie);
try try
{ {

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using NzbDrone.Core.Movies.Credits;
using Radarr.Http;
namespace Radarr.Api.V3.Credits
{
public class CreditModule : RadarrRestModule<CreditResource>
{
private readonly ICreditService _creditService;
public CreditModule(ICreditService creditService)
{
_creditService = creditService;
GetResourceById = GetCredit;
GetResourceAll = GetCredits;
}
private CreditResource GetCredit(int id)
{
return _creditService.GetById(id).ToResource();
}
private List<CreditResource> GetCredits()
{
var movieIdQuery = Request.Query.MovieId;
if (movieIdQuery.HasValue)
{
int movieId = Convert.ToInt32(movieIdQuery.Value);
return _creditService.GetAllCreditsForMovie(movieId).ToResource();
}
return _creditService.GetAllCredits().ToResource();
}
}
}

@ -0,0 +1,80 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.MediaCover;
using NzbDrone.Core.Movies.Credits;
using Radarr.Http.REST;
namespace Radarr.Api.V3.Credits
{
public class CreditResource : RestResource
{
public CreditResource()
{
}
public string PersonName { get; set; }
public string CreditTmdbId { get; set; }
public int PersonTmdbId { get; set; }
public int MovieId { get; set; }
public List<MediaCover> Images { get; set; }
public string Department { get; set; }
public string Job { get; set; }
public string Character { get; set; }
public int Order { get; set; }
public CreditType Type { get; set; }
}
public static class CreditResourceMapper
{
public static CreditResource ToResource(this Credit model)
{
if (model == null)
{
return null;
}
return new CreditResource
{
Id = model.Id,
MovieId = model.MovieId,
CreditTmdbId = model.CreditTmdbId,
PersonTmdbId = model.PersonTmdbId,
PersonName = model.Name,
Order = model.Order,
Character = model.Character,
Department = model.Department,
Images = model.Images,
Job = model.Job,
Type = model.Type
};
}
public static List<CreditResource> ToResource(this IEnumerable<Credit> credits)
{
return credits.Select(ToResource).ToList();
}
public static Credit ToModel(this CreditResource resource)
{
if (resource == null)
{
return null;
}
return new Credit
{
Id = resource.Id,
MovieId = resource.MovieId,
Name = resource.PersonName,
Order = resource.Order,
Character = resource.Character,
Department = resource.Department,
Job = resource.Job,
Type = resource.Type,
Images = resource.Images,
CreditTmdbId = resource.CreditTmdbId,
PersonTmdbId = resource.PersonTmdbId
};
}
}
}

@ -33,7 +33,7 @@ namespace Radarr.Api.V3.Movies
int tmdbId = -1; int tmdbId = -1;
if (int.TryParse(Request.Query.tmdbId, out tmdbId)) if (int.TryParse(Request.Query.tmdbId, out tmdbId))
{ {
var result = _movieInfo.GetMovieInfo(tmdbId, null, true); var result = _movieInfo.GetMovieInfo(tmdbId, null, true).Item1;
return result.ToResource(); return result.ToResource();
} }

@ -67,6 +67,7 @@ namespace Radarr.Api.V3.Movies
public AddMovieOptions AddOptions { get; set; } public AddMovieOptions AddOptions { get; set; }
public Ratings Ratings { get; set; } public Ratings Ratings { get; set; }
public MovieFileResource MovieFile { get; set; } public MovieFileResource MovieFile { get; set; }
public MovieCollection Collection { get; set; }
} }
public static class MovieResourceMapper public static class MovieResourceMapper
@ -127,7 +128,8 @@ namespace Radarr.Api.V3.Movies
Ratings = model.Ratings, Ratings = model.Ratings,
MovieFile = movieFile, MovieFile = movieFile,
YouTubeTrailerId = model.YouTubeTrailerId, YouTubeTrailerId = model.YouTubeTrailerId,
Studio = model.Studio Studio = model.Studio,
Collection = model.Collection
}; };
} }

Loading…
Cancel
Save