mirror of https://github.com/Sonarr/Sonarr
Merge pull request #654 from Sonarr/remove-pending
Fix: When removing pending items from the queue remove all releases for that episode
This commit is contained in:
commit
a78381db7d
|
@ -55,7 +55,7 @@ namespace NzbDrone.Api.Queue
|
||||||
|
|
||||||
if (pendingRelease != null)
|
if (pendingRelease != null)
|
||||||
{
|
{
|
||||||
_pendingReleaseService.RemovePendingQueueItem(id);
|
_pendingReleaseService.RemovePendingQueueItems(pendingRelease.Id);
|
||||||
|
|
||||||
return new object().AsResponse();
|
return new object().AsResponse();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Download.Pending;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class RemovePendingFixture : CoreTest<PendingReleaseService>
|
||||||
|
{
|
||||||
|
|
||||||
|
private List<PendingRelease> _pending;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_pending = new List<PendingRelease>();
|
||||||
|
|
||||||
|
Mocker.GetMock<IPendingReleaseRepository>()
|
||||||
|
.Setup(s => s.AllBySeriesId(It.IsAny<int>()))
|
||||||
|
.Returns(_pending);
|
||||||
|
|
||||||
|
Mocker.GetMock<IPendingReleaseRepository>()
|
||||||
|
.Setup(s => s.Get(It.IsAny<int>()))
|
||||||
|
.Returns<int>(r => _pending.Single(c => c.Id == r));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddPending(int id, int seasonNumber, int[] episodes)
|
||||||
|
{
|
||||||
|
_pending.Add(new PendingRelease
|
||||||
|
{
|
||||||
|
Id = id,
|
||||||
|
ParsedEpisodeInfo = new ParsedEpisodeInfo { SeasonNumber = seasonNumber, EpisodeNumbers = episodes }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_remove_same_release()
|
||||||
|
{
|
||||||
|
AddPending(id: 1, seasonNumber: 2, episodes: new[] { 3 });
|
||||||
|
|
||||||
|
Subject.RemovePendingQueueItems(1);
|
||||||
|
|
||||||
|
AssertRemoved(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_remove_multiple_releases_release()
|
||||||
|
{
|
||||||
|
AddPending(id: 1, seasonNumber: 2, episodes: new[] { 1 });
|
||||||
|
AddPending(id: 2, seasonNumber: 2, episodes: new[] { 2 });
|
||||||
|
AddPending(id: 3, seasonNumber: 2, episodes: new[] { 3 });
|
||||||
|
AddPending(id: 4, seasonNumber: 2, episodes: new[] { 3 });
|
||||||
|
|
||||||
|
Subject.RemovePendingQueueItems(3);
|
||||||
|
|
||||||
|
AssertRemoved(3, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_remove_diffrent_season()
|
||||||
|
{
|
||||||
|
AddPending(id: 1, seasonNumber: 2, episodes: new[] { 1 });
|
||||||
|
AddPending(id: 2, seasonNumber: 2, episodes: new[] { 1 });
|
||||||
|
AddPending(id: 3, seasonNumber: 3, episodes: new[] { 1 });
|
||||||
|
AddPending(id: 4, seasonNumber: 3, episodes: new[] { 1 });
|
||||||
|
|
||||||
|
Subject.RemovePendingQueueItems(1);
|
||||||
|
|
||||||
|
AssertRemoved(1, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_remove_diffrent_episodes()
|
||||||
|
{
|
||||||
|
AddPending(id: 1, seasonNumber: 2, episodes: new[] { 1 });
|
||||||
|
AddPending(id: 2, seasonNumber: 2, episodes: new[] { 1 });
|
||||||
|
AddPending(id: 3, seasonNumber: 2, episodes: new[] { 2 });
|
||||||
|
AddPending(id: 4, seasonNumber: 2, episodes: new[] { 3 });
|
||||||
|
|
||||||
|
Subject.RemovePendingQueueItems(1);
|
||||||
|
|
||||||
|
AssertRemoved(1, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_remove_multiepisodes()
|
||||||
|
{
|
||||||
|
AddPending(id: 1, seasonNumber: 2, episodes: new[] { 1 });
|
||||||
|
AddPending(id: 2, seasonNumber: 2, episodes: new[] { 1, 2 });
|
||||||
|
|
||||||
|
Subject.RemovePendingQueueItems(1);
|
||||||
|
|
||||||
|
AssertRemoved(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_not_remove_singleepisodes()
|
||||||
|
{
|
||||||
|
AddPending(id: 1, seasonNumber: 2, episodes: new[] { 1 });
|
||||||
|
AddPending(id: 2, seasonNumber: 2, episodes: new[] { 1, 2 });
|
||||||
|
|
||||||
|
Subject.RemovePendingQueueItems(2);
|
||||||
|
|
||||||
|
AssertRemoved(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void AssertRemoved(params int[] ids)
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IPendingReleaseRepository>().Verify(c => c.DeleteMany(It.Is<IEnumerable<int>>(s => s.SequenceEqual(ids))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -166,6 +166,7 @@
|
||||||
<Compile Include="Download\DownloadClientTests\UTorrentTests\UTorrentFixture.cs" />
|
<Compile Include="Download\DownloadClientTests\UTorrentTests\UTorrentFixture.cs" />
|
||||||
<Compile Include="Download\DownloadServiceFixture.cs" />
|
<Compile Include="Download\DownloadServiceFixture.cs" />
|
||||||
<Compile Include="Download\FailedDownloadServiceFixture.cs" />
|
<Compile Include="Download\FailedDownloadServiceFixture.cs" />
|
||||||
|
<Compile Include="Download\Pending\PendingReleaseServiceTests\RemovePendingFixture.cs" />
|
||||||
<Compile Include="Download\Pending\PendingReleaseServiceTests\RemoveRejectedFixture.cs" />
|
<Compile Include="Download\Pending\PendingReleaseServiceTests\RemoveRejectedFixture.cs" />
|
||||||
<Compile Include="Download\Pending\PendingReleaseServiceTests\RemoveGrabbedFixture.cs" />
|
<Compile Include="Download\Pending\PendingReleaseServiceTests\RemoveGrabbedFixture.cs" />
|
||||||
<Compile Include="Download\Pending\PendingReleaseServiceTests\AddFixture.cs" />
|
<Compile Include="Download\Pending\PendingReleaseServiceTests\AddFixture.cs" />
|
||||||
|
|
|
@ -21,12 +21,12 @@ namespace NzbDrone.Core.Download.Pending
|
||||||
public interface IPendingReleaseService
|
public interface IPendingReleaseService
|
||||||
{
|
{
|
||||||
void Add(DownloadDecision decision);
|
void Add(DownloadDecision decision);
|
||||||
|
|
||||||
List<ReleaseInfo> GetPending();
|
List<ReleaseInfo> GetPending();
|
||||||
List<RemoteEpisode> GetPendingRemoteEpisodes(int seriesId);
|
List<RemoteEpisode> GetPendingRemoteEpisodes(int seriesId);
|
||||||
List<Queue.Queue> GetPendingQueue();
|
List<Queue.Queue> GetPendingQueue();
|
||||||
Queue.Queue FindPendingQueueItem(int queueId);
|
Queue.Queue FindPendingQueueItem(int queueId);
|
||||||
void RemovePendingQueueItem(int queueId);
|
void RemovePendingQueueItems(int episodeId);
|
||||||
RemoteEpisode OldestPendingRelease(int seriesId, IEnumerable<int> episodeIds);
|
RemoteEpisode OldestPendingRelease(int seriesId, IEnumerable<int> episodeIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ namespace NzbDrone.Core.Download.Pending
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Add(DownloadDecision decision)
|
public void Add(DownloadDecision decision)
|
||||||
{
|
{
|
||||||
var alreadyPending = GetPendingReleases();
|
var alreadyPending = GetPendingReleases();
|
||||||
|
@ -74,7 +74,7 @@ namespace NzbDrone.Core.Download.Pending
|
||||||
.Intersect(episodeIds)
|
.Intersect(episodeIds)
|
||||||
.Any());
|
.Any());
|
||||||
|
|
||||||
if (existingReports.Any(MatchingReleasePredicate(decision)))
|
if (existingReports.Any(MatchingReleasePredicate(decision.RemoteEpisode.Release)))
|
||||||
{
|
{
|
||||||
_logger.Debug("This release is already pending, not adding again");
|
_logger.Debug("This release is already pending, not adding again");
|
||||||
return;
|
return;
|
||||||
|
@ -152,11 +152,17 @@ namespace NzbDrone.Core.Download.Pending
|
||||||
return GetPendingQueue().SingleOrDefault(p => p.Id == queueId);
|
return GetPendingQueue().SingleOrDefault(p => p.Id == queueId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemovePendingQueueItem(int queueId)
|
public void RemovePendingQueueItems(int queueId)
|
||||||
{
|
{
|
||||||
var id = FindPendingReleaseId(queueId);
|
var targetItem = _repository.Get(queueId);
|
||||||
|
var seriesReleases = _repository.AllBySeriesId(targetItem.SeriesId);
|
||||||
|
|
||||||
_repository.Delete(id);
|
|
||||||
|
var releasesToRemove = seriesReleases.Where(
|
||||||
|
c => c.ParsedEpisodeInfo.SeasonNumber == targetItem.ParsedEpisodeInfo.SeasonNumber &&
|
||||||
|
c.ParsedEpisodeInfo.EpisodeNumbers.SequenceEqual(targetItem.ParsedEpisodeInfo.EpisodeNumbers));
|
||||||
|
|
||||||
|
_repository.DeleteMany(releasesToRemove.Select(c => c.Id));
|
||||||
}
|
}
|
||||||
|
|
||||||
public RemoteEpisode OldestPendingRelease(int seriesId, IEnumerable<int> episodeIds)
|
public RemoteEpisode OldestPendingRelease(int seriesId, IEnumerable<int> episodeIds)
|
||||||
|
@ -223,11 +229,11 @@ namespace NzbDrone.Core.Download.Pending
|
||||||
_eventAggregator.PublishEvent(new PendingReleasesUpdatedEvent());
|
_eventAggregator.PublishEvent(new PendingReleasesUpdatedEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Func<PendingRelease, bool> MatchingReleasePredicate(DownloadDecision decision)
|
private static Func<PendingRelease, bool> MatchingReleasePredicate(ReleaseInfo release)
|
||||||
{
|
{
|
||||||
return p => p.Title == decision.RemoteEpisode.Release.Title &&
|
return p => p.Title == release.Title &&
|
||||||
p.Release.PublishDate == decision.RemoteEpisode.Release.PublishDate &&
|
p.Release.PublishDate == release.PublishDate &&
|
||||||
p.Release.Indexer == decision.RemoteEpisode.Release.Indexer;
|
p.Release.Indexer == release.Indexer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int GetDelay(RemoteEpisode remoteEpisode)
|
private int GetDelay(RemoteEpisode remoteEpisode)
|
||||||
|
@ -236,7 +242,7 @@ namespace NzbDrone.Core.Download.Pending
|
||||||
var delay = delayProfile.GetProtocolDelay(remoteEpisode.Release.DownloadProtocol);
|
var delay = delayProfile.GetProtocolDelay(remoteEpisode.Release.DownloadProtocol);
|
||||||
var minimumAge = _configService.MinimumAge;
|
var minimumAge = _configService.MinimumAge;
|
||||||
|
|
||||||
return new [] { delay, minimumAge }.Max();
|
return new[] { delay, minimumAge }.Max();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RemoveGrabbed(RemoteEpisode remoteEpisode)
|
private void RemoveGrabbed(RemoteEpisode remoteEpisode)
|
||||||
|
@ -278,7 +284,7 @@ namespace NzbDrone.Core.Download.Pending
|
||||||
|
|
||||||
foreach (var rejectedRelease in rejected)
|
foreach (var rejectedRelease in rejected)
|
||||||
{
|
{
|
||||||
var matching = pending.SingleOrDefault(MatchingReleasePredicate(rejectedRelease));
|
var matching = pending.SingleOrDefault(MatchingReleasePredicate(rejectedRelease.RemoteEpisode.Release));
|
||||||
|
|
||||||
if (matching != null)
|
if (matching != null)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue