diff --git a/src/NzbDrone.Core/Movies/MovieMetadataRepository.cs b/src/NzbDrone.Core/Movies/MovieMetadataRepository.cs index 180db057e..bce138878 100644 --- a/src/NzbDrone.Core/Movies/MovieMetadataRepository.cs +++ b/src/NzbDrone.Core/Movies/MovieMetadataRepository.cs @@ -2,7 +2,9 @@ using System.Collections.Generic; using System.Linq; using NLog; using NzbDrone.Core.Datastore; +using NzbDrone.Core.Languages; using NzbDrone.Core.Messaging.Events; +using NzbDrone.Core.Movies.Translations; namespace NzbDrone.Core.Movies { @@ -10,6 +12,7 @@ namespace NzbDrone.Core.Movies { MovieMetadata FindByTmdbId(int tmdbId); List FindById(List tmdbIds); + List GetMoviesWithCollections(); List GetMoviesByCollectionTmdbId(int collectionId); bool UpsertMany(List data); } @@ -34,6 +37,43 @@ namespace NzbDrone.Core.Movies return Query(x => Enumerable.Contains(tmdbIds, x.TmdbId)); } + public List GetMoviesWithCollections() + { + var movieDictionary = new Dictionary(); + + var builder = new SqlBuilder(_database.DatabaseType) + .LeftJoin((mm, t) => mm.Id == t.MovieMetadataId) + .Where(x => x.CollectionTmdbId > 0); + + _ = _database.QueryJoined( + 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 GetMoviesByCollectionTmdbId(int collectionId) { return Query(x => x.CollectionTmdbId == collectionId); diff --git a/src/NzbDrone.Core/Movies/MovieMetadataService.cs b/src/NzbDrone.Core/Movies/MovieMetadataService.cs index 30a0a9d23..b0aab7ff1 100644 --- a/src/NzbDrone.Core/Movies/MovieMetadataService.cs +++ b/src/NzbDrone.Core/Movies/MovieMetadataService.cs @@ -6,6 +6,7 @@ namespace NzbDrone.Core.Movies { MovieMetadata Get(int id); MovieMetadata FindByTmdbId(int tmdbid); + List GetMoviesWithCollections(); List GetMoviesByCollectionTmdbId(int collectionId); bool Upsert(MovieMetadata movie); bool UpsertMany(List movies); @@ -25,6 +26,11 @@ namespace NzbDrone.Core.Movies return _movieMetadataRepository.FindByTmdbId(tmdbid); } + public List GetMoviesWithCollections() + { + return _movieMetadataRepository.GetMoviesWithCollections(); + } + public List GetMoviesByCollectionTmdbId(int collectionId) { return _movieMetadataRepository.GetMoviesByCollectionTmdbId(collectionId); diff --git a/src/Radarr.Api.V3/Collections/CollectionController.cs b/src/Radarr.Api.V3/Collections/CollectionController.cs index 41f9823db..9732d8d17 100644 --- a/src/Radarr.Api.V3/Collections/CollectionController.cs +++ b/src/Radarr.Api.V3/Collections/CollectionController.cs @@ -24,18 +24,21 @@ namespace Radarr.Api.V3.Collections private readonly IMovieService _movieService; private readonly IMovieMetadataService _movieMetadataService; private readonly IBuildFileNames _fileNameBuilder; + private readonly INamingConfigService _namingService; public CollectionController(IBroadcastSignalRMessage signalRBroadcaster, IMovieCollectionService collectionService, IMovieService movieService, IMovieMetadataService movieMetadataService, - IBuildFileNames fileNameBuilder) + IBuildFileNames fileNameBuilder, + INamingConfigService namingService) : base(signalRBroadcaster) { _collectionService = collectionService; _movieService = movieService; _movieMetadataService = movieMetadataService; _fileNameBuilder = fileNameBuilder; + _namingService = namingService; } protected override CollectionResource GetResourceById(int id) @@ -46,7 +49,9 @@ namespace Radarr.Api.V3.Collections [HttpGet] public List GetCollections() { - return _collectionService.GetAllCollections().Select(c => MapToResource(c)).ToList(); + var collectionMovies = _movieMetadataService.GetMoviesWithCollections(); + + return MapToResource(_collectionService.GetAllCollections(), collectionMovies).ToList(); } [RestPutById] @@ -92,6 +97,27 @@ namespace Radarr.Api.V3.Collections return Accepted(update); } + private IEnumerable MapToResource(List collections, List 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) { var resource = collection.ToResource(); diff --git a/src/Radarr.Api.V3/ImportLists/ImportListMoviesController.cs b/src/Radarr.Api.V3/ImportLists/ImportListMoviesController.cs index f5a646f3c..1ddeb6c38 100644 --- a/src/Radarr.Api.V3/ImportLists/ImportListMoviesController.cs +++ b/src/Radarr.Api.V3/ImportLists/ImportListMoviesController.cs @@ -24,6 +24,7 @@ namespace Radarr.Api.V3.ImportLists private readonly IImportListMovieService _listMovieService; private readonly IImportListFactory _importListFactory; private readonly IImportExclusionsService _importExclusionService; + private readonly INamingConfigService _namingService; private readonly IConfigService _configService; public ImportListMoviesController(IMovieService movieService, @@ -32,6 +33,7 @@ namespace Radarr.Api.V3.ImportLists IImportListMovieService listMovieService, IImportListFactory importListFactory, IImportExclusionsService importExclusionsService, + INamingConfigService namingService, IConfigService configService) { _movieService = movieService; @@ -40,6 +42,7 @@ namespace Radarr.Api.V3.ImportLists _listMovieService = listMovieService; _importListFactory = importListFactory; _importExclusionService = importExclusionsService; + _namingService = namingService; _configService = configService; } @@ -91,6 +94,9 @@ namespace Radarr.Api.V3.ImportLists private IEnumerable MapToResource(IEnumerable movies, Language language) { + //Avoid calling for naming spec on every movie in filenamebuilder + var namingConfig = _namingService.GetConfig(); + foreach (var currentMovie in movies) { var resource = DiscoverMoviesResourceMapper.ToResource(currentMovie); @@ -104,7 +110,7 @@ namespace Radarr.Api.V3.ImportLists resource.Title = translation?.Title ?? resource.Title; resource.Overview = translation?.Overview ?? resource.Overview; - resource.Folder = _fileNameBuilder.GetMovieFolder(currentMovie); + resource.Folder = _fileNameBuilder.GetMovieFolder(currentMovie, namingConfig); yield return resource; } @@ -112,6 +118,9 @@ namespace Radarr.Api.V3.ImportLists private IEnumerable MapToResource(IEnumerable movies, Language language) { + // Avoid calling for naming spec on every movie in filenamebuilder + var namingConfig = _namingService.GetConfig(); + foreach (var currentMovie in movies) { var resource = DiscoverMoviesResourceMapper.ToResource(currentMovie); @@ -127,11 +136,8 @@ namespace Radarr.Api.V3.ImportLists resource.Overview = translation?.Overview ?? resource.Overview; resource.Folder = _fileNameBuilder.GetMovieFolder(new Movie { - Title = currentMovie.Title, - Year = currentMovie.Year, - ImdbId = currentMovie.ImdbId, - TmdbId = currentMovie.TmdbId - }); + MovieMetadata = currentMovie.MovieMetadata + }, namingConfig); yield return resource; }