1
0
mirror of https://github.com/Radarr/Radarr.git synced 2024-10-03 22:57:18 +02:00

Fixed: Speed up Collections API Endpoint

This commit is contained in:
Qstick 2022-06-02 19:31:42 -05:00
parent 301a6904c0
commit 696bb845a5
4 changed files with 86 additions and 8 deletions

View File

@ -2,7 +2,9 @@
using System.Linq; using System.Linq;
using NLog; using NLog;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
using NzbDrone.Core.Languages;
using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Movies.Translations;
namespace NzbDrone.Core.Movies namespace NzbDrone.Core.Movies
{ {
@ -10,6 +12,7 @@ public interface IMovieMetadataRepository : IBasicRepository<MovieMetadata>
{ {
MovieMetadata FindByTmdbId(int tmdbId); MovieMetadata FindByTmdbId(int tmdbId);
List<MovieMetadata> FindById(List<int> tmdbIds); List<MovieMetadata> FindById(List<int> tmdbIds);
List<MovieMetadata> GetMoviesWithCollections();
List<MovieMetadata> GetMoviesByCollectionTmdbId(int collectionId); List<MovieMetadata> GetMoviesByCollectionTmdbId(int collectionId);
bool UpsertMany(List<MovieMetadata> data); bool UpsertMany(List<MovieMetadata> data);
} }
@ -34,6 +37,43 @@ public List<MovieMetadata> FindById(List<int> tmdbIds)
return Query(x => Enumerable.Contains(tmdbIds, x.TmdbId)); return Query(x => Enumerable.Contains(tmdbIds, x.TmdbId));
} }
public List<MovieMetadata> GetMoviesWithCollections()
{
var movieDictionary = new Dictionary<int, MovieMetadata>();
var builder = new SqlBuilder(_database.DatabaseType)
.LeftJoin<MovieMetadata, MovieTranslation>((mm, t) => mm.Id == t.MovieMetadataId)
.Where<MovieMetadata>(x => x.CollectionTmdbId > 0);
_ = _database.QueryJoined<MovieMetadata, MovieTranslation>(
builder,
(metadata, translation) =>
{
MovieMetadata movieEntry;
if (!movieDictionary.TryGetValue(metadata.Id, out movieEntry))
{
movieEntry = metadata;
movieDictionary.Add(movieEntry.Id, movieEntry);
}
if (translation != null)
{
movieEntry.Translations.Add(translation);
}
else
{
// Add a translation to avoid filename builder making another call thinking translations are not loaded
// Optimize this later by pulling translations with metadata always
movieEntry.Translations.Add(new MovieTranslation { Title = movieEntry.Title, Language = Language.English });
}
return movieEntry;
});
return movieDictionary.Values.ToList();
}
public List<MovieMetadata> GetMoviesByCollectionTmdbId(int collectionId) public List<MovieMetadata> GetMoviesByCollectionTmdbId(int collectionId)
{ {
return Query(x => x.CollectionTmdbId == collectionId); return Query(x => x.CollectionTmdbId == collectionId);

View File

@ -6,6 +6,7 @@ public interface IMovieMetadataService
{ {
MovieMetadata Get(int id); MovieMetadata Get(int id);
MovieMetadata FindByTmdbId(int tmdbid); MovieMetadata FindByTmdbId(int tmdbid);
List<MovieMetadata> GetMoviesWithCollections();
List<MovieMetadata> GetMoviesByCollectionTmdbId(int collectionId); List<MovieMetadata> GetMoviesByCollectionTmdbId(int collectionId);
bool Upsert(MovieMetadata movie); bool Upsert(MovieMetadata movie);
bool UpsertMany(List<MovieMetadata> movies); bool UpsertMany(List<MovieMetadata> movies);
@ -25,6 +26,11 @@ public MovieMetadata FindByTmdbId(int tmdbid)
return _movieMetadataRepository.FindByTmdbId(tmdbid); return _movieMetadataRepository.FindByTmdbId(tmdbid);
} }
public List<MovieMetadata> GetMoviesWithCollections()
{
return _movieMetadataRepository.GetMoviesWithCollections();
}
public List<MovieMetadata> GetMoviesByCollectionTmdbId(int collectionId) public List<MovieMetadata> GetMoviesByCollectionTmdbId(int collectionId)
{ {
return _movieMetadataRepository.GetMoviesByCollectionTmdbId(collectionId); return _movieMetadataRepository.GetMoviesByCollectionTmdbId(collectionId);

View File

@ -24,18 +24,21 @@ public class CollectionController : RestControllerWithSignalR<CollectionResource
private readonly IMovieService _movieService; private readonly IMovieService _movieService;
private readonly IMovieMetadataService _movieMetadataService; private readonly IMovieMetadataService _movieMetadataService;
private readonly IBuildFileNames _fileNameBuilder; private readonly IBuildFileNames _fileNameBuilder;
private readonly INamingConfigService _namingService;
public CollectionController(IBroadcastSignalRMessage signalRBroadcaster, public CollectionController(IBroadcastSignalRMessage signalRBroadcaster,
IMovieCollectionService collectionService, IMovieCollectionService collectionService,
IMovieService movieService, IMovieService movieService,
IMovieMetadataService movieMetadataService, IMovieMetadataService movieMetadataService,
IBuildFileNames fileNameBuilder) IBuildFileNames fileNameBuilder,
INamingConfigService namingService)
: base(signalRBroadcaster) : base(signalRBroadcaster)
{ {
_collectionService = collectionService; _collectionService = collectionService;
_movieService = movieService; _movieService = movieService;
_movieMetadataService = movieMetadataService; _movieMetadataService = movieMetadataService;
_fileNameBuilder = fileNameBuilder; _fileNameBuilder = fileNameBuilder;
_namingService = namingService;
} }
protected override CollectionResource GetResourceById(int id) protected override CollectionResource GetResourceById(int id)
@ -46,7 +49,9 @@ protected override CollectionResource GetResourceById(int id)
[HttpGet] [HttpGet]
public List<CollectionResource> GetCollections() public List<CollectionResource> GetCollections()
{ {
return _collectionService.GetAllCollections().Select(c => MapToResource(c)).ToList(); var collectionMovies = _movieMetadataService.GetMoviesWithCollections();
return MapToResource(_collectionService.GetAllCollections(), collectionMovies).ToList();
} }
[RestPutById] [RestPutById]
@ -92,6 +97,27 @@ public ActionResult UpdateCollections(CollectionUpdateResource collectionResourc
return Accepted(update); return Accepted(update);
} }
private IEnumerable<CollectionResource> MapToResource(List<MovieCollection> collections, List<MovieMetadata> collectionMovies)
{
// Avoid calling for naming spec on every movie in filenamebuilder
var namingConfig = _namingService.GetConfig();
foreach (var collection in collections)
{
var resource = collection.ToResource();
foreach (var movie in collectionMovies.Where(m => m.CollectionTmdbId == collection.TmdbId))
{
var movieResource = movie.ToResource();
movieResource.Folder = _fileNameBuilder.GetMovieFolder(new Movie { MovieMetadata = movie }, namingConfig);
resource.Movies.Add(movieResource);
}
yield return resource;
}
}
private CollectionResource MapToResource(MovieCollection collection) private CollectionResource MapToResource(MovieCollection collection)
{ {
var resource = collection.ToResource(); var resource = collection.ToResource();

View File

@ -24,6 +24,7 @@ public class ImportListMoviesController : Controller
private readonly IImportListMovieService _listMovieService; private readonly IImportListMovieService _listMovieService;
private readonly IImportListFactory _importListFactory; private readonly IImportListFactory _importListFactory;
private readonly IImportExclusionsService _importExclusionService; private readonly IImportExclusionsService _importExclusionService;
private readonly INamingConfigService _namingService;
private readonly IConfigService _configService; private readonly IConfigService _configService;
public ImportListMoviesController(IMovieService movieService, public ImportListMoviesController(IMovieService movieService,
@ -32,6 +33,7 @@ public ImportListMoviesController(IMovieService movieService,
IImportListMovieService listMovieService, IImportListMovieService listMovieService,
IImportListFactory importListFactory, IImportListFactory importListFactory,
IImportExclusionsService importExclusionsService, IImportExclusionsService importExclusionsService,
INamingConfigService namingService,
IConfigService configService) IConfigService configService)
{ {
_movieService = movieService; _movieService = movieService;
@ -40,6 +42,7 @@ public ImportListMoviesController(IMovieService movieService,
_listMovieService = listMovieService; _listMovieService = listMovieService;
_importListFactory = importListFactory; _importListFactory = importListFactory;
_importExclusionService = importExclusionsService; _importExclusionService = importExclusionsService;
_namingService = namingService;
_configService = configService; _configService = configService;
} }
@ -91,6 +94,9 @@ public object GetDiscoverMovies(bool includeRecommendations = false)
private IEnumerable<ImportListMoviesResource> MapToResource(IEnumerable<Movie> movies, Language language) private IEnumerable<ImportListMoviesResource> MapToResource(IEnumerable<Movie> movies, Language language)
{ {
//Avoid calling for naming spec on every movie in filenamebuilder
var namingConfig = _namingService.GetConfig();
foreach (var currentMovie in movies) foreach (var currentMovie in movies)
{ {
var resource = DiscoverMoviesResourceMapper.ToResource(currentMovie); var resource = DiscoverMoviesResourceMapper.ToResource(currentMovie);
@ -104,7 +110,7 @@ private IEnumerable<ImportListMoviesResource> MapToResource(IEnumerable<Movie> m
resource.Title = translation?.Title ?? resource.Title; resource.Title = translation?.Title ?? resource.Title;
resource.Overview = translation?.Overview ?? resource.Overview; resource.Overview = translation?.Overview ?? resource.Overview;
resource.Folder = _fileNameBuilder.GetMovieFolder(currentMovie); resource.Folder = _fileNameBuilder.GetMovieFolder(currentMovie, namingConfig);
yield return resource; yield return resource;
} }
@ -112,6 +118,9 @@ private IEnumerable<ImportListMoviesResource> MapToResource(IEnumerable<Movie> m
private IEnumerable<ImportListMoviesResource> MapToResource(IEnumerable<ImportListMovie> movies, Language language) private IEnumerable<ImportListMoviesResource> MapToResource(IEnumerable<ImportListMovie> movies, Language language)
{ {
// Avoid calling for naming spec on every movie in filenamebuilder
var namingConfig = _namingService.GetConfig();
foreach (var currentMovie in movies) foreach (var currentMovie in movies)
{ {
var resource = DiscoverMoviesResourceMapper.ToResource(currentMovie); var resource = DiscoverMoviesResourceMapper.ToResource(currentMovie);
@ -127,11 +136,8 @@ private IEnumerable<ImportListMoviesResource> MapToResource(IEnumerable<ImportLi
resource.Overview = translation?.Overview ?? resource.Overview; resource.Overview = translation?.Overview ?? resource.Overview;
resource.Folder = _fileNameBuilder.GetMovieFolder(new Movie resource.Folder = _fileNameBuilder.GetMovieFolder(new Movie
{ {
Title = currentMovie.Title, MovieMetadata = currentMovie.MovieMetadata
Year = currentMovie.Year, }, namingConfig);
ImdbId = currentMovie.ImdbId,
TmdbId = currentMovie.TmdbId
});
yield return resource; yield return resource;
} }