From 6d46819972212fba0878509019ad965a8e10568b Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Tue, 8 Oct 2013 23:58:29 -0700 Subject: [PATCH] Download client will return queue with remoteEpsiode Fixed: In Queue check is more accurate --- .../NotInQueueSpecificationFixture.cs | 88 ++++++++++++++----- .../Specifications/NotInQueueSpecification.cs | 17 ++-- .../Download/Clients/Nzbget/NzbgetClient.cs | 13 ++- .../Download/Clients/Sabnzbd/SabnzbdClient.cs | 17 +++- src/NzbDrone.Core/Download/IDownloadClient.cs | 1 - src/NzbDrone.Core/Download/QueueItem.cs | 2 + src/NzbDrone.Core/Queue/QueueService.cs | 40 +++------ 7 files changed, 114 insertions(+), 64 deletions(-) diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/NotInQueueSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/NotInQueueSpecificationFixture.cs index e9e9fb959..1ca3e9c41 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/NotInQueueSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/NotInQueueSpecificationFixture.cs @@ -1,9 +1,10 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using FizzWare.NBuilder; using FluentAssertions; +using Moq; using NUnit.Framework; using NzbDrone.Core.DecisionEngine.Specifications; +using NzbDrone.Core.Download; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Qualities; using NzbDrone.Core.Tv; @@ -17,6 +18,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests private Series _series; private Episode _episode; private RemoteEpisode _remoteEpisode; + private Mock _downloadClient; private Series _otherSeries; private Episode _otherEpisode; @@ -46,27 +48,60 @@ namespace NzbDrone.Core.Test.DecisionEngineTests .With(r => r.Episodes = new List { _episode }) .With(r => r.ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.DVD)}) .Build(); + + _downloadClient = Mocker.GetMock(); + + Mocker.GetMock() + .Setup(s => s.GetDownloadClient()) + .Returns(_downloadClient.Object); + + _downloadClient.SetupGet(s => s.IsConfigured) + .Returns(true); + } + + private void GivenEmptyQueue() + { + _downloadClient.Setup(s => s.GetQueue()) + .Returns(new List()); + } + + private void GivenQueue(IEnumerable remoteEpisodes) + { + var queue = new List(); + + foreach (var remoteEpisode in remoteEpisodes) + { + queue.Add(new QueueItem + { + RemoteEpisode = remoteEpisode + }); + } + + _downloadClient.Setup(s => s.GetQueue()) + .Returns(queue); } [Test] - public void should_return_false_when_queue_is_empty() + public void should_return_true_when_queue_is_empty() { - Subject.IsInQueue(_remoteEpisode, new List()).Should().BeFalse(); + GivenEmptyQueue(); + Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); } [Test] - public void should_return_false_when_series_doesnt_match() + public void should_return_true_when_series_doesnt_match() { var remoteEpisode = Builder.CreateNew() .With(r => r.Series = _otherSeries) .With(r => r.Episodes = new List { _episode }) .Build(); - Subject.IsInQueue(_remoteEpisode, new List { remoteEpisode }).Should().BeFalse(); + GivenQueue(new List { remoteEpisode }); + Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); } [Test] - public void should_return_false_when_quality_in_queue_is_lower() + public void should_return_true_when_quality_in_queue_is_lower() { var remoteEpisode = Builder.CreateNew() .With(r => r.Series = _series) @@ -77,11 +112,12 @@ namespace NzbDrone.Core.Test.DecisionEngineTests }) .Build(); - Subject.IsInQueue(_remoteEpisode, new List { remoteEpisode }).Should().BeFalse(); + GivenQueue(new List { remoteEpisode }); + Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); } [Test] - public void should_return_false_when_episode_doesnt_match() + public void should_return_true_when_episode_doesnt_match() { var remoteEpisode = Builder.CreateNew() .With(r => r.Series = _series) @@ -92,11 +128,12 @@ namespace NzbDrone.Core.Test.DecisionEngineTests }) .Build(); - Subject.IsInQueue(_remoteEpisode, new List { remoteEpisode }).Should().BeFalse(); + GivenQueue(new List { remoteEpisode }); + Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeTrue(); } [Test] - public void should_return_true_when_qualities_are_the_same() + public void should_return_false_when_qualities_are_the_same() { var remoteEpisode = Builder.CreateNew() .With(r => r.Series = _series) @@ -107,11 +144,12 @@ namespace NzbDrone.Core.Test.DecisionEngineTests }) .Build(); - Subject.IsInQueue(_remoteEpisode, new List { remoteEpisode }).Should().BeTrue(); + GivenQueue(new List { remoteEpisode }); + Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse(); } [Test] - public void should_return_true_when_quality_in_queue_is_better() + public void should_return_false_when_quality_in_queue_is_better() { var remoteEpisode = Builder.CreateNew() .With(r => r.Series = _series) @@ -122,11 +160,12 @@ namespace NzbDrone.Core.Test.DecisionEngineTests }) .Build(); - Subject.IsInQueue(_remoteEpisode, new List { remoteEpisode }).Should().BeTrue(); + GivenQueue(new List { remoteEpisode }); + Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse(); } [Test] - public void should_return_true_if_matching_multi_episode_is_in_queue() + public void should_return_false_if_matching_multi_episode_is_in_queue() { var remoteEpisode = Builder.CreateNew() .With(r => r.Series = _series) @@ -137,11 +176,12 @@ namespace NzbDrone.Core.Test.DecisionEngineTests }) .Build(); - Subject.IsInQueue(_remoteEpisode, new List { remoteEpisode }).Should().BeTrue(); + GivenQueue(new List { remoteEpisode }); + Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse(); } [Test] - public void should_return_true_if_multi_episode_has_one_episode_in_queue() + public void should_return_false_if_multi_episode_has_one_episode_in_queue() { var remoteEpisode = Builder.CreateNew() .With(r => r.Series = _series) @@ -154,11 +194,12 @@ namespace NzbDrone.Core.Test.DecisionEngineTests _remoteEpisode.Episodes.Add(_otherEpisode); - Subject.IsInQueue(_remoteEpisode, new List { remoteEpisode }).Should().BeTrue(); + GivenQueue(new List { remoteEpisode }); + Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse(); } [Test] - public void should_return_true_if_multi_part_episode_is_already_in_queue() + public void should_return_false_if_multi_part_episode_is_already_in_queue() { var remoteEpisode = Builder.CreateNew() .With(r => r.Series = _series) @@ -171,11 +212,12 @@ namespace NzbDrone.Core.Test.DecisionEngineTests _remoteEpisode.Episodes.Add(_otherEpisode); - Subject.IsInQueue(_remoteEpisode, new List { remoteEpisode }).Should().BeTrue(); + GivenQueue(new List { remoteEpisode }); + Subject.IsSatisfiedBy(_remoteEpisode, null).Should().BeFalse(); } [Test] - public void should_return_true_if_multi_part_episode_has_two_episodes_in_queue() + public void should_return_false_if_multi_part_episode_has_two_episodes_in_queue() { var remoteEpisodes = Builder.CreateListOfSize(2) .All() @@ -193,8 +235,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests .Build(); _remoteEpisode.Episodes.Add(_otherEpisode); - - Subject.IsInQueue(_remoteEpisode, remoteEpisodes ).Should().BeTrue(); + GivenQueue(remoteEpisodes); + Subject.IsSatisfiedBy(_remoteEpisode, null ).Should().BeFalse(); } } } \ No newline at end of file diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/NotInQueueSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/NotInQueueSpecification.cs index 8b72ae357..6a8adc40f 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/NotInQueueSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/NotInQueueSpecification.cs @@ -13,13 +13,11 @@ namespace NzbDrone.Core.DecisionEngine.Specifications public class NotInQueueSpecification : IDecisionEngineSpecification { private readonly IProvideDownloadClient _downloadClientProvider; - private readonly IParsingService _parsingService; private readonly Logger _logger; - public NotInQueueSpecification(IProvideDownloadClient downloadClientProvider, IParsingService parsingService, Logger logger) + public NotInQueueSpecification(IProvideDownloadClient downloadClientProvider, Logger logger) { _downloadClientProvider = downloadClientProvider; - _parsingService = parsingService; _logger = logger; } @@ -41,20 +39,17 @@ namespace NzbDrone.Core.DecisionEngine.Specifications return true; } - var queue = downloadClient.GetQueue().Select(queueItem => Parser.Parser.ParseTitle(queueItem.Title)).Where(episodeInfo => episodeInfo != null); + var queue = downloadClient.GetQueue().Select(q => q.RemoteEpisode); - var mappedQueue = queue.Select(queueItem => _parsingService.Map(queueItem, 0)) - .Where(remoteEpisode => remoteEpisode.Series != null); - - return !IsInQueue(subject, mappedQueue); + return !IsInQueue(subject, queue); } - public bool IsInQueue(RemoteEpisode newEpisode, IEnumerable queue) + private bool IsInQueue(RemoteEpisode newEpisode, IEnumerable queue) { var matchingSeries = queue.Where(q => q.Series.Id == newEpisode.Series.Id); - var matchingTitleWithQuality = matchingSeries.Where(q => q.ParsedEpisodeInfo.Quality >= newEpisode.ParsedEpisodeInfo.Quality); + var matchingSeriesAndQuality = matchingSeries.Where(q => q.ParsedEpisodeInfo.Quality >= newEpisode.ParsedEpisodeInfo.Quality); - return matchingTitleWithQuality.Any(q => q.Episodes.Select(e => e.Id).Intersect(newEpisode.Episodes.Select(e => e.Id)).Any()); + return matchingSeriesAndQuality.Any(q => q.Episodes.Select(e => e.Id).Intersect(newEpisode.Episodes.Select(e => e.Id)).Any()); } } } diff --git a/src/NzbDrone.Core/Download/Clients/Nzbget/NzbgetClient.cs b/src/NzbDrone.Core/Download/Clients/Nzbget/NzbgetClient.cs index e7a53fde9..f3d692d32 100644 --- a/src/NzbDrone.Core/Download/Clients/Nzbget/NzbgetClient.cs +++ b/src/NzbDrone.Core/Download/Clients/Nzbget/NzbgetClient.cs @@ -4,6 +4,7 @@ using NLog; using NzbDrone.Common; using NzbDrone.Common.Serializer; using NzbDrone.Core.Configuration; +using NzbDrone.Core.Parser; using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.Download.Clients.Nzbget @@ -12,12 +13,14 @@ namespace NzbDrone.Core.Download.Clients.Nzbget { private readonly IConfigService _configService; private readonly IHttpProvider _httpProvider; + private readonly IParsingService _parsingService; private readonly Logger _logger; - public NzbgetClient(IConfigService configService, IHttpProvider httpProvider, Logger logger) + public NzbgetClient(IConfigService configService, IHttpProvider httpProvider, IParsingService parsingService, Logger logger) { _configService = configService; _httpProvider = httpProvider; + _parsingService = parsingService; _logger = logger; } @@ -75,6 +78,14 @@ namespace NzbDrone.Core.Download.Clients.Nzbget queueItem.Size = nzbGetQueueItem.FileSizeMb; queueItem.Sizeleft = nzbGetQueueItem.RemainingSizeMb; + var parsedEpisodeInfo = Parser.Parser.ParseTitle(queueItem.Title); + if (parsedEpisodeInfo == null) continue; + + var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0); + if (remoteEpisode.Series == null) continue; + + queueItem.RemoteEpisode = remoteEpisode; + yield return queueItem; } } diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdClient.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdClient.cs index 3e36e941d..4e1fabcfc 100644 --- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdClient.cs +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdClient.cs @@ -7,6 +7,7 @@ using NzbDrone.Common; using NzbDrone.Common.Cache; using NzbDrone.Common.Serializer; using NzbDrone.Core.Configuration; +using NzbDrone.Core.Parser; using NzbDrone.Core.Parser.Model; using RestSharp; @@ -53,13 +54,19 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd { private readonly IConfigService _configService; private readonly IHttpProvider _httpProvider; + private readonly IParsingService _parsingService; private readonly ICached> _queueCache; private readonly Logger _logger; - public SabnzbdClient(IConfigService configService, IHttpProvider httpProvider, ICacheManger cacheManger, Logger logger) + public SabnzbdClient(IConfigService configService, + IHttpProvider httpProvider, + ICacheManger cacheManger, + IParsingService parsingService, + Logger logger) { _configService = configService; _httpProvider = httpProvider; + _parsingService = parsingService; _queueCache = cacheManger.GetCache>(GetType(), "queue"); _logger = logger; } @@ -121,6 +128,14 @@ namespace NzbDrone.Core.Download.Clients.Sabnzbd queueItem.Timeleft = sabQueueItem.Timeleft; queueItem.Status = sabQueueItem.Status; + var parsedEpisodeInfo = Parser.Parser.ParseTitle(queueItem.Title); + if (parsedEpisodeInfo == null) continue; + + var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0); + if (remoteEpisode.Series == null) continue; + + queueItem.RemoteEpisode = remoteEpisode; + queueItems.Add(queueItem); } diff --git a/src/NzbDrone.Core/Download/IDownloadClient.cs b/src/NzbDrone.Core/Download/IDownloadClient.cs index aca724d1b..ce32b62b2 100644 --- a/src/NzbDrone.Core/Download/IDownloadClient.cs +++ b/src/NzbDrone.Core/Download/IDownloadClient.cs @@ -9,5 +9,4 @@ namespace NzbDrone.Core.Download bool IsConfigured { get; } IEnumerable GetQueue(); } - } diff --git a/src/NzbDrone.Core/Download/QueueItem.cs b/src/NzbDrone.Core/Download/QueueItem.cs index c63d98c1a..9112680b9 100644 --- a/src/NzbDrone.Core/Download/QueueItem.cs +++ b/src/NzbDrone.Core/Download/QueueItem.cs @@ -1,4 +1,5 @@ using System; +using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.Download { @@ -10,5 +11,6 @@ namespace NzbDrone.Core.Download public decimal Sizeleft { get; set; } public TimeSpan Timeleft { get; set; } public String Status { get; set; } + public RemoteEpisode RemoteEpisode { get; set; } } } diff --git a/src/NzbDrone.Core/Queue/QueueService.cs b/src/NzbDrone.Core/Queue/QueueService.cs index e3e78c7ac..1bc417fef 100644 --- a/src/NzbDrone.Core/Queue/QueueService.cs +++ b/src/NzbDrone.Core/Queue/QueueService.cs @@ -15,13 +15,11 @@ namespace NzbDrone.Core.Queue public class QueueService : IQueueService { private readonly IProvideDownloadClient _downloadClientProvider; - private readonly IParsingService _parsingService; private readonly Logger _logger; - public QueueService(IProvideDownloadClient downloadClientProvider, IParsingService parsingService, Logger logger) + public QueueService(IProvideDownloadClient downloadClientProvider, Logger logger) { _downloadClientProvider = downloadClientProvider; - _parsingService = parsingService; _logger = logger; } @@ -39,31 +37,19 @@ namespace NzbDrone.Core.Queue foreach (var queueItem in queueItems) { - var parsedEpisodeInfo = Parser.Parser.ParseTitle(queueItem.Title); - - if (parsedEpisodeInfo != null && !string.IsNullOrWhiteSpace(parsedEpisodeInfo.SeriesTitle)) + foreach (var episode in queueItem.RemoteEpisode.Episodes) { - var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, 0); - - if (remoteEpisode.Series == null) - { - continue; - } - - foreach (var episode in remoteEpisode.Episodes) - { - var queue = new Queue(); - queue.Id = queueItem.Id.GetHashCode(); - queue.Series = remoteEpisode.Series; - queue.Episode = episode; - queue.Quality = remoteEpisode.ParsedEpisodeInfo.Quality; - queue.Title = queueItem.Title; - queue.Size = queueItem.Size; - queue.Sizeleft = queueItem.Sizeleft; - queue.Timeleft = queueItem.Timeleft; - queue.Status = queueItem.Status; - queued.Add(queue); - } + var queue = new Queue(); + queue.Id = queueItem.Id.GetHashCode(); + queue.Series = queueItem.RemoteEpisode.Series; + queue.Episode = episode; + queue.Quality = queueItem.RemoteEpisode.ParsedEpisodeInfo.Quality; + queue.Title = queueItem.Title; + queue.Size = queueItem.Size; + queue.Sizeleft = queueItem.Sizeleft; + queue.Timeleft = queueItem.Timeleft; + queue.Status = queueItem.Status; + queued.Add(queue); } }