diff --git a/src/NzbDrone.Core/MediaFiles/MediaFileRepository.cs b/src/NzbDrone.Core/MediaFiles/MediaFileRepository.cs index aba43c8fa..b6e06d32c 100644 --- a/src/NzbDrone.Core/MediaFiles/MediaFileRepository.cs +++ b/src/NzbDrone.Core/MediaFiles/MediaFileRepository.cs @@ -8,6 +8,7 @@ namespace NzbDrone.Core.MediaFiles public interface IMediaFileRepository : IBasicRepository { List GetFilesBySeries(int seriesId); + List GetFilesBySeriesIds(List seriesIds); List GetFilesBySeason(int seriesId, int seasonNumber); List GetFilesWithoutMediaInfo(); List GetFilesWithRelativePath(int seriesId, string relativePath); @@ -26,6 +27,11 @@ namespace NzbDrone.Core.MediaFiles return Query(c => c.SeriesId == seriesId).ToList(); } + public List GetFilesBySeriesIds(List seriesIds) + { + return Query(c => seriesIds.Contains(c.SeriesId)).ToList(); + } + public List GetFilesBySeason(int seriesId, int seasonNumber) { return Query(c => c.SeriesId == seriesId && c.SeasonNumber == seasonNumber).ToList(); diff --git a/src/NzbDrone.Core/MediaFiles/MediaFileService.cs b/src/NzbDrone.Core/MediaFiles/MediaFileService.cs index 6e2c78d46..a8910638d 100644 --- a/src/NzbDrone.Core/MediaFiles/MediaFileService.cs +++ b/src/NzbDrone.Core/MediaFiles/MediaFileService.cs @@ -17,6 +17,7 @@ namespace NzbDrone.Core.MediaFiles void Update(List episodeFiles); void Delete(EpisodeFile episodeFile, DeleteMediaFileReason reason); List GetFilesBySeries(int seriesId); + List GetFilesBySeriesIds(List seriesIds); List GetFilesBySeason(int seriesId, int seasonNumber); List GetFiles(IEnumerable ids); List GetFilesWithoutMediaInfo(); @@ -71,6 +72,11 @@ namespace NzbDrone.Core.MediaFiles return _mediaFileRepository.GetFilesBySeries(seriesId); } + public List GetFilesBySeriesIds(List seriesIds) + { + return _mediaFileRepository.GetFilesBySeriesIds(seriesIds); + } + public List GetFilesBySeason(int seriesId, int seasonNumber) { return _mediaFileRepository.GetFilesBySeason(seriesId, seasonNumber); diff --git a/src/NzbDrone.Core/MediaFiles/RenameEpisodeFileService.cs b/src/NzbDrone.Core/MediaFiles/RenameEpisodeFileService.cs index 8993ba661..9502bb1a4 100644 --- a/src/NzbDrone.Core/MediaFiles/RenameEpisodeFileService.cs +++ b/src/NzbDrone.Core/MediaFiles/RenameEpisodeFileService.cs @@ -19,6 +19,7 @@ namespace NzbDrone.Core.MediaFiles { List GetRenamePreviews(int seriesId); List GetRenamePreviews(int seriesId, int seasonNumber); + List GetRenamePreviews(List seriesIds); } public class RenameEpisodeFileService : IRenameEpisodeFileService, @@ -75,6 +76,25 @@ namespace NzbDrone.Core.MediaFiles .OrderByDescending(e => e.EpisodeNumbers.First()).ToList(); } + public List GetRenamePreviews(List seriesIds) + { + var seriesList = _seriesService.GetSeries(seriesIds); + var episodesList = _episodeService.GetEpisodesBySeries(seriesIds).ToLookup(e => e.SeriesId); + var filesList = _mediaFileService.GetFilesBySeriesIds(seriesIds).ToLookup(f => f.SeriesId); + + return seriesList.SelectMany(series => + { + var episodes = episodesList[series.Id].ToList(); + var files = filesList[series.Id].ToList(); + + return GetPreviews(series, episodes, files); + }) + .OrderByDescending(e => e.SeriesId) + .ThenByDescending(e => e.SeasonNumber) + .ThenByDescending(e => e.EpisodeNumbers.First()) + .ToList(); + } + private IEnumerable GetPreviews(Series series, List episodes, List files) { foreach (var f in files) diff --git a/src/NzbDrone.Core/Tv/EpisodeService.cs b/src/NzbDrone.Core/Tv/EpisodeService.cs index 20dad0582..0abca4871 100644 --- a/src/NzbDrone.Core/Tv/EpisodeService.cs +++ b/src/NzbDrone.Core/Tv/EpisodeService.cs @@ -23,6 +23,7 @@ namespace NzbDrone.Core.Tv List FindEpisodesBySceneNumbering(int seriesId, int sceneAbsoluteEpisodeNumber); Episode FindEpisode(int seriesId, string date, int? part); List GetEpisodeBySeries(int seriesId); + List GetEpisodesBySeries(List seriesIds); List GetEpisodesBySeason(int seriesId, int seasonNumber); List GetEpisodesBySceneSeason(int seriesId, int sceneSeasonNumber); List EpisodesWithFiles(int seriesId); @@ -99,6 +100,11 @@ namespace NzbDrone.Core.Tv return _episodeRepository.GetEpisodes(seriesId).ToList(); } + public List GetEpisodesBySeries(List seriesIds) + { + return _episodeRepository.GetEpisodesBySeriesIds(seriesIds).ToList(); + } + public List GetEpisodesBySeason(int seriesId, int seasonNumber) { return _episodeRepository.GetEpisodes(seriesId, seasonNumber); diff --git a/src/Sonarr.Api.V3/Episodes/RenameEpisodeController.cs b/src/Sonarr.Api.V3/Episodes/RenameEpisodeController.cs index b729be666..fb9263c36 100644 --- a/src/Sonarr.Api.V3/Episodes/RenameEpisodeController.cs +++ b/src/Sonarr.Api.V3/Episodes/RenameEpisodeController.cs @@ -1,7 +1,9 @@ using System.Collections.Generic; +using System.Linq; using Microsoft.AspNetCore.Mvc; using NzbDrone.Core.MediaFiles; using Sonarr.Http; +using Sonarr.Http.REST; namespace Sonarr.Api.V3.Episodes { @@ -26,5 +28,22 @@ namespace Sonarr.Api.V3.Episodes return _renameEpisodeFileService.GetRenamePreviews(seriesId).ToResource(); } + + [HttpGet("bulk")] + [Produces("application/json")] + public List GetEpisodes([FromQuery] List seriesIds) + { + if (seriesIds is { Count: 0 }) + { + throw new BadRequestException("seriesIds must be provided"); + } + + if (seriesIds.Any(seriesId => seriesId <= 0)) + { + throw new BadRequestException("seriesIds must be positive integers"); + } + + return _renameEpisodeFileService.GetRenamePreviews(seriesIds).ToResource(); + } } }