mirror of https://github.com/Radarr/Radarr
New: Scrape Cast/Crew/Collection Data on Movie Refresh
This commit is contained in:
parent
dec0e3eec3
commit
d76423a305
|
@ -28,7 +28,7 @@ namespace NzbDrone.Api.Movies
|
|||
int tmdbId = -1;
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace NzbDrone.Core.Test.MetadataSource.SkyHook
|
|||
[TestCase(70981, "Prometheus")]
|
||||
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);
|
||||
|
||||
|
|
|
@ -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" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<RuntimeFiles Include="..\Runtimes\$(RuntimeIdentifier)\*"/>
|
||||
<RuntimeFiles Include="..\Runtimes\$(RuntimeIdentifier)\*" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\Logo\1024.png">
|
||||
|
@ -30,10 +30,10 @@
|
|||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Target Name="CopyRuntimeFilesOnBuild" AfterTargets="AfterBuild" >
|
||||
<Target Name="CopyRuntimeFilesOnBuild" AfterTargets="AfterBuild">
|
||||
<Copy SourceFiles="@(RuntimeFiles)" DestinationFolder="$(OutDir)" />
|
||||
</Target>
|
||||
<Target Name="CopyRuntimeFilesOnPublish" AfterTargets="Publish" >
|
||||
<Target Name="CopyRuntimeFilesOnPublish" AfterTargets="Publish">
|
||||
<Copy SourceFiles="@(RuntimeFiles)" DestinationFolder="$(PublishDir)" />
|
||||
</Target>
|
||||
</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.Movies;
|
||||
using NzbDrone.Core.Movies.AlternativeTitles;
|
||||
using NzbDrone.Core.Movies.Credits;
|
||||
using NzbDrone.Core.NetImport;
|
||||
using NzbDrone.Core.NetImport.ImportExclusions;
|
||||
using NzbDrone.Core.Notifications;
|
||||
|
@ -96,11 +97,12 @@ namespace NzbDrone.Core.Datastore
|
|||
.Ignore(f => f.Path);
|
||||
|
||||
Mapper.Entity<Movie>("Movies").RegisterModel()
|
||||
.Ignore(s => s.RootFolderPath)
|
||||
.Ignore(m => m.Actors);
|
||||
.Ignore(s => s.RootFolderPath);
|
||||
|
||||
Mapper.Entity<AlternativeTitle>("AlternativeTitles").RegisterModel();
|
||||
|
||||
Mapper.Entity<Credit>("Credits").RegisterModel();
|
||||
|
||||
Mapper.Entity<ImportExclusion>("ImportExclusions").RegisterModel();
|
||||
|
||||
Mapper.Entity<QualityDefinition>("QualityDefinitions").RegisterModel()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Movies;
|
||||
using NzbDrone.Core.Movies.Credits;
|
||||
using NzbDrone.Core.Profiles;
|
||||
|
||||
namespace NzbDrone.Core.MetadataSource
|
||||
|
@ -8,7 +9,7 @@ namespace NzbDrone.Core.MetadataSource
|
|||
public interface IProvideMovieInfo
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 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 string status_message { get; set; }
|
||||
public int budget { get; set; }
|
||||
|
@ -69,6 +69,8 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
|
|||
public AlternativeTitles alternative_titles { get; set; }
|
||||
public ReleaseDatesResource release_dates { get; set; }
|
||||
public VideosResource videos { get; set; }
|
||||
|
||||
public CreditsResource credits { get; set; }
|
||||
}
|
||||
|
||||
public class ReleaseDatesResource
|
||||
|
@ -76,6 +78,12 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
|
|||
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 string certification { get; set; }
|
||||
|
@ -91,7 +99,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
|
|||
public List<ReleaseDate> release_dates { get; set; }
|
||||
}
|
||||
|
||||
public class Belongs_To_Collection
|
||||
public class CollectionResource
|
||||
{
|
||||
public int id { get; set; }
|
||||
public string name { get; set; }
|
||||
|
@ -139,6 +147,26 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
|
|||
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 string id { get; set; }
|
||||
|
|
|
@ -16,6 +16,7 @@ using NzbDrone.Core.MetadataSource.RadarrAPI;
|
|||
using NzbDrone.Core.MetadataSource.SkyHook.Resource;
|
||||
using NzbDrone.Core.Movies;
|
||||
using NzbDrone.Core.Movies.AlternativeTitles;
|
||||
using NzbDrone.Core.Movies.Credits;
|
||||
using NzbDrone.Core.NetImport.ImportExclusions;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Profiles;
|
||||
|
@ -76,7 +77,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
|||
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";
|
||||
|
||||
|
@ -84,7 +85,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
|||
.SetSegment("route", "movie")
|
||||
.SetSegment("id", tmdbId.ToString())
|
||||
.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("country", "US")
|
||||
|
@ -309,7 +310,20 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
|||
|
||||
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)
|
||||
|
@ -477,7 +491,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
|||
|
||||
try
|
||||
{
|
||||
return new List<Movie> { GetMovieInfo(tmdbid) };
|
||||
return new List<Movie> { GetMovieInfo(tmdbid, null, false).Item1 };
|
||||
}
|
||||
catch (MovieNotFoundException)
|
||||
{
|
||||
|
@ -628,61 +642,61 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
|||
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,
|
||||
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>
|
||||
{
|
||||
new MediaCover.MediaCover(MediaCoverTypes.Headshot, arg.Image)
|
||||
new MediaCover.MediaCover(MediaCoverTypes.Headshot, "https://image.tmdb.org/t/p/original" + arg.Profile_Path)
|
||||
};
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
if (arg.Profile_Path != null)
|
||||
{
|
||||
newActor.Images = new List<MediaCover.MediaCover>
|
||||
{
|
||||
new MediaCover.MediaCover(MediaCoverTypes.Headshot, "https://image.tmdb.org/t/p/original" + arg.Profile_Path)
|
||||
};
|
||||
}
|
||||
|
||||
return new Ratings
|
||||
{
|
||||
Votes = rating.Count,
|
||||
Value = rating.Value
|
||||
};
|
||||
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,
|
||||
CoverType = MapCoverType(arg.CoverType)
|
||||
Name = arg.name,
|
||||
TmdbId = arg.id,
|
||||
};
|
||||
}
|
||||
|
||||
private static MediaCoverTypes MapCoverType(string coverType)
|
||||
{
|
||||
switch (coverType.ToLower())
|
||||
{
|
||||
case "poster":
|
||||
return MediaCoverTypes.Poster;
|
||||
case "banner":
|
||||
return MediaCoverTypes.Banner;
|
||||
case "fanart":
|
||||
return MediaCoverTypes.Fanart;
|
||||
default:
|
||||
return MediaCoverTypes.Unknown;
|
||||
}
|
||||
return newCollection;
|
||||
}
|
||||
|
||||
public Movie MapMovieToTmdbMovie(Movie movie)
|
||||
|
@ -692,7 +706,7 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
|
|||
Movie newMovie = movie;
|
||||
if (movie.TmdbId > 0)
|
||||
{
|
||||
newMovie = GetMovieInfo(movie.TmdbId);
|
||||
newMovie = GetMovieInfo(movie.TmdbId, null, false).Item1;
|
||||
}
|
||||
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>();
|
||||
Genres = new List<string>();
|
||||
Actors = new List<Actor>();
|
||||
Tags = new HashSet<int>();
|
||||
AlternativeTitles = new List<AlternativeTitle>();
|
||||
}
|
||||
|
@ -38,7 +37,9 @@ namespace NzbDrone.Core.Movies
|
|||
public int Year { get; set; }
|
||||
public Ratings Ratings { 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 RootFolderPath { get; set; }
|
||||
public MoviePathState PathState { get; set; }
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Datastore;
|
||||
|
||||
namespace NzbDrone.Core.Movies
|
||||
{
|
||||
public class Actor : IEmbeddedDocument
|
||||
public class MovieCollection : IEmbeddedDocument
|
||||
{
|
||||
public Actor()
|
||||
public MovieCollection()
|
||||
{
|
||||
Images = new List<MediaCover.MediaCover>();
|
||||
}
|
||||
|
||||
public string Name { get; set; }
|
||||
public string Character { get; set; }
|
||||
public int TmdbId { get; set; }
|
||||
public List<MediaCover.MediaCover> Images { get; set; }
|
||||
}
|
||||
}
|
|
@ -5,8 +5,6 @@ using System.Linq;
|
|||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Instrumentation.Extensions;
|
||||
|
||||
//using NzbDrone.Core.DataAugmentation.DailyMovie;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Exceptions;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
|
@ -16,6 +14,7 @@ using NzbDrone.Core.MetadataSource;
|
|||
using NzbDrone.Core.MetadataSource.RadarrAPI;
|
||||
using NzbDrone.Core.Movies.AlternativeTitles;
|
||||
using NzbDrone.Core.Movies.Commands;
|
||||
using NzbDrone.Core.Movies.Credits;
|
||||
using NzbDrone.Core.Movies.Events;
|
||||
|
||||
namespace NzbDrone.Core.Movies
|
||||
|
@ -25,6 +24,7 @@ namespace NzbDrone.Core.Movies
|
|||
private readonly IProvideMovieInfo _movieInfo;
|
||||
private readonly IMovieService _movieService;
|
||||
private readonly IAlternativeTitleService _titleService;
|
||||
private readonly ICreditService _creditService;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly IManageCommandQueue _commandQueueManager;
|
||||
private readonly IDiskScanService _diskScanService;
|
||||
|
@ -37,6 +37,7 @@ namespace NzbDrone.Core.Movies
|
|||
public RefreshMovieService(IProvideMovieInfo movieInfo,
|
||||
IMovieService movieService,
|
||||
IAlternativeTitleService titleService,
|
||||
ICreditService creditService,
|
||||
IEventAggregator eventAggregator,
|
||||
IDiskScanService diskScanService,
|
||||
IRadarrAPIClient apiClient,
|
||||
|
@ -48,6 +49,7 @@ namespace NzbDrone.Core.Movies
|
|||
_movieInfo = movieInfo;
|
||||
_movieService = movieService;
|
||||
_titleService = titleService;
|
||||
_creditService = creditService;
|
||||
_eventAggregator = eventAggregator;
|
||||
_apiClient = apiClient;
|
||||
_commandQueueManager = commandQueue;
|
||||
|
@ -61,9 +63,9 @@ namespace NzbDrone.Core.Movies
|
|||
{
|
||||
_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)
|
||||
{
|
||||
|
@ -82,7 +84,7 @@ namespace NzbDrone.Core.Movies
|
|||
movie.Runtime = movieInfo.Runtime;
|
||||
movie.Images = movieInfo.Images;
|
||||
movie.Ratings = movieInfo.Ratings;
|
||||
movie.Actors = movieInfo.Actors;
|
||||
movie.Collection = movieInfo.Collection;
|
||||
movie.Genres = movieInfo.Genres;
|
||||
movie.Certification = movieInfo.Certification;
|
||||
movie.InCinemas = movieInfo.InCinemas;
|
||||
|
@ -137,6 +139,7 @@ namespace NzbDrone.Core.Movies
|
|||
}
|
||||
|
||||
_movieService.UpdateMovie(new List<Movie> { movie });
|
||||
_creditService.UpdateCredits(tuple.Item2, movie);
|
||||
|
||||
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;
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ namespace Radarr.Api.V3.Movies
|
|||
public AddMovieOptions AddOptions { get; set; }
|
||||
public Ratings Ratings { get; set; }
|
||||
public MovieFileResource MovieFile { get; set; }
|
||||
public MovieCollection Collection { get; set; }
|
||||
}
|
||||
|
||||
public static class MovieResourceMapper
|
||||
|
@ -127,7 +128,8 @@ namespace Radarr.Api.V3.Movies
|
|||
Ratings = model.Ratings,
|
||||
MovieFile = movieFile,
|
||||
YouTubeTrailerId = model.YouTubeTrailerId,
|
||||
Studio = model.Studio
|
||||
Studio = model.Studio,
|
||||
Collection = model.Collection
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue