Fixed: Speed up mass deletes from Movie Editor (#4463)

pull/2/head
Qstick 5 years ago committed by GitHub
parent 913037c45e
commit 7adb358d1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -20,9 +20,9 @@ namespace NzbDrone.Api.Movies
public class MovieModule : RadarrRestModuleWithSignalR<MovieResource, Movie>,
IHandle<MovieImportedEvent>,
IHandle<MovieFileDeletedEvent>,
IHandle<MoviesDeletedEvent>,
IHandle<MovieUpdatedEvent>,
IHandle<MovieEditedEvent>,
IHandle<MovieDeletedEvent>,
IHandle<MovieRenamedEvent>,
IHandle<MediaCoversUpdatedEvent>
{
@ -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)

@ -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<BlacklistRepository, Blacklist>
{
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<Movie>.CreateNew()
.With(s => s.Id = 7)
.Build();
_movie2 = Builder<Movie>.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<Blacklist>.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<Language>())
.With(c => c.Id = 0)
.BuildListOfNew();
Db.InsertMany(blacklistItems);
Subject.DeleteForMovies(new List<int> { _movie1.Id });
var removedMovieBlacklists = Subject.BlacklistedByMovies(new List<int> { _movie1.Id });
var nonRemovedMovieBlacklists = Subject.BlacklistedByMovies(new List<int> { _movie2.Id });
removedMovieBlacklists.Should().HaveCount(0);
nonRemovedMovieBlacklists.Should().HaveCount(1);
}
}
}

@ -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<DownloadHistoryRepository, DownloadHistory>
{
private Movie _movie1;
private Movie _movie2;
[SetUp]
public void Setup()
{
_movie1 = Builder<Movie>.CreateNew()
.With(s => s.Id = 7)
.Build();
_movie2 = Builder<Movie>.CreateNew()
.With(s => s.Id = 8)
.Build();
}
[Test]
public void should_delete_history_items_by_movieId()
{
var items = Builder<DownloadHistory>.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<int> { _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);
}
}
}

@ -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<int> { _movie1.Id });
var remainingFiles = Subject.AllByMovieId(_movie1.Id);

@ -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<int> { _movie.Id });
var remainingFiles = Subject.GetFilesByMovie(_movie.Id);

@ -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<HistoryRepository, MovieHistory>
{
private Movie _movie1;
private Movie _movie2;
[SetUp]
public void Setup()
{
_movie1 = Builder<Movie>.CreateNew()
.With(s => s.Id = 7)
.Build();
_movie2 = Builder<Movie>.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<MovieHistory>.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> { Language.English })
.With(c => c.EventType = MovieHistoryEventType.Grabbed)
.BuildListOfNew();
Db.InsertMany(items);
Subject.DeleteForMovies(new List<int> { _movie1.Id });
var removedItems = Subject.GetByMovieId(_movie1.Id, null);
var nonRemovedItems = Subject.GetByMovieId(_movie2.Id, null);
removedItems.Should().HaveCount(0);
nonRemovedItems.Should().HaveCount(1);
}
}
}

@ -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<MediaFileRepository, MovieFile>
{
private Movie _movie1;
private Movie _movie2;
[SetUp]
public void Setup()
{
_movie1 = Builder<Movie>.CreateNew()
.With(s => s.Id = 7)
.Build();
_movie2 = Builder<Movie>.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<MovieFile>.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> { Language.English })
.BuildListOfNew();
Db.InsertMany(items);
Subject.DeleteForMovies(new List<int> { _movie1.Id });
var removedItems = Subject.GetFilesByMovie(_movie1.Id);
var nonRemovedItems = Subject.GetFilesByMovie(_movie2.Id);
removedItems.Should().HaveCount(0);
nonRemovedItems.Should().HaveCount(1);
}
}
}

@ -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<CreditRepository, Credit>
{
private Movie _movie1;
private Movie _movie2;
[SetUp]
public void Setup()
{
_movie1 = Builder<Movie>.CreateNew()
.With(s => s.Id = 7)
.Build();
_movie2 = Builder<Movie>.CreateNew()
.With(s => s.Id = 8)
.Build();
}
[Test]
public void should_delete_credits_by_movieId()
{
var credits = Builder<Credit>.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<int> { _movie1.Id });
var removedMovieCredits = Subject.FindByMovieId(_movie1.Id);
var nonRemovedMovieCredits = Subject.FindByMovieId(_movie2.Id);
removedMovieCredits.Should().HaveCount(0);
nonRemovedMovieCredits.Should().HaveCount(1);
}
}
}

@ -9,7 +9,8 @@ namespace NzbDrone.Core.Blacklisting
{
List<Blacklist> BlacklistedByTitle(int movieId, string sourceTitle);
List<Blacklist> BlacklistedByTorrentInfoHash(int movieId, string torrentInfoHash);
List<Blacklist> BlacklistedByMovie(int movieId);
List<Blacklist> BlacklistedByMovies(List<int> movieIds);
void DeleteForMovies(List<int> movieIds);
}
public class BlacklistRepository : BasicRepository<Blacklist>, IBlacklistRepository
@ -29,9 +30,14 @@ namespace NzbDrone.Core.Blacklisting
return Query(x => x.MovieId == movieId && x.TorrentInfoHash.Contains(torrentInfoHash));
}
public List<Blacklist> BlacklistedByMovie(int movieId)
public List<Blacklist> BlacklistedByMovies(List<int> movieIds)
{
return Query(x => x.MovieId == movieId);
return Query(x => movieIds.Contains(x.MovieId));
}
public void DeleteForMovies(List<int> movieIds)
{
Delete(x => movieIds.Contains(x.MovieId));
}
protected override SqlBuilder PagedBuilder() => new SqlBuilder().Join<Blacklist, Movie>((b, m) => b.MovieId == m.Id);

@ -23,7 +23,7 @@ namespace NzbDrone.Core.Blacklisting
IExecute<ClearBlacklistCommand>,
IHandle<DownloadFailedEvent>,
IHandleAsync<MovieDeletedEvent>
IHandleAsync<MoviesDeletedEvent>
{
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());
}
}
}

@ -8,7 +8,7 @@ namespace NzbDrone.Core.Download.History
public interface IDownloadHistoryRepository : IBasicRepository<DownloadHistory>
{
List<DownloadHistory> FindByDownloadId(string downloadId);
void DeleteByMovieId(int movieId);
void DeleteByMovieIds(List<int> movieIds);
}
public class DownloadHistoryRepository : BasicRepository<DownloadHistory>, 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<int> movieIds)
{
Delete(r => r.MovieId == movieId);
Delete(r => movieIds.Contains(r.MovieId));
}
}
}

@ -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<DownloadCompletedEvent>,
IHandle<DownloadFailedEvent>,
IHandle<DownloadIgnoredEvent>,
IHandle<MovieDeletedEvent>
IHandle<MoviesDeletedEvent>
{
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());
}
}
}

@ -6,7 +6,7 @@ namespace NzbDrone.Core.Download.Pending
{
public interface IPendingReleaseRepository : IBasicRepository<PendingRelease>
{
void DeleteByMovieId(int movieId);
void DeleteByMovieIds(List<int> movieIds);
List<PendingRelease> AllByMovieId(int movieId);
List<PendingRelease> WithoutFallback();
}
@ -18,9 +18,9 @@ namespace NzbDrone.Core.Download.Pending
{
}
public void DeleteByMovieId(int movieId)
public void DeleteByMovieIds(List<int> movieIds)
{
Delete(x => x.MovieId == movieId);
Delete(x => movieIds.Contains(x.MovieId));
}
public List<PendingRelease> AllByMovieId(int movieId)

@ -34,7 +34,7 @@ namespace NzbDrone.Core.Download.Pending
public class PendingReleaseService : IPendingReleaseService,
IHandle<MovieGrabbedEvent>,
IHandle<MovieDeletedEvent>,
IHandle<MoviesDeletedEvent>,
IHandle<RssSyncCompleteEvent>
{
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)

@ -8,7 +8,7 @@ namespace NzbDrone.Core.Extras.Files
public interface IExtraFileRepository<TExtraFile> : IBasicRepository<TExtraFile>
where TExtraFile : ExtraFile, new()
{
void DeleteForMovie(int movieId);
void DeleteForMovies(List<int> movieIds);
void DeleteForMovieFile(int movieFileId);
List<TExtraFile> GetFilesByMovie(int movieId);
List<TExtraFile> GetFilesByMovieFile(int movieFileId);
@ -23,9 +23,9 @@ namespace NzbDrone.Core.Extras.Files
{
}
public void DeleteForMovie(int movieId)
public void DeleteForMovies(List<int> movieIds)
{
Delete(x => x.MovieId == movieId);
Delete(x => movieIds.Contains(x.MovieId));
}
public void DeleteForMovieFile(int movieFileId)

@ -25,8 +25,8 @@ namespace NzbDrone.Core.Extras.Files
}
public abstract class ExtraFileService<TExtraFile> : IExtraFileService<TExtraFile>,
IHandleAsync<MovieDeletedEvent>,
IHandleAsync<MovieFileDeletedEvent>
IHandleAsync<MovieFileDeletedEvent>,
IHandleAsync<MoviesDeletedEvent>
where TExtraFile : ExtraFile, new()
{
private readonly IExtraFileRepository<TExtraFile> _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)

@ -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<MovieUpdatedEvent>, ICheckOnCondition<MovieDeletedEvent>
[CheckOn(typeof(MoviesDeletedEvent), CheckOnCondition.FailedOnly)]
public class RemovedSeriesCheck : HealthCheckBase, ICheckOnCondition<MovieUpdatedEvent>, ICheckOnCondition<MoviesDeletedEvent>
{
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)

@ -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)]

@ -16,7 +16,7 @@ namespace NzbDrone.Core.History
List<MovieHistory> FindByDownloadId(string downloadId);
List<MovieHistory> FindDownloadHistory(int movieId, QualityModel quality);
List<MovieHistory> GetByMovieId(int movieId, MovieHistoryEventType? eventType);
void DeleteForMovie(int movieId);
void DeleteForMovies(List<int> movieIds);
MovieHistory MostRecentForMovie(int movieId);
List<MovieHistory> 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<int> movieIds)
{
Delete(c => c.MovieId == movieId);
Delete(c => movieIds.Contains(c.MovieId));
}
protected override SqlBuilder PagedBuilder() => new SqlBuilder()

@ -37,7 +37,7 @@ namespace NzbDrone.Core.History
IHandle<DownloadFailedEvent>,
IHandle<MovieFileDeletedEvent>,
IHandle<MovieFileRenamedEvent>,
IHandle<MovieDeletedEvent>,
IHandle<MoviesDeletedEvent>,
IHandle<DownloadIgnoredEvent>
{
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)

@ -23,7 +23,7 @@ namespace NzbDrone.Core.MediaCover
public class MediaCoverService :
IHandleAsync<MovieUpdatedEvent>,
IHandleAsync<MovieDeletedEvent>,
IHandleAsync<MoviesDeletedEvent>,
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);
}
}
}
}

@ -20,7 +20,7 @@ namespace NzbDrone.Core.MediaFiles
}
public class MediaFileDeletionService : IDeleteMediaFiles,
IHandleAsync<MovieDeletedEvent>,
IHandleAsync<MoviesDeletedEvent>,
IHandle<MovieFileDeletedEvent>
{
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);
}
}
}

@ -8,6 +8,7 @@ namespace NzbDrone.Core.MediaFiles
{
List<MovieFile> GetFilesByMovie(int movieId);
List<MovieFile> GetFilesWithoutMediaInfo();
void DeleteForMovies(List<int> movieIds);
}
public class MediaFileRepository : BasicRepository<MovieFile>, IMediaFileRepository
@ -26,5 +27,10 @@ namespace NzbDrone.Core.MediaFiles
{
return Query(x => x.MediaInfo == null);
}
public void DeleteForMovies(List<int> movieIds)
{
Delete(x => movieIds.Contains(x.MovieId));
}
}
}

@ -22,7 +22,7 @@ namespace NzbDrone.Core.MediaFiles
List<MovieFile> GetMovies(IEnumerable<int> ids);
}
public class MediaFileService : IMediaFileService, IHandleAsync<MovieDeletedEvent>
public class MediaFileService : IMediaFileService, IHandleAsync<MoviesDeletedEvent>
{
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());
}
}
}

@ -10,6 +10,7 @@ namespace NzbDrone.Core.Movies.AlternativeTitles
AlternativeTitle FindBySourceId(int sourceId);
List<AlternativeTitle> FindBySourceIds(List<int> sourceIds);
List<AlternativeTitle> FindByMovieId(int movieId);
void DeleteForMovies(List<int> movieIds);
}
public class AlternativeTitleRepository : BasicRepository<AlternativeTitle>, IAlternativeTitleRepository
@ -33,5 +34,10 @@ namespace NzbDrone.Core.Movies.AlternativeTitles
{
return Query(x => x.MovieId == movieId);
}
public void DeleteForMovies(List<int> movieIds)
{
Delete(x => movieIds.Contains(x.MovieId));
}
}
}

@ -18,7 +18,7 @@ namespace NzbDrone.Core.Movies.AlternativeTitles
List<AlternativeTitle> UpdateTitles(List<AlternativeTitle> titles, Movie movie);
}
public class AlternativeTitleService : IAlternativeTitleService, IHandleAsync<MovieDeletedEvent>
public class AlternativeTitleService : IAlternativeTitleService, IHandleAsync<MoviesDeletedEvent>
{
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());
}
}
}

@ -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<Credit>
{
List<Credit> FindByMovieId(int movieId);
void DeleteForMovies(List<int> movieIds);
}
public class CreditRepository : BasicRepository<Credit>, ICreditRepository
@ -20,5 +21,10 @@ namespace NzbDrone.Core.Movies.Credits
{
return Query(x => x.MovieId == movieId);
}
public void DeleteForMovies(List<int> movieIds)
{
Delete(x => movieIds.Contains(x.MovieId));
}
}
}

@ -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<Credit> UpdateCredits(List<Credit> credits, Movie movie);
}
public class CreditService : ICreditService, IHandleAsync<MovieDeletedEvent>
public class CreditService : ICreditService, IHandleAsync<MoviesDeletedEvent>
{
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());
}
}
}

@ -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;
}
}
}

@ -0,0 +1,19 @@
using System.Collections.Generic;
using NzbDrone.Common.Messaging;
namespace NzbDrone.Core.Movies.Events
{
public class MoviesDeletedEvent : IEvent
{
public List<Movie> Movies { get; private set; }
public bool DeleteFiles { get; private set; }
public bool AddExclusion { get; private set; }
public MoviesDeletedEvent(List<Movie> movies, bool deleteFiles, bool addExclusion)
{
Movies = movies;
DeleteFiles = deleteFiles;
AddExclusion = addExclusion;
}
}
}

@ -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<Movie> MoviesWithoutFiles(PagingSpec<Movie> pagingSpec);
void SetFileId(Movie movie, MovieFile movieFile);
void DeleteMovie(int movieId, bool deleteFiles, bool addExclusion = false);
void DeleteMovies(List<int> movieIds, bool deleteFiles, bool addExclusion = false);
List<Movie> GetAllMovies();
List<Movie> 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> { movie }, deleteFiles, addExclusion));
_logger.Info("Deleted movie {0}", movie);
}
public void DeleteMovies(List<int> 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<Movie> GetAllMovies()

@ -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<ImportExclusion> 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<MoviesDeletedEvent>
{
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());
}
}
}
}

@ -94,10 +94,7 @@ namespace Radarr.Api.V3.Movies
{
var resource = Request.Body.FromJson<MovieEditorResource>();
foreach (var id in resource.MovieIds)
{
_movieService.DeleteMovie(id, resource.DeleteFiles, resource.AddNetImportExclusion);
}
_movieService.DeleteMovies(resource.MovieIds, resource.DeleteFiles, resource.AddNetImportExclusion);
return new object();
}

@ -25,7 +25,7 @@ namespace Radarr.Api.V3.Movies
IHandle<MovieFileDeletedEvent>,
IHandle<MovieUpdatedEvent>,
IHandle<MovieEditedEvent>,
IHandle<MovieDeletedEvent>,
IHandle<MoviesDeletedEvent>,
IHandle<MovieRenamedEvent>,
IHandle<MediaCoversUpdatedEvent>
{
@ -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)

Loading…
Cancel
Save