mirror of
https://github.com/Radarr/Radarr.git
synced 2024-09-17 15:02:34 +02:00
some preliminary work to move decision engine to use the visitor pattern.
This commit is contained in:
parent
969dff5197
commit
02d842a2b2
@ -7,6 +7,7 @@
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Model;
|
||||
|
@ -7,6 +7,7 @@
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
@ -40,7 +41,7 @@ public void Setup()
|
||||
.Setup(c => c.IsSatisfiedBy(It.IsAny<EpisodeParseResult>()))
|
||||
.Returns(true);
|
||||
|
||||
Mocker.GetMock<AlreadyInQueueSpecification>()
|
||||
Mocker.GetMock<NotInQueueSpecification>()
|
||||
.Setup(c => c.IsSatisfiedBy(It.IsAny<EpisodeParseResult>()))
|
||||
.Returns(false);
|
||||
|
||||
@ -84,7 +85,7 @@ private void WithNoDiskUpgrade()
|
||||
|
||||
private void WithEpisodeAlreadyInQueue()
|
||||
{
|
||||
Mocker.GetMock<AlreadyInQueueSpecification>()
|
||||
Mocker.GetMock<NotInQueueSpecification>()
|
||||
.Setup(c => c.IsSatisfiedBy(It.IsAny<EpisodeParseResult>()))
|
||||
.Returns(true);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Model;
|
||||
|
@ -7,6 +7,7 @@
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Providers;
|
||||
|
@ -7,6 +7,7 @@
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
|
@ -7,6 +7,7 @@
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Providers;
|
||||
|
@ -5,6 +5,7 @@
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Model;
|
||||
|
@ -0,0 +1,34 @@
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class QualityUpgradableSpecificationFixture : CoreTest<QualityUpgradableSpecification>
|
||||
{
|
||||
[Test]
|
||||
public void IsUpgradePossible_should_return_true_if_current_episode_is_less_than_cutoff()
|
||||
{
|
||||
Subject.IsUpgradable(new QualityProfile { Cutoff = Quality.Bluray1080p },
|
||||
new QualityModel(Quality.DVD, true)).Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsUpgradePossible_should_return_false_if_current_episode_is_equal_to_cutoff()
|
||||
{
|
||||
Subject.IsUpgradable(new QualityProfile { Cutoff = Quality.HDTV720p },
|
||||
new QualityModel(Quality.HDTV720p, true)).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsUpgradePossible_should_return_false_if_current_episode_is_greater_than_cutoff()
|
||||
{
|
||||
Subject.IsUpgradable(new QualityProfile { Cutoff = Quality.HDTV720p },
|
||||
new QualityModel(Quality.Bluray1080p, true)).Should().BeFalse();
|
||||
}
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Model;
|
||||
@ -13,7 +14,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
{
|
||||
[TestFixture]
|
||||
// ReSharper disable InconsistentNaming
|
||||
public class QualityUpgradeSpecificationFixture : CoreTest
|
||||
public class QualityUpgradeSpecificationFixture : CoreTest<QualityUpgradableSpecification>
|
||||
{
|
||||
public static object[] IsUpgradeTestCases =
|
||||
{
|
||||
@ -31,7 +32,7 @@ public class QualityUpgradeSpecificationFixture : CoreTest
|
||||
[Test, TestCaseSource("IsUpgradeTestCases")]
|
||||
public void IsUpgradeTest(Quality current, bool currentProper, Quality newQuality, bool newProper, Quality cutoff, bool expected)
|
||||
{
|
||||
new QualityUpgradeSpecification().IsSatisfiedBy(new QualityModel(current, currentProper), new QualityModel(newQuality, newProper), cutoff)
|
||||
Subject.IsUpgradable(new QualityProfile() { Cutoff = cutoff }, new QualityModel(current, currentProper), new QualityModel(newQuality, newProper))
|
||||
.Should().Be(expected);
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
|
@ -6,6 +6,7 @@
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
@ -31,7 +32,7 @@ public class UpgradeDiskSpecificationFixture : CoreTest
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
Mocker.Resolve<QualityUpgradeSpecification>();
|
||||
Mocker.Resolve<QualityUpgradableSpecification>();
|
||||
_upgradeDisk = Mocker.Resolve<UpgradeDiskSpecification>();
|
||||
|
||||
firstFile = new EpisodeFile { Quality = Quality.Bluray1080p, Proper = true, DateAdded = DateTime.Now };
|
||||
|
@ -5,6 +5,7 @@
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.History;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
@ -31,7 +32,7 @@ public class UpgradeHistorySpecificationFixture : CoreTest
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
Mocker.Resolve<QualityUpgradeSpecification>();
|
||||
Mocker.Resolve<QualityUpgradableSpecification>();
|
||||
_upgradeHistory = Mocker.Resolve<UpgradeHistorySpecification>();
|
||||
|
||||
var singleEpisodeList = new List<Episode> { new Episode { SeasonNumber = 12, EpisodeNumber = 3 } };
|
||||
|
@ -1,103 +0,0 @@
|
||||
// ReSharper disable RedundantUsingDirective
|
||||
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.Repository;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
{
|
||||
[TestFixture]
|
||||
// ReSharper disable InconsistentNaming
|
||||
public class UpgradePossibleSpecificationFixture : CoreTest
|
||||
{
|
||||
private void WithWebdlCutoff()
|
||||
{
|
||||
var profile = new QualityProfile { Cutoff = Quality.WEBDL720p };
|
||||
Mocker.GetMock<IQualityProfileService>().Setup(s => s.Get(It.IsAny<int>())).Returns(profile);
|
||||
}
|
||||
|
||||
private Series _series;
|
||||
private EpisodeFile _episodeFile;
|
||||
private Episode _episode;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_series = Builder<Series>.CreateNew()
|
||||
.Build();
|
||||
|
||||
_episodeFile = Builder<EpisodeFile>.CreateNew()
|
||||
.With(f => f.Quality = Quality.SDTV)
|
||||
.Build();
|
||||
|
||||
_episode = Builder<Episode>.CreateNew()
|
||||
.With(e => e.SeriesId = _series.Id)
|
||||
.With(e => e.Series = _series)
|
||||
.With(e => e.EpisodeFile = _episodeFile)
|
||||
.Build();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsUpgradePossible_should_return_true_if_no_episode_file_exists()
|
||||
{
|
||||
var episode = Builder<Episode>.CreateNew()
|
||||
.With(e => e.EpisodeFile = null)
|
||||
.Build();
|
||||
|
||||
//Act
|
||||
bool result = Mocker.Resolve<UpgradePossibleSpecification>().IsSatisfiedBy(episode);
|
||||
|
||||
//Assert
|
||||
result.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsUpgradePossible_should_return_true_if_current_episode_is_less_than_cutoff()
|
||||
{
|
||||
WithWebdlCutoff();
|
||||
|
||||
//Act
|
||||
bool result = Mocker.Resolve<UpgradePossibleSpecification>().IsSatisfiedBy(_episode);
|
||||
|
||||
//Assert
|
||||
result.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsUpgradePossible_should_return_false_if_current_episode_is_equal_to_cutoff()
|
||||
{
|
||||
WithWebdlCutoff();
|
||||
|
||||
_episodeFile.Quality = Quality.WEBDL720p;
|
||||
|
||||
//Act
|
||||
bool result = Mocker.Resolve<UpgradePossibleSpecification>().IsSatisfiedBy(_episode);
|
||||
|
||||
//Assert
|
||||
result.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsUpgradePossible_should_return_false_if_current_episode_is_greater_than_cutoff()
|
||||
{
|
||||
WithWebdlCutoff();
|
||||
|
||||
_episodeFile.Quality = Quality.Bluray720p;
|
||||
|
||||
//Act
|
||||
bool result = Mocker.Resolve<UpgradePossibleSpecification>().IsSatisfiedBy(_episode);
|
||||
|
||||
//Assert
|
||||
result.Should().BeFalse();
|
||||
}
|
||||
}
|
||||
}
|
@ -191,7 +191,7 @@
|
||||
<Compile Include="DecisionEngineTests\UpgradeHistorySpecificationFixture.cs" />
|
||||
<Compile Include="DecisionEngineTests\UpgradeDiskSpecificationFixture.cs" />
|
||||
<Compile Include="DecisionEngineTests\QualityUpgradeSpecificationFixture.cs" />
|
||||
<Compile Include="DecisionEngineTests\UpgradePossibleSpecificationFixture.cs" />
|
||||
<Compile Include="DecisionEngineTests\QualityUpgradableSpecificationFixture.cs" />
|
||||
<Compile Include="ProviderTests\DownloadClientTests\BlackholeProviderFixture.cs" />
|
||||
<Compile Include="ProviderTests\NotificationProviderTests\NotificationProviderFixture.cs" />
|
||||
<Compile Include="ProviderTests\DownloadClientTests\SabProviderTests\QueueFixture.cs" />
|
||||
|
@ -6,6 +6,7 @@
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
@ -4,6 +4,7 @@
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.ReferenceData;
|
||||
|
@ -1,6 +1,4 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace NzbDrone.Core
|
||||
namespace NzbDrone.Core
|
||||
{
|
||||
public static class Constants
|
||||
{
|
||||
|
@ -1,7 +1,6 @@
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Repository.Search;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine
|
||||
{
|
||||
@ -10,7 +9,7 @@ public class AllowedDownloadSpecification
|
||||
private readonly QualityAllowedByProfileSpecification _qualityAllowedByProfileSpecification;
|
||||
private readonly UpgradeDiskSpecification _upgradeDiskSpecification;
|
||||
private readonly AcceptableSizeSpecification _acceptableSizeSpecification;
|
||||
private readonly AlreadyInQueueSpecification _alreadyInQueueSpecification;
|
||||
private readonly NotInQueueSpecification _notInQueueSpecification;
|
||||
private readonly RetentionSpecification _retentionSpecification;
|
||||
private readonly AllowedReleaseGroupSpecification _allowedReleaseGroupSpecification;
|
||||
private readonly CustomStartDateSpecification _customStartDateSpecification;
|
||||
@ -19,14 +18,14 @@ public class AllowedDownloadSpecification
|
||||
|
||||
public AllowedDownloadSpecification(QualityAllowedByProfileSpecification qualityAllowedByProfileSpecification,
|
||||
UpgradeDiskSpecification upgradeDiskSpecification, AcceptableSizeSpecification acceptableSizeSpecification,
|
||||
AlreadyInQueueSpecification alreadyInQueueSpecification, RetentionSpecification retentionSpecification,
|
||||
NotInQueueSpecification notInQueueSpecification, RetentionSpecification retentionSpecification,
|
||||
AllowedReleaseGroupSpecification allowedReleaseGroupSpecification, CustomStartDateSpecification customStartDateSpecification,
|
||||
LanguageSpecification languageSpecification)
|
||||
{
|
||||
_qualityAllowedByProfileSpecification = qualityAllowedByProfileSpecification;
|
||||
_upgradeDiskSpecification = upgradeDiskSpecification;
|
||||
_acceptableSizeSpecification = acceptableSizeSpecification;
|
||||
_alreadyInQueueSpecification = alreadyInQueueSpecification;
|
||||
_notInQueueSpecification = notInQueueSpecification;
|
||||
_retentionSpecification = retentionSpecification;
|
||||
_allowedReleaseGroupSpecification = allowedReleaseGroupSpecification;
|
||||
_customStartDateSpecification = customStartDateSpecification;
|
||||
@ -46,7 +45,7 @@ public virtual ReportRejectionReasons IsSatisfiedBy(EpisodeParseResult subject)
|
||||
if (!_retentionSpecification.IsSatisfiedBy(subject)) return ReportRejectionReasons.Retention;
|
||||
if (!_acceptableSizeSpecification.IsSatisfiedBy(subject)) return ReportRejectionReasons.Size;
|
||||
if (!_allowedReleaseGroupSpecification.IsSatisfiedBy(subject)) return ReportRejectionReasons.ReleaseGroupNotWanted;
|
||||
if (_alreadyInQueueSpecification.IsSatisfiedBy(subject)) return ReportRejectionReasons.AlreadyInQueue;
|
||||
if (!_notInQueueSpecification.IsSatisfiedBy(subject)) return ReportRejectionReasons.AlreadyInQueue;
|
||||
|
||||
logger.Debug("Episode {0} is needed", subject);
|
||||
return ReportRejectionReasons.None;
|
||||
|
@ -1,32 +0,0 @@
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Providers;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine
|
||||
{
|
||||
public class AlreadyInQueueSpecification
|
||||
{
|
||||
private readonly DownloadProvider _downloadProvider;
|
||||
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public AlreadyInQueueSpecification(DownloadProvider downloadProvider)
|
||||
{
|
||||
_downloadProvider = downloadProvider;
|
||||
|
||||
}
|
||||
|
||||
public AlreadyInQueueSpecification()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
{
|
||||
return _downloadProvider.GetActiveDownloadClient().IsInQueue(subject);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Model;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine
|
||||
{
|
||||
public class CustomStartDateSpecification
|
||||
{
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
{
|
||||
if (!subject.Series.CustomStartDate.HasValue)
|
||||
{
|
||||
logger.Debug("{0} does not restrict downloads before date.", subject.Series.Title);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (subject.Episodes.Any(episode => episode.AirDate >= subject.Series.CustomStartDate.Value))
|
||||
{
|
||||
logger.Debug("One or more episodes aired after cutoff, downloading.");
|
||||
return true;
|
||||
}
|
||||
|
||||
logger.Debug("Episodes aired before cutoff date: {0}", subject.Series.CustomStartDate);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
10
NzbDrone.Core/DecisionEngine/IFetchableSpecification.cs
Normal file
10
NzbDrone.Core/DecisionEngine/IFetchableSpecification.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using NzbDrone.Core.Model;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine
|
||||
{
|
||||
public interface IFetchableSpecification
|
||||
{
|
||||
string RejectionReason { get; }
|
||||
bool IsSatisfiedBy(EpisodeParseResult subject);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Model;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine
|
||||
{
|
||||
public class LanguageSpecification
|
||||
{
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
{
|
||||
logger.Trace("Checking if report meets language requirements. {0}", subject.Language);
|
||||
if (subject.Language != LanguageType.English)
|
||||
{
|
||||
logger.Trace("Report Language: {0} rejected because it is not english", subject.Language);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Model;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine
|
||||
{
|
||||
public class QualityAllowedByProfileSpecification
|
||||
{
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
{
|
||||
logger.Trace("Checking if report meets quality requirements. {0}", subject.Quality);
|
||||
if (!subject.Series.QualityProfile.Allowed.Contains(subject.Quality.Quality))
|
||||
{
|
||||
logger.Trace("Quality {0} rejected by Series' quality profile", subject.Quality);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
using NLog;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine
|
||||
{
|
||||
public interface IQualityUpgradableSpecification
|
||||
{
|
||||
bool IsUpgradable(QualityProfile profile, QualityModel currentQuality, QualityModel newQuality = null);
|
||||
}
|
||||
|
||||
public class QualityUpgradableSpecification : IQualityUpgradableSpecification
|
||||
{
|
||||
private readonly Logger _logger;
|
||||
|
||||
public QualityUpgradableSpecification(Logger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public bool IsUpgradable(QualityProfile profile, QualityModel currentQuality, QualityModel newQuality = null)
|
||||
{
|
||||
if (newQuality != null)
|
||||
{
|
||||
if (currentQuality >= newQuality)
|
||||
{
|
||||
_logger.Trace("existing item has better or equal quality. skipping");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (currentQuality.Quality == newQuality.Quality && newQuality.Proper)
|
||||
{
|
||||
_logger.Trace("Upgrading existing item to proper.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentQuality.Quality >= profile.Cutoff)
|
||||
{
|
||||
_logger.Trace("Existing item meets cut-off. skipping.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Model;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine
|
||||
{
|
||||
public class QualityUpgradeSpecification
|
||||
{
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public virtual bool IsSatisfiedBy(QualityModel currentQuality, QualityModel newQuality, Quality cutOff)
|
||||
{
|
||||
if (currentQuality >= newQuality)
|
||||
{
|
||||
logger.Trace("existing item has better or equal quality. skipping");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (currentQuality.Quality == newQuality.Quality && newQuality.Proper)
|
||||
{
|
||||
logger.Trace("Upgrading existing item to proper.");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (currentQuality.Quality >= cutOff)
|
||||
{
|
||||
logger.Trace("Existing item meets cut-off. skipping.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Model;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine
|
||||
{
|
||||
public class RetentionSpecification
|
||||
{
|
||||
private readonly IConfigService _configService;
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public RetentionSpecification(IConfigService configService)
|
||||
{
|
||||
_configService = configService;
|
||||
}
|
||||
|
||||
public RetentionSpecification()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
{
|
||||
logger.Trace("Checking if report meets retention requirements. {0}", subject.Age);
|
||||
if (_configService.Retention > 0 && subject.Age > _configService.Retention)
|
||||
{
|
||||
logger.Trace("Report age: {0} rejected by user's retention limit", subject.Age);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,37 +1,35 @@
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Providers;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine
|
||||
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||
{
|
||||
public class AcceptableSizeSpecification
|
||||
public class AcceptableSizeSpecification : IFetchableSpecification
|
||||
{
|
||||
private readonly IQualitySizeService _qualityTypeProvider;
|
||||
private readonly IEpisodeService _episodeService;
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
private readonly Logger _logger;
|
||||
|
||||
public AcceptableSizeSpecification(IQualitySizeService qualityTypeProvider, IEpisodeService episodeService)
|
||||
public AcceptableSizeSpecification(IQualitySizeService qualityTypeProvider, IEpisodeService episodeService, Logger logger)
|
||||
{
|
||||
_qualityTypeProvider = qualityTypeProvider;
|
||||
_episodeService = episodeService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public AcceptableSizeSpecification()
|
||||
public string RejectionReason
|
||||
{
|
||||
|
||||
get { return "File size too big or small"; }
|
||||
}
|
||||
|
||||
public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
{
|
||||
logger.Trace("Beginning size check for: {0}", subject);
|
||||
_logger.Trace("Beginning size check for: {0}", subject);
|
||||
|
||||
if(subject.Quality.Quality == Quality.RAWHD)
|
||||
if (subject.Quality.Quality == Quality.RAWHD)
|
||||
{
|
||||
logger.Trace("Raw-HD release found, skipping size check.");
|
||||
_logger.Trace("Raw-HD release found, skipping size check.");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -39,7 +37,7 @@ public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
|
||||
if (qualityType.MaxSize == 0)
|
||||
{
|
||||
logger.Trace("Max size is 0 (unlimited) - skipping check.");
|
||||
_logger.Trace("Max size is 0 (unlimited) - skipping check.");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -66,13 +64,13 @@ public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
//If the parsed size is greater than maxSize we don't want it
|
||||
if (subject.Size > maxSize)
|
||||
{
|
||||
logger.Trace("Item: {0}, Size: {1} is greater than maximum allowed size ({2}), rejecting.", subject, subject.Size, maxSize);
|
||||
_logger.Trace("Item: {0}, Size: {1} is greater than maximum allowed size ({2}), rejecting.", subject, subject.Size, maxSize);
|
||||
return false;
|
||||
}
|
||||
|
||||
logger.Trace("Item: {0}, meets size contraints.", subject);
|
||||
|
||||
_logger.Trace("Item: {0}, meets size constraints.", subject);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -1,46 +1,50 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Model;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine
|
||||
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||
{
|
||||
public class AllowedReleaseGroupSpecification
|
||||
public class AllowedReleaseGroupSpecification : IFetchableSpecification
|
||||
{
|
||||
private readonly IConfigService _configService;
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
private readonly Logger _logger;
|
||||
|
||||
public AllowedReleaseGroupSpecification(IConfigService configService)
|
||||
public AllowedReleaseGroupSpecification(IConfigService configService, Logger logger)
|
||||
{
|
||||
_configService = configService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public AllowedReleaseGroupSpecification()
|
||||
|
||||
public string RejectionReason
|
||||
{
|
||||
|
||||
get
|
||||
{
|
||||
return "Release group is blacklisted.";
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
{
|
||||
logger.Trace("Beginning release group check for: {0}", subject);
|
||||
_logger.Trace("Beginning release group check for: {0}", subject);
|
||||
|
||||
var allowed = _configService.AllowedReleaseGroups;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(allowed))
|
||||
return true;
|
||||
|
||||
foreach(var group in allowed.Trim(',', ' ').Split(','))
|
||||
foreach (var group in allowed.Trim(',', ' ').Split(','))
|
||||
{
|
||||
if (subject.ReleaseGroup.Equals(group.Trim(' '), StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
logger.Trace("Item: {0}'s release group is wanted: {1}", subject, subject.ReleaseGroup);
|
||||
_logger.Trace("Item: {0}'s release group is wanted: {1}", subject, subject.ReleaseGroup);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
logger.Trace("Item: {0}'s release group is not wanted: {1}", subject, subject.ReleaseGroup);
|
||||
|
||||
_logger.Trace("Item: {0}'s release group is not wanted: {1}", subject, subject.ReleaseGroup);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Model;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||
{
|
||||
public class CustomStartDateSpecification : IFetchableSpecification
|
||||
{
|
||||
private readonly Logger _logger;
|
||||
|
||||
public CustomStartDateSpecification(Logger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public string RejectionReason
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Aired before configured cut-off";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
{
|
||||
if (!subject.Series.CustomStartDate.HasValue)
|
||||
{
|
||||
_logger.Debug("{0} does not restrict downloads before date.", subject.Series.Title);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (subject.Episodes.Any(episode => episode.AirDate >= subject.Series.CustomStartDate.Value))
|
||||
{
|
||||
_logger.Debug("One or more episodes aired after cutoff, downloading.");
|
||||
return true;
|
||||
}
|
||||
|
||||
_logger.Debug("Episodes aired before cutoff date: {0}", subject.Series.CustomStartDate);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
using NLog;
|
||||
using NzbDrone.Core.Model;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||
{
|
||||
public class LanguageSpecification : IFetchableSpecification
|
||||
{
|
||||
private readonly Logger _logger;
|
||||
|
||||
public LanguageSpecification(Logger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public string RejectionReason
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Not English";
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
{
|
||||
_logger.Trace("Checking if report meets language requirements. {0}", subject.Language);
|
||||
if (subject.Language != LanguageType.English)
|
||||
{
|
||||
_logger.Trace("Report Language: {0} rejected because it is not English", subject.Language);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,26 +1,29 @@
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine
|
||||
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||
{
|
||||
public class MonitoredEpisodeSpecification
|
||||
public class MonitoredEpisodeSpecification : IFetchableSpecification
|
||||
{
|
||||
private readonly IEpisodeService _episodeService;
|
||||
private readonly ISeriesRepository _seriesRepository;
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
private readonly Logger _logger;
|
||||
|
||||
public MonitoredEpisodeSpecification(IEpisodeService episodeService, ISeriesRepository seriesRepository)
|
||||
public MonitoredEpisodeSpecification(IEpisodeService episodeService, ISeriesRepository seriesRepository, Logger logger)
|
||||
{
|
||||
_episodeService = episodeService;
|
||||
_seriesRepository = seriesRepository;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public MonitoredEpisodeSpecification()
|
||||
public string RejectionReason
|
||||
{
|
||||
|
||||
get
|
||||
{
|
||||
return "Series is not monitored";
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
@ -29,7 +32,7 @@ public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
|
||||
if (series == null)
|
||||
{
|
||||
logger.Trace("{0} is not mapped to any series in DB. skipping", subject.CleanTitle);
|
||||
_logger.Trace("{0} is not mapped to any series in DB. skipping", subject.CleanTitle);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -37,7 +40,7 @@ public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
|
||||
if (!series.Monitored)
|
||||
{
|
||||
logger.Debug("{0} is present in the DB but not tracked. skipping.", subject.CleanTitle);
|
||||
_logger.Debug("{0} is present in the DB but not tracked. skipping.", subject.CleanTitle);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -50,7 +53,7 @@ public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
return true;
|
||||
}
|
||||
|
||||
logger.Debug("All episodes are ignored. skipping.");
|
||||
_logger.Debug("All episodes are ignored. skipping.");
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
using NLog;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Model;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||
{
|
||||
public class NotInQueueSpecification : IFetchableSpecification
|
||||
{
|
||||
private readonly DownloadProvider _downloadProvider;
|
||||
|
||||
|
||||
public NotInQueueSpecification(DownloadProvider downloadProvider)
|
||||
{
|
||||
_downloadProvider = downloadProvider;
|
||||
|
||||
}
|
||||
|
||||
public string RejectionReason
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Already in download queue.";
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
{
|
||||
return !_downloadProvider.GetActiveDownloadClient().IsInQueue(subject);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
using NLog;
|
||||
using NzbDrone.Core.Model;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||
{
|
||||
public class QualityAllowedByProfileSpecification : IFetchableSpecification
|
||||
{
|
||||
private readonly Logger _logger;
|
||||
|
||||
public QualityAllowedByProfileSpecification(Logger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public string RejectionReason
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Quality rejected by series profile";
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
{
|
||||
_logger.Trace("Checking if report meets quality requirements. {0}", subject.Quality);
|
||||
if (!subject.Series.QualityProfile.Allowed.Contains(subject.Quality.Quality))
|
||||
{
|
||||
_logger.Trace("Quality {0} rejected by Series' quality profile", subject.Quality);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
using NLog;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Model;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||
{
|
||||
public class RetentionSpecification : IFetchableSpecification
|
||||
{
|
||||
private readonly IConfigService _configService;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public RetentionSpecification(IConfigService configService, Logger logger)
|
||||
{
|
||||
_configService = configService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
||||
public string RejectionReason
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Report past retention limit.";
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
{
|
||||
_logger.Trace("Checking if report meets retention requirements. {0}", subject.Age);
|
||||
if (_configService.Retention > 0 && subject.Age > _configService.Retention)
|
||||
{
|
||||
_logger.Trace("Report age: {0} rejected by user's retention limit", subject.Age);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||
{
|
||||
public class UpgradeDiskSpecification : IFetchableSpecification
|
||||
{
|
||||
private readonly QualityUpgradableSpecification _qualityUpgradableSpecification;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public UpgradeDiskSpecification(QualityUpgradableSpecification qualityUpgradableSpecification, Logger logger)
|
||||
{
|
||||
_qualityUpgradableSpecification = qualityUpgradableSpecification;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public string RejectionReason
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Higher quality exists on disk";
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
{
|
||||
foreach (var file in subject.Episodes.Select(c => c.EpisodeFile).Where(c => c != null))
|
||||
{
|
||||
_logger.Trace("Comparing file quality with report. Existing file is {0} proper:{1}", file.Quality, file.Proper);
|
||||
if (!_qualityUpgradableSpecification.IsUpgradable(subject.Series.QualityProfile, new QualityModel { Quality = file.Quality, Proper = file.Proper }, subject.Quality))
|
||||
return false;
|
||||
|
||||
if (subject.Quality.Proper && file.DateAdded < DateTime.Today.AddDays(-7))
|
||||
{
|
||||
_logger.Trace("Proper for old file, skipping: {0}", subject);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
using NLog;
|
||||
using NzbDrone.Core.History;
|
||||
using NzbDrone.Core.Model;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||
{
|
||||
public class UpgradeHistorySpecification : IFetchableSpecification
|
||||
{
|
||||
private readonly IHistoryService _historyService;
|
||||
private readonly QualityUpgradableSpecification _qualityUpgradableSpecification;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public UpgradeHistorySpecification(IHistoryService historyService, QualityUpgradableSpecification qualityUpgradableSpecification, Logger logger)
|
||||
{
|
||||
_historyService = historyService;
|
||||
_qualityUpgradableSpecification = qualityUpgradableSpecification;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public string RejectionReason
|
||||
{
|
||||
get
|
||||
{
|
||||
return "Higher quality report exists in history";
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
{
|
||||
foreach (var episode in subject.Episodes)
|
||||
{
|
||||
var bestQualityInHistory = _historyService.GetBestQualityInHistory(subject.Series.Id, episode.SeasonNumber, episode.EpisodeNumber);
|
||||
if (bestQualityInHistory != null)
|
||||
{
|
||||
_logger.Trace("Comparing history quality with report. History is {0}", bestQualityInHistory);
|
||||
if (!_qualityUpgradableSpecification.IsUpgradable(subject.Series.QualityProfile, bestQualityInHistory, subject.Quality))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Model;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine
|
||||
{
|
||||
public class UpgradeDiskSpecification
|
||||
{
|
||||
private readonly QualityUpgradeSpecification _qualityUpgradeSpecification;
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public UpgradeDiskSpecification(QualityUpgradeSpecification qualityUpgradeSpecification)
|
||||
{
|
||||
_qualityUpgradeSpecification = qualityUpgradeSpecification;
|
||||
}
|
||||
|
||||
public UpgradeDiskSpecification()
|
||||
{
|
||||
}
|
||||
|
||||
public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
{
|
||||
foreach (var file in subject.Episodes.Select(c => c.EpisodeFile).Where(c => c != null))
|
||||
{
|
||||
logger.Trace("Comparing file quality with report. Existing file is {0} proper:{1}", file.Quality, file.Proper);
|
||||
if (!_qualityUpgradeSpecification.IsSatisfiedBy(new QualityModel { Quality = file.Quality, Proper = file.Proper }, subject.Quality, subject.Series.QualityProfile.Cutoff))
|
||||
return false;
|
||||
|
||||
if(subject.Quality.Proper && file.DateAdded < DateTime.Today.AddDays(-7))
|
||||
{
|
||||
logger.Trace("Proper for old file, skipping: {0}", subject);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.History;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Providers;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine
|
||||
{
|
||||
public class UpgradeHistorySpecification
|
||||
{
|
||||
private readonly IHistoryService _historyService;
|
||||
private readonly QualityUpgradeSpecification _qualityUpgradeSpecification;
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public UpgradeHistorySpecification(IHistoryService historyService, QualityUpgradeSpecification qualityUpgradeSpecification)
|
||||
{
|
||||
_historyService = historyService;
|
||||
_qualityUpgradeSpecification = qualityUpgradeSpecification;
|
||||
}
|
||||
|
||||
public UpgradeHistorySpecification()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual bool IsSatisfiedBy(EpisodeParseResult subject)
|
||||
{
|
||||
foreach (var episode in subject.Episodes)
|
||||
{
|
||||
var bestQualityInHistory = _historyService.GetBestQualityInHistory(subject.Series.Id, episode.SeasonNumber, episode.EpisodeNumber);
|
||||
if (bestQualityInHistory != null)
|
||||
{
|
||||
logger.Trace("Comparing history quality with report. History is {0}", bestQualityInHistory);
|
||||
if (!_qualityUpgradeSpecification.IsSatisfiedBy(bestQualityInHistory, subject.Quality, subject.Series.QualityProfile.Cutoff))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Repository;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine
|
||||
{
|
||||
public class UpgradePossibleSpecification
|
||||
{
|
||||
private readonly IQualityProfileService _qualityProvider;
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public UpgradePossibleSpecification(IQualityProfileService qualityProvider)
|
||||
{
|
||||
_qualityProvider = qualityProvider;
|
||||
}
|
||||
|
||||
public UpgradePossibleSpecification()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual bool IsSatisfiedBy(Episode subject)
|
||||
{
|
||||
//Used to check if the existing episode can be upgraded by searching (Before we search)
|
||||
if (subject.EpisodeFileId == 0)
|
||||
return true;
|
||||
|
||||
var profile = _qualityProvider.Get(subject.Series.QualityProfileId);
|
||||
|
||||
|
||||
//TODO:How about proper?
|
||||
if (subject.EpisodeFile.Quality >= profile.Cutoff)
|
||||
return false;
|
||||
|
||||
return true; ;
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.History;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Model;
|
||||
|
@ -4,6 +4,7 @@
|
||||
using NLog;
|
||||
using NzbDrone.Common;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.Model.Notification;
|
||||
@ -11,25 +10,25 @@ namespace NzbDrone.Core.Jobs.Implementations
|
||||
public class EpisodeSearchJob : IJob
|
||||
{
|
||||
private readonly IEpisodeService _episodeService;
|
||||
private readonly UpgradePossibleSpecification _upgradePossibleSpecification;
|
||||
private readonly IQualityUpgradableSpecification _qualityUpgradableSpecification;
|
||||
private readonly EpisodeSearch _episodeSearch;
|
||||
private readonly DailyEpisodeSearch _dailyEpisodeSearch;
|
||||
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public EpisodeSearchJob(IEpisodeService episodeService, UpgradePossibleSpecification upgradePossibleSpecification,
|
||||
public EpisodeSearchJob(IEpisodeService episodeService, IQualityUpgradableSpecification qualityUpgradableSpecification,
|
||||
EpisodeSearch episodeSearch, DailyEpisodeSearch dailyEpisodeSearch)
|
||||
{
|
||||
if(dailyEpisodeSearch == null) throw new ArgumentNullException("dailyEpisodeSearch");
|
||||
if (dailyEpisodeSearch == null) throw new ArgumentNullException("dailyEpisodeSearch");
|
||||
_episodeService = episodeService;
|
||||
_upgradePossibleSpecification = upgradePossibleSpecification;
|
||||
_qualityUpgradableSpecification = qualityUpgradableSpecification;
|
||||
_episodeSearch = episodeSearch;
|
||||
_dailyEpisodeSearch = dailyEpisodeSearch;
|
||||
}
|
||||
|
||||
public EpisodeSearchJob()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
public string Name
|
||||
@ -55,7 +54,7 @@ public virtual void Start(ProgressNotification notification, dynamic options)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_upgradePossibleSpecification.IsSatisfiedBy(episode))
|
||||
if (!_qualityUpgradableSpecification.IsUpgradable(episode.Series.QualityProfile, episode.EpisodeFile.QualityModel))
|
||||
{
|
||||
logger.Info("Search for {0} was aborted, file in disk meets or exceeds Profile's Cutoff", episode);
|
||||
notification.CurrentMessage = String.Format("Skipping search for {0}, the file you have is already at cutoff", episode);
|
||||
@ -76,7 +75,7 @@ public virtual void Start(ProgressNotification notification, dynamic options)
|
||||
|
||||
else
|
||||
{
|
||||
_episodeSearch.Search(episode.Series, new { Episode = episode }, notification);
|
||||
_episodeSearch.Search(episode.Series, new { Episode = episode }, notification);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
using NLog;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Model;
|
||||
|
@ -34,7 +34,7 @@ public EpisodeFile(EpisodeFile source)
|
||||
public string SceneName { get; set; }
|
||||
public string ReleaseGroup { get; set; }
|
||||
|
||||
public QualityModel QualityWrapper
|
||||
public QualityModel QualityModel
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -188,6 +188,18 @@
|
||||
<Compile Include="Datastore\BasicRepository.cs" />
|
||||
<Compile Include="Datastore\ObjectDbFactory.cs" />
|
||||
<Compile Include="Datastore\SiaqodbProxy.cs" />
|
||||
<Compile Include="DecisionEngine\IFetchableSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\Specifications\AcceptableSizeSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\AllowedDownloadSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\Specifications\AllowedReleaseGroupSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\Specifications\NotInQueueSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\Specifications\CustomStartDateSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\Specifications\LanguageSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\Specifications\MonitoredEpisodeSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\Specifications\QualityAllowedByProfileSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\QualityUpgradableSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\Specifications\UpgradeDiskSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\Specifications\UpgradeHistorySpecification.cs" />
|
||||
<Compile Include="Download\EpisodeDownloadedEvent.cs" />
|
||||
<Compile Include="Download\EpisodeGrabbedEvent.cs" />
|
||||
<Compile Include="Download\SeriesRenamedEvent.cs" />
|
||||
@ -299,11 +311,8 @@
|
||||
<Compile Include="Model\Xem\XemValues.cs" />
|
||||
<Compile Include="AutofacSignalrDependencyResolver.cs" />
|
||||
<Compile Include="MediaCover\MediaCoverService.cs" />
|
||||
<Compile Include="DecisionEngine\LanguageSpecification.cs" />
|
||||
<Compile Include="Download\Clients\Nzbget\NzbgetProvider.cs" />
|
||||
<Compile Include="Providers\MediaInfoProvider.cs" />
|
||||
<Compile Include="DecisionEngine\AllowedReleaseGroupSpecification.cs" />
|
||||
<Compile Include="DecisionEngine\CustomStartDateSpecification.cs" />
|
||||
<Compile Include="Download\Clients\PneumaticProvider.cs" />
|
||||
<Compile Include="Indexers\Nzbx.cs" />
|
||||
<Compile Include="Indexers\NzbClub.cs" />
|
||||
@ -346,34 +355,7 @@
|
||||
<Compile Include="Configuration\ConfigService.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DecisionEngine\AcceptableSizeSpecification.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DecisionEngine\AllowedDownloadSpecification.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DecisionEngine\AlreadyInQueueSpecification.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DecisionEngine\MonitoredEpisodeSpecification.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DecisionEngine\QualityAllowedByProfileSpecification.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DecisionEngine\QualityUpgradeSpecification.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DecisionEngine\RetentionSpecification.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DecisionEngine\UpgradeDiskSpecification.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DecisionEngine\UpgradeHistorySpecification.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="DecisionEngine\UpgradePossibleSpecification.cs">
|
||||
<Compile Include="DecisionEngine\Specifications\RetentionSpecification.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Providers\DiskScanProvider.cs">
|
||||
|
@ -140,7 +140,7 @@ public virtual EpisodeFile ImportFile(Series series, string filePath)
|
||||
}
|
||||
|
||||
//Make sure this file is an upgrade for ALL episodes already on disk
|
||||
if (episodes.All(e => e.EpisodeFile == null || e.EpisodeFile.QualityWrapper <= parseResult.Quality))
|
||||
if (episodes.All(e => e.EpisodeFile == null || e.EpisodeFile.QualityModel <= parseResult.Quality))
|
||||
{
|
||||
Logger.Debug("Deleting the existing file(s) on disk to upgrade to: {0}", filePath);
|
||||
//Do the delete for files where there is already an episode on disk
|
||||
|
@ -4,6 +4,7 @@
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.ReferenceData;
|
||||
|
@ -4,6 +4,7 @@
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.ReferenceData;
|
||||
|
@ -4,6 +4,7 @@
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NLog;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.ReferenceData;
|
||||
|
@ -4,6 +4,7 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using NLog;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Download;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.ReferenceData;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<SolutionConfiguration>
|
||||
<FileVersion>1</FileVersion>
|
||||
<AutoEnableOnStartup>False</AutoEnableOnStartup>
|
||||
<AutoEnableOnStartup>True</AutoEnableOnStartup>
|
||||
<AllowParallelTestExecution>true</AllowParallelTestExecution>
|
||||
<AllowTestsToRunInParallelWithThemselves>true</AllowTestsToRunInParallelWithThemselves>
|
||||
<FrameworkUtilisationTypeForNUnit>UseDynamicAnalysis</FrameworkUtilisationTypeForNUnit>
|
||||
|
Loading…
Reference in New Issue
Block a user