diff --git a/src/Lidarr.Api.V1/Artist/ArtistEditorModule.cs b/src/Lidarr.Api.V1/Artist/ArtistEditorModule.cs index eb3a8bc9c..ebf208aa8 100644 --- a/src/Lidarr.Api.V1/Artist/ArtistEditorModule.cs +++ b/src/Lidarr.Api.V1/Artist/ArtistEditorModule.cs @@ -95,10 +95,7 @@ namespace Lidarr.Api.V1.Artist { var resource = Request.Body.FromJson(); - foreach (var artistId in resource.ArtistIds) - { - _artistService.DeleteArtist(artistId, resource.DeleteFiles); - } + _artistService.DeleteArtists(resource.ArtistIds, resource.DeleteFiles); return new object(); } diff --git a/src/Lidarr.Api.V1/Artist/ArtistModule.cs b/src/Lidarr.Api.V1/Artist/ArtistModule.cs index 588ecc532..8b03027d8 100644 --- a/src/Lidarr.Api.V1/Artist/ArtistModule.cs +++ b/src/Lidarr.Api.V1/Artist/ArtistModule.cs @@ -29,7 +29,7 @@ namespace Lidarr.Api.V1.Artist IHandle, IHandle, IHandle, - IHandle, + IHandle, IHandle, IHandle { @@ -285,9 +285,12 @@ namespace Lidarr.Api.V1.Artist BroadcastResourceChange(ModelAction.Updated, GetArtistResource(message.Artist)); } - public void Handle(ArtistDeletedEvent message) + public void Handle(ArtistsDeletedEvent message) { - BroadcastResourceChange(ModelAction.Deleted, message.Artist.ToResource()); + foreach (var artist in message.Artists) + { + BroadcastResourceChange(ModelAction.Deleted, artist.ToResource()); + } } public void Handle(ArtistRenamedEvent message) diff --git a/src/NzbDrone.Core/ArtistStats/ArtistStatisticsService.cs b/src/NzbDrone.Core/ArtistStats/ArtistStatisticsService.cs index 5810387a7..c00ee5948 100644 --- a/src/NzbDrone.Core/ArtistStats/ArtistStatisticsService.cs +++ b/src/NzbDrone.Core/ArtistStats/ArtistStatisticsService.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using NzbDrone.Common.Cache; using NzbDrone.Core.MediaFiles.Events; @@ -16,7 +16,7 @@ namespace NzbDrone.Core.ArtistStats public class ArtistStatisticsService : IArtistStatisticsService, IHandle, - IHandle, + IHandle, IHandle, IHandle, IHandle, @@ -76,10 +76,14 @@ namespace NzbDrone.Core.ArtistStats } [EventHandleOrder(EventHandleOrder.First)] - public void Handle(ArtistDeletedEvent message) + public void Handle(ArtistsDeletedEvent message) { _cache.Remove("AllArtists"); - _cache.Remove(message.Artist.Id.ToString()); + + foreach (var artist in message.Artists) + { + _cache.Remove(artist.Id.ToString()); + } } [EventHandleOrder(EventHandleOrder.First)] diff --git a/src/NzbDrone.Core/Blacklisting/BlacklistRepository.cs b/src/NzbDrone.Core/Blacklisting/BlacklistRepository.cs index e540ba15e..6de8c4626 100644 --- a/src/NzbDrone.Core/Blacklisting/BlacklistRepository.cs +++ b/src/NzbDrone.Core/Blacklisting/BlacklistRepository.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using NzbDrone.Core.Datastore; using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Music; @@ -9,7 +9,8 @@ namespace NzbDrone.Core.Blacklisting { List BlacklistedByTitle(int artistId, string sourceTitle); List BlacklistedByTorrentInfoHash(int artistId, string torrentInfoHash); - List BlacklistedByArtist(int artistId); + List BlacklistedByArtists(List artistIds); + void DeleteForArtists(List artistIds); } public class BlacklistRepository : BasicRepository, IBlacklistRepository @@ -29,9 +30,14 @@ namespace NzbDrone.Core.Blacklisting return Query(e => e.ArtistId == artistId && e.TorrentInfoHash.Contains(torrentInfoHash)); } - public List BlacklistedByArtist(int artistId) + public List BlacklistedByArtists(List artistIds) { - return Query(b => b.ArtistId == artistId); + return Query(x => artistIds.Contains(x.ArtistId)); + } + + public void DeleteForArtists(List artistIds) + { + Delete(x => artistIds.Contains(x.ArtistId)); } protected override SqlBuilder PagedBuilder() => new SqlBuilder().Join((b, m) => b.ArtistId == m.Id); diff --git a/src/NzbDrone.Core/Blacklisting/BlacklistService.cs b/src/NzbDrone.Core/Blacklisting/BlacklistService.cs index 1e0b02093..7ee082e56 100644 --- a/src/NzbDrone.Core/Blacklisting/BlacklistService.cs +++ b/src/NzbDrone.Core/Blacklisting/BlacklistService.cs @@ -24,7 +24,7 @@ namespace NzbDrone.Core.Blacklisting IExecute, IHandle, - IHandleAsync + IHandleAsync { private readonly IBlacklistRepository _blacklistRepository; @@ -161,11 +161,9 @@ namespace NzbDrone.Core.Blacklisting _blacklistRepository.Insert(blacklist); } - public void HandleAsync(ArtistDeletedEvent message) + public void HandleAsync(ArtistsDeletedEvent message) { - var blacklisted = _blacklistRepository.BlacklistedByArtist(message.Artist.Id); - - _blacklistRepository.DeleteMany(blacklisted); + _blacklistRepository.DeleteForArtists(message.Artists.Select(x => x.Id).ToList()); } } } diff --git a/src/NzbDrone.Core/Download/Pending/PendingReleaseRepository.cs b/src/NzbDrone.Core/Download/Pending/PendingReleaseRepository.cs index 8052ea01b..9fb8d86bc 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 DeleteByArtistId(int artistId); + void DeleteByArtistIds(List artistIds); List AllByArtistId(int artistId); List WithoutFallback(); } @@ -18,9 +18,9 @@ namespace NzbDrone.Core.Download.Pending { } - public void DeleteByArtistId(int artistId) + public void DeleteByArtistIds(List artistIds) { - Delete(artistId); + Delete(x => artistIds.Contains(x.ArtistId)); } public List AllByArtistId(int artistId) diff --git a/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs b/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs index 19a19ce3a..c521870cb 100644 --- a/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs +++ b/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs @@ -31,7 +31,7 @@ namespace NzbDrone.Core.Download.Pending } public class PendingReleaseService : IPendingReleaseService, - IHandle, + IHandle, IHandle, IHandle { @@ -425,9 +425,9 @@ namespace NzbDrone.Core.Download.Pending return 1; } - public void Handle(ArtistDeletedEvent message) + public void Handle(ArtistsDeletedEvent message) { - _repository.DeleteByArtistId(message.Artist.Id); + _repository.DeleteByArtistIds(message.Artists.Select(x => x.Id).ToList()); } public void Handle(AlbumGrabbedEvent message) diff --git a/src/NzbDrone.Core/Extras/Files/ExtraFileRepository.cs b/src/NzbDrone.Core/Extras/Files/ExtraFileRepository.cs index ff5113253..5d88a9a36 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 DeleteForArtist(int artistId); + void DeleteForArtists(List artistIds); void DeleteForAlbum(int artistId, int albumId); void DeleteForTrackFile(int trackFileId); List GetFilesByArtist(int artistId); @@ -25,9 +25,9 @@ namespace NzbDrone.Core.Extras.Files { } - public void DeleteForArtist(int artistId) + public void DeleteForArtists(List artistIds) { - Delete(c => c.ArtistId == artistId); + Delete(c => artistIds.Contains(c.ArtistId)); } public void DeleteForAlbum(int artistId, int albumId) diff --git a/src/NzbDrone.Core/Extras/Files/ExtraFileService.cs b/src/NzbDrone.Core/Extras/Files/ExtraFileService.cs index f4a8dc8f2..a1c113a39 100644 --- a/src/NzbDrone.Core/Extras/Files/ExtraFileService.cs +++ b/src/NzbDrone.Core/Extras/Files/ExtraFileService.cs @@ -26,7 +26,7 @@ namespace NzbDrone.Core.Extras.Files } public abstract class ExtraFileService : IExtraFileService, - IHandleAsync, + IHandleAsync, IHandle where TExtraFile : ExtraFile, new() { @@ -95,10 +95,9 @@ namespace NzbDrone.Core.Extras.Files _repository.DeleteMany(ids); } - public void HandleAsync(ArtistDeletedEvent message) + public void HandleAsync(ArtistsDeletedEvent message) { - _logger.Debug("Deleting Extra from database for artist: {0}", message.Artist); - _repository.DeleteForArtist(message.Artist.Id); + _repository.DeleteForArtists(message.Artists.Select(x => x.Id).ToList()); } public void Handle(TrackFileDeletedEvent message) diff --git a/src/NzbDrone.Core/HealthCheck/Checks/RootFolderCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/RootFolderCheck.cs index 36be27f50..d5509366e 100644 --- a/src/NzbDrone.Core/HealthCheck/Checks/RootFolderCheck.cs +++ b/src/NzbDrone.Core/HealthCheck/Checks/RootFolderCheck.cs @@ -8,7 +8,7 @@ using NzbDrone.Core.RootFolders; namespace NzbDrone.Core.HealthCheck.Checks { - [CheckOn(typeof(ArtistDeletedEvent))] + [CheckOn(typeof(ArtistsDeletedEvent))] [CheckOn(typeof(ArtistMovedEvent))] [CheckOn(typeof(TrackImportedEvent), CheckOnCondition.FailedOnly)] [CheckOn(typeof(TrackImportFailedEvent), CheckOnCondition.SuccessfulOnly)] diff --git a/src/NzbDrone.Core/History/HistoryRepository.cs b/src/NzbDrone.Core/History/HistoryRepository.cs index 98142b9b1..71c6c4892 100644 --- a/src/NzbDrone.Core/History/HistoryRepository.cs +++ b/src/NzbDrone.Core/History/HistoryRepository.cs @@ -16,7 +16,7 @@ namespace NzbDrone.Core.History List GetByArtist(int artistId, HistoryEventType? eventType); List GetByAlbum(int albumId, HistoryEventType? eventType); List FindDownloadHistory(int idArtistId, QualityModel quality); - void DeleteForArtist(int artistId); + void DeleteForArtists(List artistIds); List Since(DateTime date, HistoryEventType? eventType); } @@ -97,9 +97,9 @@ namespace NzbDrone.Core.History allowed.Contains(h.EventType)); } - public void DeleteForArtist(int artistId) + public void DeleteForArtists(List artistIds) { - Delete(c => c.ArtistId == artistId); + Delete(c => artistIds.Contains(c.ArtistId)); } protected override SqlBuilder PagedBuilder() => new SqlBuilder() diff --git a/src/NzbDrone.Core/History/HistoryService.cs b/src/NzbDrone.Core/History/HistoryService.cs index 816c67cb5..ca6e19f20 100644 --- a/src/NzbDrone.Core/History/HistoryService.cs +++ b/src/NzbDrone.Core/History/HistoryService.cs @@ -39,7 +39,7 @@ namespace NzbDrone.Core.History IHandle, IHandle, IHandle, - IHandle, + IHandle, IHandle { private readonly IHistoryRepository _historyRepository; @@ -365,9 +365,9 @@ namespace NzbDrone.Core.History } } - public void Handle(ArtistDeletedEvent message) + public void Handle(ArtistsDeletedEvent message) { - _historyRepository.DeleteForArtist(message.Artist.Id); + _historyRepository.DeleteForArtists(message.Artists.Select(x => x.Id).ToList()); } public void Handle(DownloadIgnoredEvent message) diff --git a/src/NzbDrone.Core/ImportLists/Exclusions/ImportListExclusionService.cs b/src/NzbDrone.Core/ImportLists/Exclusions/ImportListExclusionService.cs index f4b3de7e6..b81971e20 100644 --- a/src/NzbDrone.Core/ImportLists/Exclusions/ImportListExclusionService.cs +++ b/src/NzbDrone.Core/ImportLists/Exclusions/ImportListExclusionService.cs @@ -18,7 +18,7 @@ namespace NzbDrone.Core.ImportLists.Exclusions } public class ImportListExclusionService : IImportListExclusionService, - IHandleAsync, + IHandleAsync, IHandleAsync { private readonly IImportListExclusionRepository _repo; @@ -72,27 +72,32 @@ namespace NzbDrone.Core.ImportLists.Exclusions return _repo.All().ToList(); } - public void HandleAsync(ArtistDeletedEvent message) + public void HandleAsync(ArtistsDeletedEvent message) { if (!message.AddImportListExclusion) { return; } - var existingExclusion = _repo.FindByForeignId(message.Artist.ForeignArtistId); + var importExclusions = new List(); - if (existingExclusion != null) + foreach (var artist in message.Artists) { - return; + var existingExclusion = _repo.FindByForeignId(artist.ForeignArtistId); + + if (existingExclusion != null) + { + return; + } + + importExclusions.Add(new ImportListExclusion + { + ForeignId = artist.ForeignArtistId, + Name = artist.Name + }); } - var importExclusion = new ImportListExclusion - { - ForeignId = message.Artist.ForeignArtistId, - Name = message.Artist.Name - }; - - _repo.Insert(importExclusion); + _repo.InsertMany(importExclusions); } public void HandleAsync(AlbumDeletedEvent message) diff --git a/src/NzbDrone.Core/MediaCover/MediaCoverService.cs b/src/NzbDrone.Core/MediaCover/MediaCoverService.cs index 02c5219c4..b55910e0e 100644 --- a/src/NzbDrone.Core/MediaCover/MediaCoverService.cs +++ b/src/NzbDrone.Core/MediaCover/MediaCoverService.cs @@ -25,7 +25,7 @@ namespace NzbDrone.Core.MediaCover public class MediaCoverService : IHandleAsync, - IHandleAsync, + IHandleAsync, IHandleAsync, IHandleAsync, IMapCoversToLocal @@ -293,12 +293,15 @@ namespace NzbDrone.Core.MediaCover _eventAggregator.PublishEvent(new MediaCoversUpdatedEvent(message.Artist, updated)); } - public void HandleAsync(ArtistDeletedEvent message) + public void HandleAsync(ArtistsDeletedEvent message) { - var path = GetArtistCoverPath(message.Artist.Id); - if (_diskProvider.FolderExists(path)) + foreach (var artist in message.Artists) { - _diskProvider.DeleteFolder(path, true); + var path = GetArtistCoverPath(artist.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 0a5b1e7b5..4bbd265fd 100644 --- a/src/NzbDrone.Core/MediaFiles/MediaFileDeletionService.cs +++ b/src/NzbDrone.Core/MediaFiles/MediaFileDeletionService.cs @@ -21,7 +21,7 @@ namespace NzbDrone.Core.MediaFiles } public class MediaFileDeletionService : IDeleteMediaFiles, - IHandleAsync, + IHandleAsync, IHandleAsync, IHandle { @@ -99,36 +99,39 @@ namespace NzbDrone.Core.MediaFiles _mediaFileService.Delete(trackFile, DeleteMediaFileReason.Manual); } - public void HandleAsync(ArtistDeletedEvent message) + public void HandleAsync(ArtistsDeletedEvent message) { if (message.DeleteFiles) { - var artist = message.Artist; + var artists = message.Artists; var allArtists = _artistService.AllArtistPaths(); - foreach (var s in allArtists) + foreach (var artist in artists) { - if (s.Key == artist.Id) + foreach (var s in allArtists) { - continue; + if (s.Key == artist.Id) + { + continue; + } + + if (artist.Path.IsParentPath(s.Value)) + { + _logger.Error("Artist path: '{0}' is a parent of another artist, not deleting files.", artist.Path); + return; + } + + if (artist.Path.PathEquals(s.Value)) + { + _logger.Error("Artist path: '{0}' is the same as another artist, not deleting files.", artist.Path); + return; + } } - if (artist.Path.IsParentPath(s.Value)) + if (_diskProvider.FolderExists(artist.Path)) { - _logger.Error("Artist path: '{0}' is a parent of another artist, not deleting files.", artist.Path); - return; + _recycleBinProvider.DeleteFolder(artist.Path); } - - if (artist.Path.PathEquals(s.Value)) - { - _logger.Error("Artist path: '{0}' is the same as another artist, not deleting files.", artist.Path); - return; - } - } - - if (_diskProvider.FolderExists(message.Artist.Path)) - { - _recycleBinProvider.DeleteFolder(message.Artist.Path); } } } diff --git a/src/NzbDrone.Core/Music/Events/ArtistDeletedEvent.cs b/src/NzbDrone.Core/Music/Events/ArtistsDeletedEvent.cs similarity index 54% rename from src/NzbDrone.Core/Music/Events/ArtistDeletedEvent.cs rename to src/NzbDrone.Core/Music/Events/ArtistsDeletedEvent.cs index 0c1bf0043..465fa209f 100644 --- a/src/NzbDrone.Core/Music/Events/ArtistDeletedEvent.cs +++ b/src/NzbDrone.Core/Music/Events/ArtistsDeletedEvent.cs @@ -1,16 +1,17 @@ +using System.Collections.Generic; using NzbDrone.Common.Messaging; namespace NzbDrone.Core.Music.Events { - public class ArtistDeletedEvent : IEvent + public class ArtistsDeletedEvent : IEvent { - public Artist Artist { get; private set; } + public List Artists { get; private set; } public bool DeleteFiles { get; private set; } public bool AddImportListExclusion { get; private set; } - public ArtistDeletedEvent(Artist artist, bool deleteFiles, bool addImportListExclusion) + public ArtistsDeletedEvent(List artists, bool deleteFiles, bool addImportListExclusion) { - Artist = artist; + Artists = artists; DeleteFiles = deleteFiles; AddImportListExclusion = addImportListExclusion; } diff --git a/src/NzbDrone.Core/Music/Services/AlbumService.cs b/src/NzbDrone.Core/Music/Services/AlbumService.cs index d1b952cba..14b1af6d7 100644 --- a/src/NzbDrone.Core/Music/Services/AlbumService.cs +++ b/src/NzbDrone.Core/Music/Services/AlbumService.cs @@ -42,7 +42,7 @@ namespace NzbDrone.Core.Music } public class AlbumService : IAlbumService, - IHandle + IHandle { private readonly IAlbumRepository _albumRepository; private readonly IEventAggregator _eventAggregator; @@ -289,9 +289,10 @@ namespace NzbDrone.Core.Music } } - public void Handle(ArtistDeletedEvent message) + public void Handle(ArtistsDeletedEvent message) { - var albums = GetAlbumsByArtistMetadataId(message.Artist.ArtistMetadataId); + //TODO Do this in one call instead of one for each artist? + var albums = message.Artists.SelectMany(x => GetAlbumsByArtistMetadataId(x.ArtistMetadataId)).ToList(); DeleteMany(albums); } } diff --git a/src/NzbDrone.Core/Music/Services/ArtistService.cs b/src/NzbDrone.Core/Music/Services/ArtistService.cs index fbc90ad8e..bd49aeac1 100644 --- a/src/NzbDrone.Core/Music/Services/ArtistService.cs +++ b/src/NzbDrone.Core/Music/Services/ArtistService.cs @@ -22,6 +22,7 @@ namespace NzbDrone.Core.Music Artist FindByNameInexact(string title); List GetCandidates(string title); void DeleteArtist(int artistId, bool deleteFiles, bool addImportListExclusion = false); + void DeleteArtists(List artistIds, bool deleteFiles, bool addImportListExclusion = false); List GetAllArtists(); List AllForTag(int tagId); Artist UpdateArtist(Artist artist, bool publishUpdatedEvent = true); @@ -80,7 +81,21 @@ namespace NzbDrone.Core.Music _cache.Clear(); var artist = _artistRepository.Get(artistId); _artistRepository.Delete(artistId); - _eventAggregator.PublishEvent(new ArtistDeletedEvent(artist, deleteFiles, addImportListExclusion)); + _eventAggregator.PublishEvent(new ArtistsDeletedEvent(new List { artist }, deleteFiles, addImportListExclusion)); + } + + public void DeleteArtists(List artistIds, bool deleteFiles, bool addExclusion = false) + { + var artistsToDelete = _artistRepository.Get(artistIds).ToList(); + + _artistRepository.DeleteMany(artistIds); + + _eventAggregator.PublishEvent(new ArtistsDeletedEvent(artistsToDelete, deleteFiles, addExclusion)); + + foreach (var artist in artistsToDelete) + { + _logger.Info("Deleted artist {0}", artist); + } } public Artist FindById(string foreignArtistId)