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

This commit is contained in:
Qstick 2019-11-02 15:32:05 -04:00
parent dec0e3eec3
commit d76423a305
20 changed files with 500 additions and 68 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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()

View File

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

View File

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

View File

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

View File

@ -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())
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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
{

View File

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

View File

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

View File

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

View File

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