New: Speed up mass deletes from Series Editor
* New: Speed up mass deletes from Series Editor * fixup! Additional speed up using GetAllSeriesPaths vs GetAllSeries * fixup! Tests
This commit is contained in:
parent
d08f33ae21
commit
356771d139
|
@ -1,12 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Blocklisting;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Test.Blocklisting
|
||||
{
|
||||
|
@ -14,6 +16,8 @@ namespace NzbDrone.Core.Test.Blocklisting
|
|||
public class BlocklistRepositoryFixture : DbTest<BlocklistRepository, Blocklist>
|
||||
{
|
||||
private Blocklist _blocklist;
|
||||
private Series _series1;
|
||||
private Series _series2;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
|
@ -27,6 +31,14 @@ namespace NzbDrone.Core.Test.Blocklisting
|
|||
SourceTitle = "series.title.s01e01",
|
||||
Date = DateTime.UtcNow
|
||||
};
|
||||
|
||||
_series1 = Builder<Series>.CreateNew()
|
||||
.With(s => s.Id = 7)
|
||||
.Build();
|
||||
|
||||
_series2 = Builder<Series>.CreateNew()
|
||||
.With(s => s.Id = 8)
|
||||
.Build();
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -51,5 +63,30 @@ namespace NzbDrone.Core.Test.Blocklisting
|
|||
|
||||
Subject.BlocklistedByTitle(_blocklist.SeriesId, _blocklist.SourceTitle.ToUpperInvariant()).Should().HaveCount(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_delete_blocklists_by_seriesId()
|
||||
{
|
||||
var blocklistItems = Builder<Blocklist>.CreateListOfSize(5)
|
||||
.TheFirst(1)
|
||||
.With(c => c.SeriesId = _series2.Id)
|
||||
.TheRest()
|
||||
.With(c => c.SeriesId = _series1.Id)
|
||||
.All()
|
||||
.With(c => c.Quality = new QualityModel())
|
||||
.With(c => c.Languages = new List<Language>())
|
||||
.With(c => c.EpisodeIds = new List<int> { 1 })
|
||||
.BuildListOfNew();
|
||||
|
||||
Db.InsertMany(blocklistItems);
|
||||
|
||||
Subject.DeleteForSeriesIds(new List<int> { _series1.Id });
|
||||
|
||||
var removedSeriesBlocklists = Subject.BlocklistedBySeries(_series1.Id);
|
||||
var nonRemovedSeriesBlocklists = Subject.BlocklistedBySeries(_series2.Id);
|
||||
|
||||
removedSeriesBlocklists.Should().HaveCount(0);
|
||||
nonRemovedSeriesBlocklists.Should().HaveCount(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Download.History;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Test.Download.DownloadHistoryTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class DownloadHistoryRepositoryFixture : DbTest<DownloadHistoryRepository, DownloadHistory>
|
||||
{
|
||||
private Series _series1;
|
||||
private Series _series2;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_series1 = Builder<Series>.CreateNew()
|
||||
.With(s => s.Id = 7)
|
||||
.Build();
|
||||
|
||||
_series2 = Builder<Series>.CreateNew()
|
||||
.With(s => s.Id = 8)
|
||||
.Build();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_delete_history_items_by_seriesId()
|
||||
{
|
||||
var items = Builder<DownloadHistory>.CreateListOfSize(5)
|
||||
.TheFirst(1)
|
||||
.With(c => c.Id = 0)
|
||||
.With(c => c.SeriesId = _series2.Id)
|
||||
.TheRest()
|
||||
.With(c => c.Id = 0)
|
||||
.With(c => c.SeriesId = _series1.Id)
|
||||
.BuildListOfNew();
|
||||
|
||||
Db.InsertMany(items);
|
||||
|
||||
Subject.DeleteBySeriesIds(new List<int> { _series1.Id });
|
||||
|
||||
var removedItems = Subject.All().Where(h => h.SeriesId == _series1.Id);
|
||||
var nonRemovedItems = Subject.All().Where(h => h.SeriesId == _series2.Id);
|
||||
|
||||
removedItems.Should().HaveCount(0);
|
||||
nonRemovedItems.Should().HaveCount(1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
|
@ -320,7 +320,7 @@ namespace NzbDrone.Core.Test.Download.TrackedDownloads
|
|||
.Setup(s => s.Map(It.IsAny<ParsedEpisodeInfo>(), It.IsAny<int>(), It.IsAny<int>(), null))
|
||||
.Returns(default(RemoteEpisode));
|
||||
|
||||
Subject.Handle(new SeriesDeletedEvent(remoteEpisode.Series, true, true));
|
||||
Subject.Handle(new SeriesDeletedEvent(new List<Series> { remoteEpisode.Series }, true, true));
|
||||
|
||||
var trackedDownloads = Subject.GetTrackedDownloads();
|
||||
trackedDownloads.Should().HaveCount(1);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
|
@ -6,12 +7,28 @@ using NzbDrone.Core.History;
|
|||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Test.HistoryTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class HistoryRepositoryFixture : DbTest<HistoryRepository, EpisodeHistory>
|
||||
{
|
||||
private Series _series1;
|
||||
private Series _series2;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_series1 = Builder<Series>.CreateNew()
|
||||
.With(s => s.Id = 7)
|
||||
.Build();
|
||||
|
||||
_series2 = Builder<Series>.CreateNew()
|
||||
.With(s => s.Id = 8)
|
||||
.Build();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_read_write_dictionary()
|
||||
{
|
||||
|
@ -52,5 +69,32 @@ namespace NzbDrone.Core.Test.HistoryTests
|
|||
|
||||
downloadHistory.Should().HaveCount(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_delete_history_items_by_seriesId()
|
||||
{
|
||||
var items = Builder<EpisodeHistory>.CreateListOfSize(5)
|
||||
.TheFirst(1)
|
||||
.With(c => c.SeriesId = _series2.Id)
|
||||
.TheRest()
|
||||
.With(c => c.SeriesId = _series1.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 = EpisodeHistoryEventType.Grabbed)
|
||||
.BuildListOfNew();
|
||||
|
||||
Db.InsertMany(items);
|
||||
|
||||
Subject.DeleteForSeries(new List<int> { _series1.Id });
|
||||
|
||||
var dbItems = Subject.All();
|
||||
var removedItems = dbItems.Where(h => h.SeriesId == _series1.Id);
|
||||
var nonRemovedItems = dbItems.Where(h => h.SeriesId == _series2.Id);
|
||||
|
||||
removedItems.Should().HaveCount(0);
|
||||
nonRemovedItems.Should().HaveCount(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,12 +6,28 @@ using NzbDrone.Core.Languages;
|
|||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Test.MediaFiles
|
||||
{
|
||||
[TestFixture]
|
||||
public class MediaFileRepositoryFixture : DbTest<MediaFileRepository, EpisodeFile>
|
||||
{
|
||||
private Series _series1;
|
||||
private Series _series2;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_series1 = Builder<Series>.CreateNew()
|
||||
.With(s => s.Id = 7)
|
||||
.Build();
|
||||
|
||||
_series2 = Builder<Series>.CreateNew()
|
||||
.With(s => s.Id = 8)
|
||||
.Build();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void get_files_by_series()
|
||||
{
|
||||
|
@ -31,5 +47,30 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||
seriesFiles.Should().HaveCount(4);
|
||||
seriesFiles.Should().OnlyContain(c => c.SeriesId == 12);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_delete_files_by_seriesId()
|
||||
{
|
||||
var items = Builder<EpisodeFile>.CreateListOfSize(5)
|
||||
.TheFirst(1)
|
||||
.With(c => c.SeriesId = _series2.Id)
|
||||
.TheRest()
|
||||
.With(c => c.SeriesId = _series1.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.DeleteForSeries(new List<int> { _series1.Id });
|
||||
|
||||
var removedItems = Subject.GetFilesBySeries(_series1.Id);
|
||||
var nonRemovedItems = Subject.GetFilesBySeries(_series2.Id);
|
||||
|
||||
removedItems.Should().HaveCount(0);
|
||||
nonRemovedItems.Should().HaveCount(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace NzbDrone.Core.Blocklisting
|
|||
List<Blocklist> BlocklistedByTitle(int seriesId, string sourceTitle);
|
||||
List<Blocklist> BlocklistedByTorrentInfoHash(int seriesId, string torrentInfoHash);
|
||||
List<Blocklist> BlocklistedBySeries(int seriesId);
|
||||
void DeleteForSeriesIds(List<int> seriesIds);
|
||||
}
|
||||
|
||||
public class BlocklistRepository : BasicRepository<Blocklist>, IBlocklistRepository
|
||||
|
@ -34,6 +35,11 @@ namespace NzbDrone.Core.Blocklisting
|
|||
return Query(b => b.SeriesId == seriesId);
|
||||
}
|
||||
|
||||
public void DeleteForSeriesIds(List<int> seriesIds)
|
||||
{
|
||||
Delete(x => seriesIds.Contains(x.SeriesId));
|
||||
}
|
||||
|
||||
protected override SqlBuilder PagedBuilder() => new SqlBuilder().Join<Blocklist, Series>((b, m) => b.SeriesId == m.Id);
|
||||
protected override IEnumerable<Blocklist> PagedQuery(SqlBuilder sql) => _database.QueryJoined<Blocklist, Series>(sql, (bl, movie) =>
|
||||
{
|
||||
|
|
|
@ -189,9 +189,7 @@ namespace NzbDrone.Core.Blocklisting
|
|||
|
||||
public void HandleAsync(SeriesDeletedEvent message)
|
||||
{
|
||||
var blocklisted = _blocklistRepository.BlocklistedBySeries(message.Series.Id);
|
||||
|
||||
_blocklistRepository.DeleteMany(blocklisted);
|
||||
_blocklistRepository.DeleteForSeriesIds(message.Series.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 DeleteBySeriesId(int seriesId);
|
||||
void DeleteBySeriesIds(List<int> seriesIds);
|
||||
}
|
||||
|
||||
public class DownloadHistoryRepository : BasicRepository<DownloadHistory>, IDownloadHistoryRepository
|
||||
|
@ -23,9 +23,9 @@ namespace NzbDrone.Core.Download.History
|
|||
return Query(h => h.DownloadId == downloadId).OrderByDescending(h => h.Date).ToList();
|
||||
}
|
||||
|
||||
public void DeleteBySeriesId(int seriesId)
|
||||
public void DeleteBySeriesIds(List<int> seriesIds)
|
||||
{
|
||||
Delete(r => r.SeriesId == seriesId);
|
||||
Delete(r => seriesIds.Contains(r.SeriesId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -230,7 +230,7 @@ namespace NzbDrone.Core.Download.History
|
|||
|
||||
public void Handle(SeriesDeletedEvent message)
|
||||
{
|
||||
_repository.DeleteBySeriesId(message.Series.Id);
|
||||
_repository.DeleteBySeriesIds(message.Series.Select(m => m.Id).ToList());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace NzbDrone.Core.Download.Pending
|
|||
{
|
||||
public interface IPendingReleaseRepository : IBasicRepository<PendingRelease>
|
||||
{
|
||||
void DeleteBySeriesId(int seriesId);
|
||||
void DeleteBySeriesIds(List<int> seriesIds);
|
||||
List<PendingRelease> AllBySeriesId(int seriesId);
|
||||
List<PendingRelease> WithoutFallback();
|
||||
}
|
||||
|
@ -18,9 +18,9 @@ namespace NzbDrone.Core.Download.Pending
|
|||
{
|
||||
}
|
||||
|
||||
public void DeleteBySeriesId(int seriesId)
|
||||
public void DeleteBySeriesIds(List<int> seriesIds)
|
||||
{
|
||||
Delete(r => r.SeriesId == seriesId);
|
||||
Delete(r => seriesIds.Contains(r.SeriesId));
|
||||
}
|
||||
|
||||
public List<PendingRelease> AllBySeriesId(int seriesId)
|
||||
|
|
|
@ -451,7 +451,7 @@ namespace NzbDrone.Core.Download.Pending
|
|||
|
||||
public void Handle(SeriesDeletedEvent message)
|
||||
{
|
||||
_repository.DeleteBySeriesId(message.Series.Id);
|
||||
_repository.DeleteBySeriesIds(message.Series.Select(m => m.Id).ToList());
|
||||
}
|
||||
|
||||
public void Handle(EpisodeGrabbedEvent message)
|
||||
|
|
|
@ -260,7 +260,7 @@ namespace NzbDrone.Core.Download.TrackedDownloads
|
|||
{
|
||||
var cachedItems = _cache.Values.Where(t =>
|
||||
t.RemoteEpisode?.Series != null &&
|
||||
t.RemoteEpisode.Series.Id == message.Series.Id)
|
||||
message.Series.Any(s => s.Id == t.RemoteEpisode.Series.Id))
|
||||
.ToList();
|
||||
|
||||
if (cachedItems.Any())
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace NzbDrone.Core.Extras.Files
|
|||
public interface IExtraFileRepository<TExtraFile> : IBasicRepository<TExtraFile>
|
||||
where TExtraFile : ExtraFile, new()
|
||||
{
|
||||
void DeleteForSeries(int seriesId);
|
||||
void DeleteForSeriesIds(List<int> seriesIds);
|
||||
void DeleteForSeason(int seriesId, int seasonNumber);
|
||||
void DeleteForEpisodeFile(int episodeFileId);
|
||||
List<TExtraFile> GetFilesBySeries(int seriesId);
|
||||
|
@ -25,9 +25,9 @@ namespace NzbDrone.Core.Extras.Files
|
|||
{
|
||||
}
|
||||
|
||||
public void DeleteForSeries(int seriesId)
|
||||
public void DeleteForSeriesIds(List<int> seriesIds)
|
||||
{
|
||||
Delete(c => c.SeriesId == seriesId);
|
||||
Delete(c => seriesIds.Contains(c.SeriesId));
|
||||
}
|
||||
|
||||
public void DeleteForSeason(int seriesId, int seasonNumber)
|
||||
|
|
|
@ -97,8 +97,8 @@ namespace NzbDrone.Core.Extras.Files
|
|||
|
||||
public void HandleAsync(SeriesDeletedEvent message)
|
||||
{
|
||||
_logger.Debug("Deleting Extra from database for series: {0}", message.Series);
|
||||
_repository.DeleteForSeries(message.Series.Id);
|
||||
_logger.Debug("Deleting Extra from database for series: {0}", string.Join(',', message.Series));
|
||||
_repository.DeleteForSeriesIds(message.Series.Select(m => m.Id).ToList());
|
||||
}
|
||||
|
||||
public void Handle(EpisodeFileDeletedEvent message)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System.Linq;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
@ -41,7 +41,7 @@ namespace NzbDrone.Core.HealthCheck.Checks
|
|||
|
||||
public bool ShouldCheckOnEvent(SeriesDeletedEvent deletedEvent)
|
||||
{
|
||||
return deletedEvent.Series.Status == SeriesStatusType.Deleted;
|
||||
return deletedEvent.Series.Any(s => s.Status == SeriesStatusType.Deleted);
|
||||
}
|
||||
|
||||
public bool ShouldCheckOnEvent(SeriesUpdatedEvent updatedEvent)
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace NzbDrone.Core.History
|
|||
List<EpisodeHistory> GetBySeries(int seriesId, EpisodeHistoryEventType? eventType);
|
||||
List<EpisodeHistory> GetBySeason(int seriesId, int seasonNumber, EpisodeHistoryEventType? eventType);
|
||||
List<EpisodeHistory> FindDownloadHistory(int idSeriesId, QualityModel quality);
|
||||
void DeleteForSeries(int seriesId);
|
||||
void DeleteForSeries(List<int> seriesIds);
|
||||
List<EpisodeHistory> Since(DateTime date, EpisodeHistoryEventType? eventType);
|
||||
}
|
||||
|
||||
|
@ -100,9 +100,9 @@ namespace NzbDrone.Core.History
|
|||
.ToList();
|
||||
}
|
||||
|
||||
public void DeleteForSeries(int seriesId)
|
||||
public void DeleteForSeries(List<int> seriesIds)
|
||||
{
|
||||
Delete(c => c.SeriesId == seriesId);
|
||||
Delete(c => seriesIds.Contains(c.SeriesId));
|
||||
}
|
||||
|
||||
protected override SqlBuilder PagedBuilder() => new SqlBuilder()
|
||||
|
|
|
@ -343,7 +343,7 @@ namespace NzbDrone.Core.History
|
|||
|
||||
public void Handle(SeriesDeletedEvent message)
|
||||
{
|
||||
_historyRepository.DeleteForSeries(message.Series.Id);
|
||||
_historyRepository.DeleteForSeries(message.Series.Select(m => m.Id).ToList());
|
||||
}
|
||||
|
||||
public List<EpisodeHistory> Since(DateTime date, EpisodeHistoryEventType? eventType)
|
||||
|
|
|
@ -61,20 +61,25 @@ namespace NzbDrone.Core.ImportLists.Exclusions
|
|||
return;
|
||||
}
|
||||
|
||||
var existingExclusion = _repo.FindByTvdbId(message.Series.TvdbId);
|
||||
var exclusionsToAdd = new List<ImportListExclusion>();
|
||||
|
||||
if (existingExclusion != null)
|
||||
foreach (var series in message.Series.DistinctBy(s => s.TvdbId))
|
||||
{
|
||||
return;
|
||||
var existingExclusion = _repo.FindByTvdbId(series.TvdbId);
|
||||
|
||||
if (existingExclusion != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
exclusionsToAdd.Add(new ImportListExclusion
|
||||
{
|
||||
TvdbId = series.TvdbId,
|
||||
Title = series.Title
|
||||
});
|
||||
}
|
||||
|
||||
var importExclusion = new ImportListExclusion
|
||||
{
|
||||
TvdbId = message.Series.TvdbId,
|
||||
Title = message.Series.Title
|
||||
};
|
||||
|
||||
_repo.Insert(importExclusion);
|
||||
_repo.InsertMany(exclusionsToAdd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
|
@ -217,10 +217,13 @@ namespace NzbDrone.Core.MediaCover
|
|||
|
||||
public void HandleAsync(SeriesDeletedEvent message)
|
||||
{
|
||||
var path = GetSeriesCoverPath(message.Series.Id);
|
||||
if (_diskProvider.FolderExists(path))
|
||||
foreach (var series in message.Series)
|
||||
{
|
||||
_diskProvider.DeleteFolder(path, true);
|
||||
var path = GetSeriesCoverPath(series.Id);
|
||||
if (_diskProvider.FolderExists(path))
|
||||
{
|
||||
_diskProvider.DeleteFolder(path, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,35 +92,37 @@ namespace NzbDrone.Core.MediaFiles
|
|||
{
|
||||
if (message.DeleteFiles)
|
||||
{
|
||||
var series = message.Series;
|
||||
var allSeries = _seriesService.GetAllSeries();
|
||||
var allSeries = _seriesService.GetAllSeriesPaths();
|
||||
|
||||
foreach (var s in allSeries)
|
||||
foreach (var series in message.Series)
|
||||
{
|
||||
if (s.Id == series.Id)
|
||||
foreach (var s in allSeries)
|
||||
{
|
||||
continue;
|
||||
if (s.Key == series.Id)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (series.Path.IsParentPath(s.Value))
|
||||
{
|
||||
_logger.Error("Series path: '{0}' is a parent of another series, not deleting files.", series.Path);
|
||||
return;
|
||||
}
|
||||
|
||||
if (series.Path.PathEquals(s.Value))
|
||||
{
|
||||
_logger.Error("Series path: '{0}' is the same as another series, not deleting files.", series.Path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (series.Path.IsParentPath(s.Path))
|
||||
if (_diskProvider.FolderExists(series.Path))
|
||||
{
|
||||
_logger.Error("Series path: '{0}' is a parent of another series, not deleting files.", series.Path);
|
||||
return;
|
||||
_recycleBinProvider.DeleteFolder(series.Path);
|
||||
}
|
||||
|
||||
if (series.Path.PathEquals(s.Path))
|
||||
{
|
||||
_logger.Error("Series path: '{0}' is the same as another series, not deleting files.", series.Path);
|
||||
return;
|
||||
}
|
||||
_eventAggregator.PublishEvent(new DeleteCompletedEvent());
|
||||
}
|
||||
|
||||
if (_diskProvider.FolderExists(message.Series.Path))
|
||||
{
|
||||
_recycleBinProvider.DeleteFolder(message.Series.Path);
|
||||
}
|
||||
|
||||
_eventAggregator.PublishEvent(new DeleteCompletedEvent());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace NzbDrone.Core.MediaFiles
|
|||
List<EpisodeFile> GetFilesBySeason(int seriesId, int seasonNumber);
|
||||
List<EpisodeFile> GetFilesWithoutMediaInfo();
|
||||
List<EpisodeFile> GetFilesWithRelativePath(int seriesId, string relativePath);
|
||||
void DeleteForSeries(List<int> seriesIds);
|
||||
}
|
||||
|
||||
public class MediaFileRepository : BasicRepository<EpisodeFile>, IMediaFileRepository
|
||||
|
@ -40,5 +41,10 @@ namespace NzbDrone.Core.MediaFiles
|
|||
return Query(c => c.SeriesId == seriesId && c.RelativePath == relativePath)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public void DeleteForSeries(List<int> seriesIds)
|
||||
{
|
||||
Delete(x => seriesIds.Contains(x.SeriesId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,8 +110,7 @@ namespace NzbDrone.Core.MediaFiles
|
|||
|
||||
public void HandleAsync(SeriesDeletedEvent message)
|
||||
{
|
||||
var files = GetFilesBySeries(message.Series.Id);
|
||||
_mediaFileRepository.DeleteMany(files);
|
||||
_mediaFileRepository.DeleteForSeries(message.Series.Select(s => s.Id).ToList());
|
||||
}
|
||||
|
||||
public static List<string> FilterExistingFiles(List<string> files, List<EpisodeFile> seriesFiles, Series series)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
|
@ -252,20 +252,23 @@ namespace NzbDrone.Core.Notifications
|
|||
|
||||
public void Handle(SeriesDeletedEvent message)
|
||||
{
|
||||
var deleteMessage = new SeriesDeleteMessage(message.Series, message.DeleteFiles);
|
||||
|
||||
foreach (var notification in _notificationFactory.OnSeriesDeleteEnabled())
|
||||
foreach (var series in message.Series)
|
||||
{
|
||||
try
|
||||
var deleteMessage = new SeriesDeleteMessage(series, message.DeleteFiles);
|
||||
|
||||
foreach (var notification in _notificationFactory.OnSeriesDeleteEnabled())
|
||||
{
|
||||
if (ShouldHandleSeries(notification.Definition, deleteMessage.Series))
|
||||
try
|
||||
{
|
||||
notification.OnSeriesDelete(deleteMessage);
|
||||
if (ShouldHandleSeries(notification.Definition, deleteMessage.Series))
|
||||
{
|
||||
notification.OnSeriesDelete(deleteMessage);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warn(ex, "Unable to send OnDelete notification to: " + notification.Definition.Name);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warn(ex, "Unable to send OnDelete notification to: " + notification.Definition.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace NzbDrone.Core.Tv
|
|||
List<Episode> Find(int seriesId, string date);
|
||||
List<Episode> GetEpisodes(int seriesId);
|
||||
List<Episode> GetEpisodes(int seriesId, int seasonNumber);
|
||||
List<Episode> GetEpisodesBySeriesIds(List<int> seriesIds);
|
||||
List<Episode> GetEpisodesBySceneSeason(int seriesId, int sceneSeasonNumber);
|
||||
List<Episode> GetEpisodeByFileId(int fileId);
|
||||
List<Episode> EpisodesWithFiles(int seriesId);
|
||||
|
@ -77,6 +78,11 @@ namespace NzbDrone.Core.Tv
|
|||
return Query(s => s.SeriesId == seriesId && s.SeasonNumber == seasonNumber).ToList();
|
||||
}
|
||||
|
||||
public List<Episode> GetEpisodesBySeriesIds(List<int> seriesIds)
|
||||
{
|
||||
return Query(s => seriesIds.Contains(s.SeriesId)).ToList();
|
||||
}
|
||||
|
||||
public List<Episode> GetEpisodesBySceneSeason(int seriesId, int seasonNumber)
|
||||
{
|
||||
return Query(s => s.SeriesId == seriesId && s.SceneSeasonNumber == seasonNumber).ToList();
|
||||
|
|
|
@ -211,7 +211,7 @@ namespace NzbDrone.Core.Tv
|
|||
|
||||
public void HandleAsync(SeriesDeletedEvent message)
|
||||
{
|
||||
var episodes = GetEpisodeBySeries(message.Series.Id);
|
||||
var episodes = _episodeRepository.GetEpisodesBySeriesIds(message.Series.Select(s => s.Id).ToList());
|
||||
_episodeRepository.DeleteMany(episodes);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
using NzbDrone.Common.Messaging;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Common.Messaging;
|
||||
|
||||
namespace NzbDrone.Core.Tv.Events
|
||||
{
|
||||
public class SeriesDeletedEvent : IEvent
|
||||
{
|
||||
public Series Series { get; private set; }
|
||||
public List<Series> Series { get; private set; }
|
||||
public bool DeleteFiles { get; private set; }
|
||||
public bool AddImportListExclusion { get; private set; }
|
||||
|
||||
public SeriesDeletedEvent(Series series, bool deleteFiles, bool addImportListExclusion)
|
||||
public SeriesDeletedEvent(List<Series> series, bool deleteFiles, bool addImportListExclusion)
|
||||
{
|
||||
Series = series;
|
||||
DeleteFiles = deleteFiles;
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace NzbDrone.Core.Tv
|
|||
Series FindByTitle(string title, int year);
|
||||
Series FindByTitleInexact(string title);
|
||||
Series FindByPath(string path);
|
||||
void DeleteSeries(int seriesId, bool deleteFiles, bool addImportListExclusion);
|
||||
void DeleteSeries(List<int> seriesIds, bool deleteFiles, bool addImportListExclusion);
|
||||
List<Series> GetAllSeries();
|
||||
List<int> AllSeriesTvdbIds();
|
||||
Dictionary<int, string> GetAllSeriesPaths();
|
||||
|
@ -149,10 +149,10 @@ namespace NzbDrone.Core.Tv
|
|||
return _seriesRepository.FindByTitle(title.CleanSeriesTitle(), year);
|
||||
}
|
||||
|
||||
public void DeleteSeries(int seriesId, bool deleteFiles, bool addImportListExclusion)
|
||||
public void DeleteSeries(List<int> seriesIds, bool deleteFiles, bool addImportListExclusion)
|
||||
{
|
||||
var series = _seriesRepository.Get(seriesId);
|
||||
_seriesRepository.Delete(seriesId);
|
||||
var series = _seriesRepository.Get(seriesIds).ToList();
|
||||
_seriesRepository.DeleteMany(seriesIds);
|
||||
_eventAggregator.PublishEvent(new SeriesDeletedEvent(series, deleteFiles, addImportListExclusion));
|
||||
}
|
||||
|
||||
|
|
|
@ -172,7 +172,7 @@ namespace Sonarr.Api.V3.Series
|
|||
var deleteFiles = Request.GetBooleanQueryParameter("deleteFiles");
|
||||
var addImportListExclusion = Request.GetBooleanQueryParameter("addImportListExclusion");
|
||||
|
||||
_seriesService.DeleteSeries(id, deleteFiles, addImportListExclusion);
|
||||
_seriesService.DeleteSeries(new List<int> { id }, deleteFiles, addImportListExclusion);
|
||||
}
|
||||
|
||||
private SeriesResource GetSeriesResource(NzbDrone.Core.Tv.Series series, bool includeSeasonImages)
|
||||
|
@ -292,7 +292,10 @@ namespace Sonarr.Api.V3.Series
|
|||
[NonAction]
|
||||
public void Handle(SeriesDeletedEvent message)
|
||||
{
|
||||
BroadcastResourceChange(ModelAction.Deleted, message.Series.ToResource());
|
||||
foreach (var series in message.Series)
|
||||
{
|
||||
BroadcastResourceChange(ModelAction.Deleted, series.ToResource());
|
||||
}
|
||||
}
|
||||
|
||||
[NonAction]
|
||||
|
|
|
@ -94,10 +94,7 @@ namespace Sonarr.Api.V3.Series
|
|||
[HttpDelete]
|
||||
public object DeleteSeries([FromBody] SeriesEditorResource resource)
|
||||
{
|
||||
foreach (var seriesId in resource.SeriesIds)
|
||||
{
|
||||
_seriesService.DeleteSeries(seriesId, resource.DeleteFiles, resource.AddImportListExclusion);
|
||||
}
|
||||
_seriesService.DeleteSeries(resource.SeriesIds, resource.DeleteFiles, resource.AddImportListExclusion);
|
||||
|
||||
return new { };
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue