some preliminary work to move decision engine to use the visitor pattern.

This commit is contained in:
kay.one 2013-03-06 16:19:49 -08:00
commit 02d842a2b2
51 changed files with 470 additions and 507 deletions

View file

@ -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 @@ namespace NzbDrone.Core.DecisionEngine
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 @@ namespace NzbDrone.Core.DecisionEngine
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 @@ namespace NzbDrone.Core.DecisionEngine
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;

View file

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

View file

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

View file

@ -0,0 +1,10 @@
using NzbDrone.Core.Model;
namespace NzbDrone.Core.DecisionEngine
{
public interface IFetchableSpecification
{
string RejectionReason { get; }
bool IsSatisfiedBy(EpisodeParseResult subject);
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 @@ namespace NzbDrone.Core.DecisionEngine
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 @@ namespace NzbDrone.Core.DecisionEngine
//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;
}
}
}

View file

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

View file

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

View file

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

View file

@ -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 @@ namespace NzbDrone.Core.DecisionEngine
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 @@ namespace NzbDrone.Core.DecisionEngine
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 @@ namespace NzbDrone.Core.DecisionEngine
return true;
}
logger.Debug("All episodes are ignored. skipping.");
_logger.Debug("All episodes are ignored. skipping.");
return false;
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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