From 7adb358d1ce3a2e7c7ee6e8e990746f1d6f404e4 Mon Sep 17 00:00:00 2001 From: Qstick Date: Thu, 4 Jun 2020 23:35:02 -0400 Subject: [PATCH] Fixed: Speed up mass deletes from Movie Editor (#4463) --- src/NzbDrone.Api/Movies/MovieModule.cs | 15 +++--- .../BlacklistRepositoryFixture.cs | 37 +++++++++++++ .../DownloadHistoryRepositoryFixture.cs | 54 +++++++++++++++++++ .../PendingReleaseRepositoryFixture.cs | 3 +- .../Extras/SubtitleFileRepositoryFixture.cs | 3 +- .../HistoryTests/HistoryRepositoryFixture.cs | 37 +++++++++++++ .../MediaFiles/MediaFileRepositoryFixture.cs | 36 +++++++++++++ .../CreditTests/CreditRepositoryFixture.cs | 53 ++++++++++++++++++ .../Blacklisting/BlacklistRepository.cs | 12 +++-- .../Blacklisting/BlacklistService.cs | 8 ++- .../History/DownloadHistoryRepository.cs | 6 +-- .../History/DownloadHistoryService.cs | 7 +-- .../Pending/PendingReleaseRepository.cs | 6 +-- .../Download/Pending/PendingReleaseService.cs | 6 +-- .../Extras/Files/ExtraFileRepository.cs | 6 +-- .../Extras/Files/ExtraFileService.cs | 9 ++-- .../HealthCheck/Checks/RemovedMovieCheck.cs | 8 +-- .../HealthCheck/Checks/RootFolderCheck.cs | 2 +- .../History/HistoryRepository.cs | 6 +-- src/NzbDrone.Core/History/HistoryService.cs | 6 +-- .../MediaCover/MediaCoverService.cs | 13 +++-- .../MediaFiles/MediaFileDeletionService.cs | 42 ++++++++------- .../MediaFiles/MediaFileRepository.cs | 6 +++ .../MediaFiles/MediaFileService.cs | 7 ++- .../AlternativeTitleRepository.cs | 6 +++ .../AlternativeTitleService.cs | 7 ++- .../Movies/Credits/CreditRepository.cs | 8 ++- .../Movies/Credits/CreditService.cs | 8 +-- .../Movies/Events/MovieDeletedEvent.cs | 16 ------ .../Movies/Events/MoviesDeletedEvent.cs | 19 +++++++ src/NzbDrone.Core/Movies/MovieService.cs | 31 ++++++----- .../ImportExclusionsService.cs | 25 +++++---- src/Radarr.Api.V3/Movies/MovieEditorModule.cs | 5 +- src/Radarr.Api.V3/Movies/MovieModule.cs | 9 ++-- 34 files changed, 389 insertions(+), 133 deletions(-) create mode 100644 src/NzbDrone.Core.Test/Download/DownloadHistoryTests/DownloadHistoryRepositoryFixture.cs create mode 100644 src/NzbDrone.Core.Test/MovieTests/CreditTests/CreditRepositoryFixture.cs delete mode 100644 src/NzbDrone.Core/Movies/Events/MovieDeletedEvent.cs create mode 100644 src/NzbDrone.Core/Movies/Events/MoviesDeletedEvent.cs diff --git a/src/NzbDrone.Api/Movies/MovieModule.cs b/src/NzbDrone.Api/Movies/MovieModule.cs index 1c6eb599a..e30b16525 100644 --- a/src/NzbDrone.Api/Movies/MovieModule.cs +++ b/src/NzbDrone.Api/Movies/MovieModule.cs @@ -20,9 +20,9 @@ namespace NzbDrone.Api.Movies public class MovieModule : RadarrRestModuleWithSignalR, IHandle, IHandle, + IHandle, IHandle, IHandle, - IHandle, IHandle, IHandle { @@ -168,19 +168,22 @@ namespace NzbDrone.Api.Movies BroadcastResourceChange(ModelAction.Updated, message.MovieFile.MovieId); } - public void Handle(MovieUpdatedEvent message) + public void Handle(MoviesDeletedEvent message) { - BroadcastResourceChange(ModelAction.Updated, message.Movie.Id); + foreach (var movie in message.Movies) + { + BroadcastResourceChange(ModelAction.Deleted, movie.Id); + } } - public void Handle(MovieEditedEvent message) + public void Handle(MovieUpdatedEvent message) { BroadcastResourceChange(ModelAction.Updated, message.Movie.Id); } - public void Handle(MovieDeletedEvent message) + public void Handle(MovieEditedEvent message) { - BroadcastResourceChange(ModelAction.Deleted, message.Movie.ToResource()); + BroadcastResourceChange(ModelAction.Updated, message.Movie.Id); } public void Handle(MovieRenamedEvent message) diff --git a/src/NzbDrone.Core.Test/Blacklisting/BlacklistRepositoryFixture.cs b/src/NzbDrone.Core.Test/Blacklisting/BlacklistRepositoryFixture.cs index 8894c05df..9e09215be 100644 --- a/src/NzbDrone.Core.Test/Blacklisting/BlacklistRepositoryFixture.cs +++ b/src/NzbDrone.Core.Test/Blacklisting/BlacklistRepositoryFixture.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; using System.Linq; +using FizzWare.NBuilder; using FluentAssertions; using NUnit.Framework; using NzbDrone.Core.Blacklisting; using NzbDrone.Core.Languages; +using NzbDrone.Core.Movies; using NzbDrone.Core.Qualities; using NzbDrone.Core.Test.Framework; @@ -14,6 +16,8 @@ namespace NzbDrone.Core.Test.Blacklisting public class BlacklistRepositoryFixture : DbTest { private Blacklist _blacklist; + private Movie _movie1; + private Movie _movie2; [SetUp] public void Setup() @@ -26,6 +30,14 @@ namespace NzbDrone.Core.Test.Blacklisting SourceTitle = "movie.title.1998", Date = DateTime.UtcNow }; + + _movie1 = Builder.CreateNew() + .With(s => s.Id = 7) + .Build(); + + _movie2 = Builder.CreateNew() + .With(s => s.Id = 8) + .Build(); } [Test] @@ -50,5 +62,30 @@ namespace NzbDrone.Core.Test.Blacklisting Subject.BlacklistedByTitle(_blacklist.MovieId, _blacklist.SourceTitle.ToUpperInvariant()).Should().HaveCount(1); } + + [Test] + public void should_delete_blacklists_by_movieId() + { + var blacklistItems = Builder.CreateListOfSize(5) + .TheFirst(1) + .With(c => c.MovieId = _movie2.Id) + .TheRest() + .With(c => c.MovieId = _movie1.Id) + .All() + .With(c => c.Quality = new QualityModel()) + .With(c => c.Languages = new List()) + .With(c => c.Id = 0) + .BuildListOfNew(); + + Db.InsertMany(blacklistItems); + + Subject.DeleteForMovies(new List { _movie1.Id }); + + var removedMovieBlacklists = Subject.BlacklistedByMovies(new List { _movie1.Id }); + var nonRemovedMovieBlacklists = Subject.BlacklistedByMovies(new List { _movie2.Id }); + + removedMovieBlacklists.Should().HaveCount(0); + nonRemovedMovieBlacklists.Should().HaveCount(1); + } } } diff --git a/src/NzbDrone.Core.Test/Download/DownloadHistoryTests/DownloadHistoryRepositoryFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadHistoryTests/DownloadHistoryRepositoryFixture.cs new file mode 100644 index 000000000..223c6bf49 --- /dev/null +++ b/src/NzbDrone.Core.Test/Download/DownloadHistoryTests/DownloadHistoryRepositoryFixture.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using FizzWare.NBuilder; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.Download.History; +using NzbDrone.Core.Movies; +using NzbDrone.Core.Test.Framework; + +namespace NzbDrone.Core.Test.Download.DownloadHistoryTests +{ + [TestFixture] + public class DownloadHistoryRepositoryFixture : DbTest + { + private Movie _movie1; + private Movie _movie2; + + [SetUp] + public void Setup() + { + _movie1 = Builder.CreateNew() + .With(s => s.Id = 7) + .Build(); + + _movie2 = Builder.CreateNew() + .With(s => s.Id = 8) + .Build(); + } + + [Test] + public void should_delete_history_items_by_movieId() + { + var items = Builder.CreateListOfSize(5) + .TheFirst(1) + .With(c => c.Id = 0) + .With(c => c.MovieId = _movie2.Id) + .TheRest() + .With(c => c.Id = 0) + .With(c => c.MovieId = _movie1.Id) + .BuildListOfNew(); + + Db.InsertMany(items); + + Subject.DeleteByMovieIds(new List { _movie1.Id }); + + var removedItems = Subject.All().Where(h => h.MovieId == _movie1.Id); + var nonRemovedItems = Subject.All().Where(h => h.MovieId == _movie2.Id); + + removedItems.Should().HaveCount(0); + nonRemovedItems.Should().HaveCount(1); + } + } +} diff --git a/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseRepositoryFixture.cs b/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseRepositoryFixture.cs index 22ffd2763..c306ba828 100644 --- a/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseRepositoryFixture.cs +++ b/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseRepositoryFixture.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using FizzWare.NBuilder; using FluentAssertions; using NUnit.Framework; @@ -38,7 +39,7 @@ namespace NzbDrone.Core.Test.MediaFiles Db.InsertMany(files); - Subject.DeleteByMovieId(_movie1.Id); + Subject.DeleteByMovieIds(new List { _movie1.Id }); var remainingFiles = Subject.AllByMovieId(_movie1.Id); diff --git a/src/NzbDrone.Core.Test/Extras/SubtitleFileRepositoryFixture.cs b/src/NzbDrone.Core.Test/Extras/SubtitleFileRepositoryFixture.cs index bae8f1e95..b6509fa56 100644 --- a/src/NzbDrone.Core.Test/Extras/SubtitleFileRepositoryFixture.cs +++ b/src/NzbDrone.Core.Test/Extras/SubtitleFileRepositoryFixture.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using FizzWare.NBuilder; using FluentAssertions; using NUnit.Framework; @@ -47,7 +48,7 @@ namespace NzbDrone.Core.Test.MediaFiles Db.InsertMany(files); - Subject.DeleteForMovie(_movie.Id); + Subject.DeleteForMovies(new List { _movie.Id }); var remainingFiles = Subject.GetFilesByMovie(_movie.Id); diff --git a/src/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs b/src/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs index 4b2cd9517..563e0f10a 100644 --- a/src/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs +++ b/src/NzbDrone.Core.Test/HistoryTests/HistoryRepositoryFixture.cs @@ -6,6 +6,7 @@ using FluentAssertions; using NUnit.Framework; using NzbDrone.Core.History; using NzbDrone.Core.Languages; +using NzbDrone.Core.Movies; using NzbDrone.Core.Qualities; using NzbDrone.Core.Test.Framework; @@ -14,9 +15,19 @@ namespace NzbDrone.Core.Test.HistoryTests [TestFixture] public class HistoryRepositoryFixture : DbTest { + private Movie _movie1; + private Movie _movie2; + [SetUp] public void Setup() { + _movie1 = Builder.CreateNew() + .With(s => s.Id = 7) + .Build(); + + _movie2 = Builder.CreateNew() + .With(s => s.Id = 8) + .Build(); } [Test] @@ -112,5 +123,31 @@ namespace NzbDrone.Core.Test.HistoryTests movieHistory.Should().HaveCount(2); movieHistory.First().EventType.Should().Be(MovieHistoryEventType.Grabbed); } + + [Test] + public void should_delete_history_items_by_movieId() + { + var items = Builder.CreateListOfSize(5) + .TheFirst(1) + .With(c => c.MovieId = _movie2.Id) + .TheRest() + .With(c => c.MovieId = _movie1.Id) + .All() + .With(c => c.Id = 0) + .With(c => c.Quality = new QualityModel(Quality.Bluray1080p)) + .With(c => c.Languages = new List { Language.English }) + .With(c => c.EventType = MovieHistoryEventType.Grabbed) + .BuildListOfNew(); + + Db.InsertMany(items); + + Subject.DeleteForMovies(new List { _movie1.Id }); + + var removedItems = Subject.GetByMovieId(_movie1.Id, null); + var nonRemovedItems = Subject.GetByMovieId(_movie2.Id, null); + + removedItems.Should().HaveCount(0); + nonRemovedItems.Should().HaveCount(1); + } } } diff --git a/src/NzbDrone.Core.Test/MediaFiles/MediaFileRepositoryFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/MediaFileRepositoryFixture.cs index db8430559..259f190fe 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/MediaFileRepositoryFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/MediaFileRepositoryFixture.cs @@ -4,6 +4,7 @@ using FluentAssertions; using NUnit.Framework; using NzbDrone.Core.Languages; using NzbDrone.Core.MediaFiles; +using NzbDrone.Core.Movies; using NzbDrone.Core.Qualities; using NzbDrone.Core.Test.Framework; @@ -12,9 +13,19 @@ namespace NzbDrone.Core.Test.MediaFiles [TestFixture] public class MediaFileRepositoryFixture : DbTest { + private Movie _movie1; + private Movie _movie2; + [SetUp] public void Setup() { + _movie1 = Builder.CreateNew() + .With(s => s.Id = 7) + .Build(); + + _movie2 = Builder.CreateNew() + .With(s => s.Id = 8) + .Build(); } [Test] @@ -36,5 +47,30 @@ namespace NzbDrone.Core.Test.MediaFiles movieFiles.Should().HaveCount(4); movieFiles.Should().OnlyContain(c => c.MovieId == 12); } + + [Test] + public void should_delete_files_by_movieId() + { + var items = Builder.CreateListOfSize(5) + .TheFirst(1) + .With(c => c.MovieId = _movie2.Id) + .TheRest() + .With(c => c.MovieId = _movie1.Id) + .All() + .With(c => c.Id = 0) + .With(c => c.Quality = new QualityModel(Quality.Bluray1080p)) + .With(c => c.Languages = new List { Language.English }) + .BuildListOfNew(); + + Db.InsertMany(items); + + Subject.DeleteForMovies(new List { _movie1.Id }); + + var removedItems = Subject.GetFilesByMovie(_movie1.Id); + var nonRemovedItems = Subject.GetFilesByMovie(_movie2.Id); + + removedItems.Should().HaveCount(0); + nonRemovedItems.Should().HaveCount(1); + } } } diff --git a/src/NzbDrone.Core.Test/MovieTests/CreditTests/CreditRepositoryFixture.cs b/src/NzbDrone.Core.Test/MovieTests/CreditTests/CreditRepositoryFixture.cs new file mode 100644 index 000000000..2d94afaac --- /dev/null +++ b/src/NzbDrone.Core.Test/MovieTests/CreditTests/CreditRepositoryFixture.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using FizzWare.NBuilder; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.Movies; +using NzbDrone.Core.Movies.Credits; +using NzbDrone.Core.Test.Framework; + +namespace NzbDrone.Core.Test.MovieTests.CreditTests +{ + [TestFixture] + public class CreditRepositoryFixture : DbTest + { + private Movie _movie1; + private Movie _movie2; + + [SetUp] + public void Setup() + { + _movie1 = Builder.CreateNew() + .With(s => s.Id = 7) + .Build(); + + _movie2 = Builder.CreateNew() + .With(s => s.Id = 8) + .Build(); + } + + [Test] + public void should_delete_credits_by_movieId() + { + var credits = Builder.CreateListOfSize(5) + .TheFirst(1) + .With(c => c.Id = 0) + .With(c => c.MovieId = _movie2.Id) + .TheRest() + .With(c => c.Id = 0) + .With(c => c.MovieId = _movie1.Id) + .BuildListOfNew(); + + Db.InsertMany(credits); + + Subject.DeleteForMovies(new List { _movie1.Id }); + + var removedMovieCredits = Subject.FindByMovieId(_movie1.Id); + var nonRemovedMovieCredits = Subject.FindByMovieId(_movie2.Id); + + removedMovieCredits.Should().HaveCount(0); + nonRemovedMovieCredits.Should().HaveCount(1); + } + } +} diff --git a/src/NzbDrone.Core/Blacklisting/BlacklistRepository.cs b/src/NzbDrone.Core/Blacklisting/BlacklistRepository.cs index eb479eb76..6dc0f6809 100644 --- a/src/NzbDrone.Core/Blacklisting/BlacklistRepository.cs +++ b/src/NzbDrone.Core/Blacklisting/BlacklistRepository.cs @@ -9,7 +9,8 @@ namespace NzbDrone.Core.Blacklisting { List BlacklistedByTitle(int movieId, string sourceTitle); List BlacklistedByTorrentInfoHash(int movieId, string torrentInfoHash); - List BlacklistedByMovie(int movieId); + List BlacklistedByMovies(List movieIds); + void DeleteForMovies(List movieIds); } public class BlacklistRepository : BasicRepository, IBlacklistRepository @@ -29,9 +30,14 @@ namespace NzbDrone.Core.Blacklisting return Query(x => x.MovieId == movieId && x.TorrentInfoHash.Contains(torrentInfoHash)); } - public List BlacklistedByMovie(int movieId) + public List BlacklistedByMovies(List movieIds) { - return Query(x => x.MovieId == movieId); + return Query(x => movieIds.Contains(x.MovieId)); + } + + public void DeleteForMovies(List movieIds) + { + Delete(x => movieIds.Contains(x.MovieId)); } protected override SqlBuilder PagedBuilder() => new SqlBuilder().Join((b, m) => b.MovieId == m.Id); diff --git a/src/NzbDrone.Core/Blacklisting/BlacklistService.cs b/src/NzbDrone.Core/Blacklisting/BlacklistService.cs index 97e917d65..5209d370b 100644 --- a/src/NzbDrone.Core/Blacklisting/BlacklistService.cs +++ b/src/NzbDrone.Core/Blacklisting/BlacklistService.cs @@ -23,7 +23,7 @@ namespace NzbDrone.Core.Blacklisting IExecute, IHandle, - IHandleAsync + IHandleAsync { private readonly IBlacklistRepository _blacklistRepository; @@ -160,11 +160,9 @@ namespace NzbDrone.Core.Blacklisting _blacklistRepository.Insert(blacklist); } - public void HandleAsync(MovieDeletedEvent message) + public void HandleAsync(MoviesDeletedEvent message) { - var blacklisted = _blacklistRepository.BlacklistedByMovie(message.Movie.Id); - - _blacklistRepository.DeleteMany(blacklisted); + _blacklistRepository.DeleteForMovies(message.Movies.Select(m => m.Id).ToList()); } } } diff --git a/src/NzbDrone.Core/Download/History/DownloadHistoryRepository.cs b/src/NzbDrone.Core/Download/History/DownloadHistoryRepository.cs index e895bf315..bb0f1bfd6 100644 --- a/src/NzbDrone.Core/Download/History/DownloadHistoryRepository.cs +++ b/src/NzbDrone.Core/Download/History/DownloadHistoryRepository.cs @@ -8,7 +8,7 @@ namespace NzbDrone.Core.Download.History public interface IDownloadHistoryRepository : IBasicRepository { List FindByDownloadId(string downloadId); - void DeleteByMovieId(int movieId); + void DeleteByMovieIds(List movieIds); } public class DownloadHistoryRepository : BasicRepository, IDownloadHistoryRepository @@ -23,9 +23,9 @@ namespace NzbDrone.Core.Download.History return Query(x => x.DownloadId == downloadId).OrderByDescending(h => h.Date).ToList(); } - public void DeleteByMovieId(int movieId) + public void DeleteByMovieIds(List movieIds) { - Delete(r => r.MovieId == movieId); + Delete(r => movieIds.Contains(r.MovieId)); } } } diff --git a/src/NzbDrone.Core/Download/History/DownloadHistoryService.cs b/src/NzbDrone.Core/Download/History/DownloadHistoryService.cs index c657469d8..13763cbff 100644 --- a/src/NzbDrone.Core/Download/History/DownloadHistoryService.cs +++ b/src/NzbDrone.Core/Download/History/DownloadHistoryService.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using NzbDrone.Common.Extensions; using NzbDrone.Core.History; using NzbDrone.Core.MediaFiles.Events; @@ -19,7 +20,7 @@ namespace NzbDrone.Core.Download.History IHandle, IHandle, IHandle, - IHandle + IHandle { private readonly IDownloadHistoryRepository _repository; private readonly IHistoryService _historyService; @@ -213,9 +214,9 @@ namespace NzbDrone.Core.Download.History _repository.Insert(history); } - public void Handle(MovieDeletedEvent message) + public void Handle(MoviesDeletedEvent message) { - _repository.DeleteByMovieId(message.Movie.Id); + _repository.DeleteByMovieIds(message.Movies.Select(m => m.Id).ToList()); } } } diff --git a/src/NzbDrone.Core/Download/Pending/PendingReleaseRepository.cs b/src/NzbDrone.Core/Download/Pending/PendingReleaseRepository.cs index 681529bab..d38a382c1 100644 --- a/src/NzbDrone.Core/Download/Pending/PendingReleaseRepository.cs +++ b/src/NzbDrone.Core/Download/Pending/PendingReleaseRepository.cs @@ -6,7 +6,7 @@ namespace NzbDrone.Core.Download.Pending { public interface IPendingReleaseRepository : IBasicRepository { - void DeleteByMovieId(int movieId); + void DeleteByMovieIds(List movieIds); List AllByMovieId(int movieId); List WithoutFallback(); } @@ -18,9 +18,9 @@ namespace NzbDrone.Core.Download.Pending { } - public void DeleteByMovieId(int movieId) + public void DeleteByMovieIds(List movieIds) { - Delete(x => x.MovieId == movieId); + Delete(x => movieIds.Contains(x.MovieId)); } public List AllByMovieId(int movieId) diff --git a/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs b/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs index 99223dc2a..cbecfdd7e 100644 --- a/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs +++ b/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs @@ -34,7 +34,7 @@ namespace NzbDrone.Core.Download.Pending public class PendingReleaseService : IPendingReleaseService, IHandle, - IHandle, + IHandle, IHandle { private readonly IIndexerStatusService _indexerStatusService; @@ -408,9 +408,9 @@ namespace NzbDrone.Core.Download.Pending return 1; } - public void Handle(MovieDeletedEvent message) + public void Handle(MoviesDeletedEvent message) { - _repository.DeleteByMovieId(message.Movie.Id); + _repository.DeleteByMovieIds(message.Movies.Select(m => m.Id).ToList()); } public void Handle(MovieGrabbedEvent message) diff --git a/src/NzbDrone.Core/Extras/Files/ExtraFileRepository.cs b/src/NzbDrone.Core/Extras/Files/ExtraFileRepository.cs index 667b294fb..cf787b552 100644 --- a/src/NzbDrone.Core/Extras/Files/ExtraFileRepository.cs +++ b/src/NzbDrone.Core/Extras/Files/ExtraFileRepository.cs @@ -8,7 +8,7 @@ namespace NzbDrone.Core.Extras.Files public interface IExtraFileRepository : IBasicRepository where TExtraFile : ExtraFile, new() { - void DeleteForMovie(int movieId); + void DeleteForMovies(List movieIds); void DeleteForMovieFile(int movieFileId); List GetFilesByMovie(int movieId); List GetFilesByMovieFile(int movieFileId); @@ -23,9 +23,9 @@ namespace NzbDrone.Core.Extras.Files { } - public void DeleteForMovie(int movieId) + public void DeleteForMovies(List movieIds) { - Delete(x => x.MovieId == movieId); + Delete(x => movieIds.Contains(x.MovieId)); } public void DeleteForMovieFile(int movieFileId) diff --git a/src/NzbDrone.Core/Extras/Files/ExtraFileService.cs b/src/NzbDrone.Core/Extras/Files/ExtraFileService.cs index bf934a368..da7c223c9 100644 --- a/src/NzbDrone.Core/Extras/Files/ExtraFileService.cs +++ b/src/NzbDrone.Core/Extras/Files/ExtraFileService.cs @@ -25,8 +25,8 @@ namespace NzbDrone.Core.Extras.Files } public abstract class ExtraFileService : IExtraFileService, - IHandleAsync, - IHandleAsync + IHandleAsync, + IHandleAsync where TExtraFile : ExtraFile, new() { private readonly IExtraFileRepository _repository; @@ -94,10 +94,9 @@ namespace NzbDrone.Core.Extras.Files _repository.DeleteMany(ids); } - public void HandleAsync(MovieDeletedEvent message) + public void HandleAsync(MoviesDeletedEvent message) { - _logger.Debug("Deleting Extra from database for movie: {0}", message.Movie); - _repository.DeleteForMovie(message.Movie.Id); + _repository.DeleteForMovies(message.Movies.Select(m => m.Id).ToList()); } public void HandleAsync(MovieFileDeletedEvent message) diff --git a/src/NzbDrone.Core/HealthCheck/Checks/RemovedMovieCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/RemovedMovieCheck.cs index f4d8ab3e5..6f4745478 100644 --- a/src/NzbDrone.Core/HealthCheck/Checks/RemovedMovieCheck.cs +++ b/src/NzbDrone.Core/HealthCheck/Checks/RemovedMovieCheck.cs @@ -6,8 +6,8 @@ using NzbDrone.Core.Movies.Events; namespace NzbDrone.Core.HealthCheck.Checks { [CheckOn(typeof(MovieUpdatedEvent))] - [CheckOn(typeof(MovieDeletedEvent), CheckOnCondition.FailedOnly)] - public class RemovedSeriesCheck : HealthCheckBase, ICheckOnCondition, ICheckOnCondition + [CheckOn(typeof(MoviesDeletedEvent), CheckOnCondition.FailedOnly)] + public class RemovedSeriesCheck : HealthCheckBase, ICheckOnCondition, ICheckOnCondition { private readonly IMovieService _movieService; @@ -35,9 +35,9 @@ namespace NzbDrone.Core.HealthCheck.Checks return new HealthCheck(GetType(), HealthCheckResult.Error, string.Format("Movie {0} was removed from TMDb", movieText), "#movie-was-removed-from-tmdb"); } - public bool ShouldCheckOnEvent(MovieDeletedEvent message) + public bool ShouldCheckOnEvent(MoviesDeletedEvent message) { - return message.Movie.Status == MovieStatusType.Deleted; + return message.Movies.Any(m => m.Status == MovieStatusType.Deleted); } public bool ShouldCheckOnEvent(MovieUpdatedEvent message) diff --git a/src/NzbDrone.Core/HealthCheck/Checks/RootFolderCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/RootFolderCheck.cs index b70f9aa19..574a4ba86 100644 --- a/src/NzbDrone.Core/HealthCheck/Checks/RootFolderCheck.cs +++ b/src/NzbDrone.Core/HealthCheck/Checks/RootFolderCheck.cs @@ -7,7 +7,7 @@ using NzbDrone.Core.RootFolders; namespace NzbDrone.Core.HealthCheck.Checks { - [CheckOn(typeof(MovieDeletedEvent))] + [CheckOn(typeof(MoviesDeletedEvent))] [CheckOn(typeof(MovieMovedEvent))] [CheckOn(typeof(MoviesImportedEvent), CheckOnCondition.FailedOnly)] [CheckOn(typeof(MovieImportFailedEvent), CheckOnCondition.SuccessfulOnly)] diff --git a/src/NzbDrone.Core/History/HistoryRepository.cs b/src/NzbDrone.Core/History/HistoryRepository.cs index b1237e9df..bf7617260 100644 --- a/src/NzbDrone.Core/History/HistoryRepository.cs +++ b/src/NzbDrone.Core/History/HistoryRepository.cs @@ -16,7 +16,7 @@ namespace NzbDrone.Core.History List FindByDownloadId(string downloadId); List FindDownloadHistory(int movieId, QualityModel quality); List GetByMovieId(int movieId, MovieHistoryEventType? eventType); - void DeleteForMovie(int movieId); + void DeleteForMovies(List movieIds); MovieHistory MostRecentForMovie(int movieId); List Since(DateTime date, MovieHistoryEventType? eventType); } @@ -68,9 +68,9 @@ namespace NzbDrone.Core.History return query.OrderByDescending(h => h.Date).ToList(); } - public void DeleteForMovie(int movieId) + public void DeleteForMovies(List movieIds) { - Delete(c => c.MovieId == movieId); + Delete(c => movieIds.Contains(c.MovieId)); } protected override SqlBuilder PagedBuilder() => new SqlBuilder() diff --git a/src/NzbDrone.Core/History/HistoryService.cs b/src/NzbDrone.Core/History/HistoryService.cs index a2b1886d0..2b5181c6e 100644 --- a/src/NzbDrone.Core/History/HistoryService.cs +++ b/src/NzbDrone.Core/History/HistoryService.cs @@ -37,7 +37,7 @@ namespace NzbDrone.Core.History IHandle, IHandle, IHandle, - IHandle, + IHandle, IHandle { private readonly IHistoryRepository _historyRepository; @@ -247,9 +247,9 @@ namespace NzbDrone.Core.History _historyRepository.Insert(history); } - public void Handle(MovieDeletedEvent message) + public void Handle(MoviesDeletedEvent message) { - _historyRepository.DeleteForMovie(message.Movie.Id); + _historyRepository.DeleteForMovies(message.Movies.Select(m => m.Id).ToList()); } public string FindDownloadId(MovieImportedEvent trackedDownload) diff --git a/src/NzbDrone.Core/MediaCover/MediaCoverService.cs b/src/NzbDrone.Core/MediaCover/MediaCoverService.cs index e54d2a89a..aba2e17fa 100644 --- a/src/NzbDrone.Core/MediaCover/MediaCoverService.cs +++ b/src/NzbDrone.Core/MediaCover/MediaCoverService.cs @@ -23,7 +23,7 @@ namespace NzbDrone.Core.MediaCover public class MediaCoverService : IHandleAsync, - IHandleAsync, + IHandleAsync, IMapCoversToLocal { private readonly IImageResizer _resizer; @@ -195,12 +195,15 @@ namespace NzbDrone.Core.MediaCover _eventAggregator.PublishEvent(new MediaCoversUpdatedEvent(message.Movie, updated)); } - public void HandleAsync(MovieDeletedEvent message) + public void HandleAsync(MoviesDeletedEvent message) { - var path = GetMovieCoverPath(message.Movie.Id); - if (_diskProvider.FolderExists(path)) + foreach (var movie in message.Movies) { - _diskProvider.DeleteFolder(path, true); + var path = GetMovieCoverPath(movie.Id); + if (_diskProvider.FolderExists(path)) + { + _diskProvider.DeleteFolder(path, true); + } } } } diff --git a/src/NzbDrone.Core/MediaFiles/MediaFileDeletionService.cs b/src/NzbDrone.Core/MediaFiles/MediaFileDeletionService.cs index da2732ef1..4f06090a4 100644 --- a/src/NzbDrone.Core/MediaFiles/MediaFileDeletionService.cs +++ b/src/NzbDrone.Core/MediaFiles/MediaFileDeletionService.cs @@ -20,7 +20,7 @@ namespace NzbDrone.Core.MediaFiles } public class MediaFileDeletionService : IDeleteMediaFiles, - IHandleAsync, + IHandleAsync, IHandle { private readonly IDiskProvider _diskProvider; @@ -83,36 +83,38 @@ namespace NzbDrone.Core.MediaFiles _mediaFileService.Delete(movieFile, DeleteMediaFileReason.Manual); } - public void HandleAsync(MovieDeletedEvent message) + public void HandleAsync(MoviesDeletedEvent message) { if (message.DeleteFiles) { - var movie = message.Movie; var allMovies = _movieService.GetAllMovies(); - foreach (var s in allMovies) + foreach (var movie in message.Movies) { - if (s.Id == movie.Id) + foreach (var s in allMovies) { - continue; + if (s.Id == movie.Id) + { + continue; + } + + if (movie.Path.IsParentPath(s.Path)) + { + _logger.Error("Movie path: '{0}' is a parent of another movie, not deleting files.", movie.Path); + return; + } + + if (movie.Path.PathEquals(s.Path)) + { + _logger.Error("Movie path: '{0}' is the same as another movie, not deleting files.", movie.Path); + return; + } } - if (movie.Path.IsParentPath(s.Path)) + if (_diskProvider.FolderExists(movie.Path)) { - _logger.Error("Movie path: '{0}' is a parent of another movie, not deleting files.", movie.Path); - return; + _recycleBinProvider.DeleteFolder(movie.Path); } - - if (movie.Path.PathEquals(s.Path)) - { - _logger.Error("Movie path: '{0}' is the same as another movie, not deleting files.", movie.Path); - return; - } - } - - if (_diskProvider.FolderExists(message.Movie.Path)) - { - _recycleBinProvider.DeleteFolder(message.Movie.Path); } } } diff --git a/src/NzbDrone.Core/MediaFiles/MediaFileRepository.cs b/src/NzbDrone.Core/MediaFiles/MediaFileRepository.cs index e59bc8095..737f3ef0d 100644 --- a/src/NzbDrone.Core/MediaFiles/MediaFileRepository.cs +++ b/src/NzbDrone.Core/MediaFiles/MediaFileRepository.cs @@ -8,6 +8,7 @@ namespace NzbDrone.Core.MediaFiles { List GetFilesByMovie(int movieId); List GetFilesWithoutMediaInfo(); + void DeleteForMovies(List movieIds); } public class MediaFileRepository : BasicRepository, IMediaFileRepository @@ -26,5 +27,10 @@ namespace NzbDrone.Core.MediaFiles { return Query(x => x.MediaInfo == null); } + + public void DeleteForMovies(List movieIds) + { + Delete(x => movieIds.Contains(x.MovieId)); + } } } diff --git a/src/NzbDrone.Core/MediaFiles/MediaFileService.cs b/src/NzbDrone.Core/MediaFiles/MediaFileService.cs index 610bc8358..c44775bca 100644 --- a/src/NzbDrone.Core/MediaFiles/MediaFileService.cs +++ b/src/NzbDrone.Core/MediaFiles/MediaFileService.cs @@ -22,7 +22,7 @@ namespace NzbDrone.Core.MediaFiles List GetMovies(IEnumerable ids); } - public class MediaFileService : IMediaFileService, IHandleAsync + public class MediaFileService : IMediaFileService, IHandleAsync { private readonly IMediaFileRepository _mediaFileRepository; private readonly IMovieRepository _movieRepository; @@ -106,10 +106,9 @@ namespace NzbDrone.Core.MediaFiles return _mediaFileRepository.Get(id); } - public void HandleAsync(MovieDeletedEvent message) + public void HandleAsync(MoviesDeletedEvent message) { - var files = GetFilesByMovie(message.Movie.Id); - _mediaFileRepository.DeleteMany(files); + _mediaFileRepository.DeleteForMovies(message.Movies.Select(m => m.Id).ToList()); } } } diff --git a/src/NzbDrone.Core/Movies/AlternativeTitles/AlternativeTitleRepository.cs b/src/NzbDrone.Core/Movies/AlternativeTitles/AlternativeTitleRepository.cs index 1e1ede2fd..e3c7d5f6a 100644 --- a/src/NzbDrone.Core/Movies/AlternativeTitles/AlternativeTitleRepository.cs +++ b/src/NzbDrone.Core/Movies/AlternativeTitles/AlternativeTitleRepository.cs @@ -10,6 +10,7 @@ namespace NzbDrone.Core.Movies.AlternativeTitles AlternativeTitle FindBySourceId(int sourceId); List FindBySourceIds(List sourceIds); List FindByMovieId(int movieId); + void DeleteForMovies(List movieIds); } public class AlternativeTitleRepository : BasicRepository, IAlternativeTitleRepository @@ -33,5 +34,10 @@ namespace NzbDrone.Core.Movies.AlternativeTitles { return Query(x => x.MovieId == movieId); } + + public void DeleteForMovies(List movieIds) + { + Delete(x => movieIds.Contains(x.MovieId)); + } } } diff --git a/src/NzbDrone.Core/Movies/AlternativeTitles/AlternativeTitleService.cs b/src/NzbDrone.Core/Movies/AlternativeTitles/AlternativeTitleService.cs index 2414d4844..729149921 100644 --- a/src/NzbDrone.Core/Movies/AlternativeTitles/AlternativeTitleService.cs +++ b/src/NzbDrone.Core/Movies/AlternativeTitles/AlternativeTitleService.cs @@ -18,7 +18,7 @@ namespace NzbDrone.Core.Movies.AlternativeTitles List UpdateTitles(List titles, Movie movie); } - public class AlternativeTitleService : IAlternativeTitleService, IHandleAsync + public class AlternativeTitleService : IAlternativeTitleService, IHandleAsync { private readonly IAlternativeTitleRepository _titleRepo; private readonly IConfigService _configService; @@ -99,10 +99,9 @@ namespace NzbDrone.Core.Movies.AlternativeTitles return titles; } - public void HandleAsync(MovieDeletedEvent message) + public void HandleAsync(MoviesDeletedEvent message) { - var title = GetAllTitlesForMovie(message.Movie.Id); - _titleRepo.DeleteMany(title); + _titleRepo.DeleteForMovies(message.Movies.Select(m => m.Id).ToList()); } } } diff --git a/src/NzbDrone.Core/Movies/Credits/CreditRepository.cs b/src/NzbDrone.Core/Movies/Credits/CreditRepository.cs index f5459b7c6..330fef6ff 100644 --- a/src/NzbDrone.Core/Movies/Credits/CreditRepository.cs +++ b/src/NzbDrone.Core/Movies/Credits/CreditRepository.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using NzbDrone.Core.Datastore; using NzbDrone.Core.Messaging.Events; @@ -7,6 +7,7 @@ namespace NzbDrone.Core.Movies.Credits public interface ICreditRepository : IBasicRepository { List FindByMovieId(int movieId); + void DeleteForMovies(List movieIds); } public class CreditRepository : BasicRepository, ICreditRepository @@ -20,5 +21,10 @@ namespace NzbDrone.Core.Movies.Credits { return Query(x => x.MovieId == movieId); } + + public void DeleteForMovies(List movieIds) + { + Delete(x => movieIds.Contains(x.MovieId)); + } } } diff --git a/src/NzbDrone.Core/Movies/Credits/CreditService.cs b/src/NzbDrone.Core/Movies/Credits/CreditService.cs index 77b65e243..95644712a 100644 --- a/src/NzbDrone.Core/Movies/Credits/CreditService.cs +++ b/src/NzbDrone.Core/Movies/Credits/CreditService.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using NzbDrone.Common.Extensions; using NzbDrone.Core.Messaging.Events; @@ -16,7 +16,7 @@ namespace NzbDrone.Core.Movies.Credits List UpdateCredits(List credits, Movie movie); } - public class CreditService : ICreditService, IHandleAsync + public class CreditService : ICreditService, IHandleAsync { private readonly ICreditRepository _creditRepo; @@ -82,9 +82,9 @@ namespace NzbDrone.Core.Movies.Credits return credits; } - public void HandleAsync(MovieDeletedEvent message) + public void HandleAsync(MoviesDeletedEvent message) { - _creditRepo.DeleteMany(GetAllCreditsForMovie(message.Movie.Id)); + _creditRepo.DeleteForMovies(message.Movies.Select(m => m.Id).ToList()); } } } diff --git a/src/NzbDrone.Core/Movies/Events/MovieDeletedEvent.cs b/src/NzbDrone.Core/Movies/Events/MovieDeletedEvent.cs deleted file mode 100644 index e21032227..000000000 --- a/src/NzbDrone.Core/Movies/Events/MovieDeletedEvent.cs +++ /dev/null @@ -1,16 +0,0 @@ -using NzbDrone.Common.Messaging; - -namespace NzbDrone.Core.Movies.Events -{ - public class MovieDeletedEvent : IEvent - { - public Movie Movie { get; private set; } - public bool DeleteFiles { get; private set; } - - public MovieDeletedEvent(Movie movie, bool deleteFiles) - { - Movie = movie; - DeleteFiles = deleteFiles; - } - } -} diff --git a/src/NzbDrone.Core/Movies/Events/MoviesDeletedEvent.cs b/src/NzbDrone.Core/Movies/Events/MoviesDeletedEvent.cs new file mode 100644 index 000000000..2f3c6dfc5 --- /dev/null +++ b/src/NzbDrone.Core/Movies/Events/MoviesDeletedEvent.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using NzbDrone.Common.Messaging; + +namespace NzbDrone.Core.Movies.Events +{ + public class MoviesDeletedEvent : IEvent + { + public List Movies { get; private set; } + public bool DeleteFiles { get; private set; } + public bool AddExclusion { get; private set; } + + public MoviesDeletedEvent(List movies, bool deleteFiles, bool addExclusion) + { + Movies = movies; + DeleteFiles = deleteFiles; + AddExclusion = addExclusion; + } + } +} diff --git a/src/NzbDrone.Core/Movies/MovieService.cs b/src/NzbDrone.Core/Movies/MovieService.cs index 149165e8c..3a979851b 100644 --- a/src/NzbDrone.Core/Movies/MovieService.cs +++ b/src/NzbDrone.Core/Movies/MovieService.cs @@ -10,8 +10,6 @@ using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles.Events; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Movies.Events; -using NzbDrone.Core.NetImport.ImportExclusions; -using NzbDrone.Core.Organizer; using NzbDrone.Core.Parser; using NzbDrone.Core.Parser.RomanNumerals; @@ -39,6 +37,7 @@ namespace NzbDrone.Core.Movies PagingSpec MoviesWithoutFiles(PagingSpec pagingSpec); void SetFileId(Movie movie, MovieFile movieFile); void DeleteMovie(int movieId, bool deleteFiles, bool addExclusion = false); + void DeleteMovies(List movieIds, bool deleteFiles, bool addExclusion = false); List GetAllMovies(); List AllForTag(int tagId); Movie UpdateMovie(Movie movie); @@ -54,24 +53,18 @@ namespace NzbDrone.Core.Movies private readonly IMovieRepository _movieRepository; private readonly IConfigService _configService; private readonly IEventAggregator _eventAggregator; - private readonly IBuildFileNames _fileNameBuilder; - private readonly IImportExclusionsService _exclusionService; private readonly IBuildMoviePaths _moviePathBuilder; private readonly Logger _logger; public MovieService(IMovieRepository movieRepository, IEventAggregator eventAggregator, - IBuildFileNames fileNameBuilder, IConfigService configService, - IImportExclusionsService exclusionService, IBuildMoviePaths moviePathBuilder, Logger logger) { _movieRepository = movieRepository; _eventAggregator = eventAggregator; - _fileNameBuilder = fileNameBuilder; _configService = configService; - _exclusionService = exclusionService; _moviePathBuilder = moviePathBuilder; _logger = logger; } @@ -233,14 +226,24 @@ namespace NzbDrone.Core.Movies public void DeleteMovie(int movieId, bool deleteFiles, bool addExclusion = false) { var movie = _movieRepository.Get(movieId); - if (addExclusion) - { - _exclusionService.AddExclusion(new ImportExclusion { TmdbId = movie.TmdbId, MovieTitle = movie.Title, MovieYear = movie.Year }); - } _movieRepository.Delete(movieId); - _eventAggregator.PublishEvent(new MovieDeletedEvent(movie, deleteFiles)); - _logger.Info("Deleted movie {}", movie); + _eventAggregator.PublishEvent(new MoviesDeletedEvent(new List { movie }, deleteFiles, addExclusion)); + _logger.Info("Deleted movie {0}", movie); + } + + public void DeleteMovies(List movieIds, bool deleteFiles, bool addExclusion = false) + { + var moviesToDelete = _movieRepository.Get(movieIds).ToList(); + + _movieRepository.DeleteMany(movieIds); + + _eventAggregator.PublishEvent(new MoviesDeletedEvent(moviesToDelete, deleteFiles, addExclusion)); + + foreach (var movie in moviesToDelete) + { + _logger.Info("Deleted movie {0}", movie); + } } public List GetAllMovies() diff --git a/src/NzbDrone.Core/NetImport/ImportExclusions/ImportExclusionsService.cs b/src/NzbDrone.Core/NetImport/ImportExclusions/ImportExclusionsService.cs index 26452f599..072d1a4b8 100644 --- a/src/NzbDrone.Core/NetImport/ImportExclusions/ImportExclusionsService.cs +++ b/src/NzbDrone.Core/NetImport/ImportExclusions/ImportExclusionsService.cs @@ -1,35 +1,29 @@ using System.Collections.Generic; using System.Linq; using NLog; -using NzbDrone.Core.Configuration; using NzbDrone.Core.Messaging.Events; +using NzbDrone.Core.Movies.Events; namespace NzbDrone.Core.NetImport.ImportExclusions { public interface IImportExclusionsService { List GetAllExclusions(); - bool IsMovieExcluded(int tmdbid); + bool IsMovieExcluded(int tmdbId); ImportExclusion AddExclusion(ImportExclusion exclusion); void RemoveExclusion(ImportExclusion exclusion); ImportExclusion GetById(int id); } - public class ImportExclusionsService : IImportExclusionsService + public class ImportExclusionsService : IImportExclusionsService, IHandleAsync { private readonly IImportExclusionsRepository _exclusionRepository; - private readonly IConfigService _configService; - private readonly IEventAggregator _eventAggregator; private readonly Logger _logger; public ImportExclusionsService(IImportExclusionsRepository exclusionRepository, - IEventAggregator eventAggregator, - IConfigService configService, Logger logger) { _exclusionRepository = exclusionRepository; - _eventAggregator = eventAggregator; - _configService = configService; _logger = logger; } @@ -48,9 +42,9 @@ namespace NzbDrone.Core.NetImport.ImportExclusions return _exclusionRepository.All().ToList(); } - public bool IsMovieExcluded(int tmdbid) + public bool IsMovieExcluded(int tmdbId) { - return _exclusionRepository.IsMovieExcluded(tmdbid); + return _exclusionRepository.IsMovieExcluded(tmdbId); } public void RemoveExclusion(ImportExclusion exclusion) @@ -62,5 +56,14 @@ namespace NzbDrone.Core.NetImport.ImportExclusions { return _exclusionRepository.Get(id); } + + public void HandleAsync(MoviesDeletedEvent message) + { + if (message.AddExclusion) + { + _logger.Debug("Adding {0} Deleted Movies to Net Import Exclusions", message.Movies.Count); + _exclusionRepository.InsertMany(message.Movies.Select(m => new ImportExclusion { TmdbId = m.TmdbId, MovieTitle = m.Title, MovieYear = m.Year }).ToList()); + } + } } } diff --git a/src/Radarr.Api.V3/Movies/MovieEditorModule.cs b/src/Radarr.Api.V3/Movies/MovieEditorModule.cs index 24f1c1e87..dbf0278b9 100644 --- a/src/Radarr.Api.V3/Movies/MovieEditorModule.cs +++ b/src/Radarr.Api.V3/Movies/MovieEditorModule.cs @@ -94,10 +94,7 @@ namespace Radarr.Api.V3.Movies { var resource = Request.Body.FromJson(); - foreach (var id in resource.MovieIds) - { - _movieService.DeleteMovie(id, resource.DeleteFiles, resource.AddNetImportExclusion); - } + _movieService.DeleteMovies(resource.MovieIds, resource.DeleteFiles, resource.AddNetImportExclusion); return new object(); } diff --git a/src/Radarr.Api.V3/Movies/MovieModule.cs b/src/Radarr.Api.V3/Movies/MovieModule.cs index f5bcd461e..7e311aa59 100644 --- a/src/Radarr.Api.V3/Movies/MovieModule.cs +++ b/src/Radarr.Api.V3/Movies/MovieModule.cs @@ -25,7 +25,7 @@ namespace Radarr.Api.V3.Movies IHandle, IHandle, IHandle, - IHandle, + IHandle, IHandle, IHandle { @@ -220,9 +220,12 @@ namespace Radarr.Api.V3.Movies BroadcastResourceChange(ModelAction.Updated, message.Movie.Id); } - public void Handle(MovieDeletedEvent message) + public void Handle(MoviesDeletedEvent message) { - BroadcastResourceChange(ModelAction.Deleted, message.Movie.ToResource()); + foreach (var movie in message.Movies) + { + BroadcastResourceChange(ModelAction.Deleted, movie.Id); + } } public void Handle(MovieRenamedEvent message)