mirror of
https://github.com/Sonarr/Sonarr.git
synced 2025-01-15 10:39:47 +02:00
New: Option to not prefer repacks/propers (for use with Preferred Words)
Closes #3084
This commit is contained in:
parent
a06cbc44cd
commit
7321075631
@ -25,6 +25,12 @@ const rescanAfterRefreshOptions = [
|
||||
{ key: 'never', value: 'Never' }
|
||||
];
|
||||
|
||||
const downloadPropersAndRepacksOptions = [
|
||||
{ key: 'preferAndUpgrade', value: 'Prefer and Upgrade' },
|
||||
{ key: 'doNotUpgrade', value: 'Do not Upgrade Automatically' },
|
||||
{ key: 'doNotPrefer', value: 'Do not Prefer' }
|
||||
];
|
||||
|
||||
const fileDateOptions = [
|
||||
{ key: 'none', value: 'None' },
|
||||
{ key: 'localAirDate', value: 'Local Air Date' },
|
||||
@ -227,14 +233,23 @@ class MediaManagement extends Component {
|
||||
isAdvanced={true}
|
||||
size={sizes.MEDIUM}
|
||||
>
|
||||
<FormLabel>Download Propers</FormLabel>
|
||||
<FormLabel>Propers and Repacks</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="autoDownloadPropers"
|
||||
helpText="Should Sonarr automatically upgrade to propers when available?"
|
||||
type={inputTypes.SELECT}
|
||||
name="downloadPropersAndRepacks"
|
||||
helpTexts={[
|
||||
'Whether or not to automatically upgrade to Propers/Repacks',
|
||||
'Use \'Do not Prefer\' to sort by preferred word score over propers/repacks'
|
||||
]}
|
||||
helpTextWarning={
|
||||
settings.downloadPropersAndRepacks.value === 'doNotPrefer' ?
|
||||
'Use preferred words for automatic upgrades to propers/repacks' :
|
||||
undefined
|
||||
}
|
||||
values={downloadPropersAndRepacksOptions}
|
||||
onChange={onInputChange}
|
||||
{...settings.autoDownloadPropers}
|
||||
{...settings.downloadPropersAndRepacks}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
using Sonarr.Http.REST;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.Qualities;
|
||||
|
||||
namespace NzbDrone.Api.Config
|
||||
{
|
||||
@ -8,7 +9,7 @@ public class MediaManagementConfigResource : RestResource
|
||||
{
|
||||
public bool AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; }
|
||||
public string RecycleBin { get; set; }
|
||||
public bool AutoDownloadPropers { get; set; }
|
||||
public ProperDownloadTypes DownloadPropersAndRepacks { get; set; }
|
||||
public bool CreateEmptySeriesFolders { get; set; }
|
||||
public bool DeleteEmptyFolders { get; set; }
|
||||
public FileDateType FileDate { get; set; }
|
||||
@ -34,7 +35,7 @@ public static MediaManagementConfigResource ToResource(IConfigService model)
|
||||
{
|
||||
AutoUnmonitorPreviouslyDownloadedEpisodes = model.AutoUnmonitorPreviouslyDownloadedEpisodes,
|
||||
RecycleBin = model.RecycleBin,
|
||||
AutoDownloadPropers = model.AutoDownloadPropers,
|
||||
DownloadPropersAndRepacks = model.DownloadPropersAndRepacks,
|
||||
CreateEmptySeriesFolders = model.CreateEmptySeriesFolders,
|
||||
DeleteEmptyFolders = model.DeleteEmptyFolders,
|
||||
FileDate = model.FileDate,
|
||||
|
@ -13,6 +13,7 @@
|
||||
using FluentAssertions;
|
||||
using FizzWare.NBuilder;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Profiles.Languages;
|
||||
@ -440,7 +441,7 @@ public void should_order_by_language()
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_put_higher_quality_before_lower_allways()
|
||||
public void should_put_higher_quality_before_lower_always()
|
||||
{
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.SDTV), Language.French);
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.HDTV720p), Language.German);
|
||||
@ -452,5 +453,87 @@ public void should_put_higher_quality_before_lower_allways()
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
qualifiedReports.First().RemoteEpisode.ParsedEpisodeInfo.Quality.Quality.Should().Be(Quality.HDTV720p);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_prefer_higher_score_over_lower_score()
|
||||
{
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.WEBDL1080p), Language.English);
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.WEBDL1080p), Language.English);
|
||||
|
||||
remoteEpisode1.PreferredWordScore = 10;
|
||||
remoteEpisode2.PreferredWordScore = 0;
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
qualifiedReports.First().RemoteEpisode.PreferredWordScore.Should().Be(10);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_prefer_proper_over_score_when_download_propers_is_prefer_and_upgrade()
|
||||
{
|
||||
Mocker.GetMock<IConfigService>()
|
||||
.Setup(s => s.DownloadPropersAndRepacks)
|
||||
.Returns(ProperDownloadTypes.PreferAndUpgrade);
|
||||
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.WEBDL1080p, new Revision(1)), Language.English);
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.WEBDL1080p, new Revision(2)), Language.English);
|
||||
|
||||
remoteEpisode1.PreferredWordScore = 10;
|
||||
remoteEpisode2.PreferredWordScore = 0;
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
qualifiedReports.First().RemoteEpisode.ParsedEpisodeInfo.Quality.Revision.Version.Should().Be(2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_prefer_proper_over_score_when_download_propers_is_do_not_upgrade()
|
||||
{
|
||||
Mocker.GetMock<IConfigService>()
|
||||
.Setup(s => s.DownloadPropersAndRepacks)
|
||||
.Returns(ProperDownloadTypes.DoNotUpgrade);
|
||||
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.WEBDL1080p, new Revision(1)), Language.English);
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.WEBDL1080p, new Revision(2)), Language.English);
|
||||
|
||||
remoteEpisode1.PreferredWordScore = 10;
|
||||
remoteEpisode2.PreferredWordScore = 0;
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
qualifiedReports.First().RemoteEpisode.ParsedEpisodeInfo.Quality.Revision.Version.Should().Be(2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_prefer_score_over_proper_when_download_propers_is_do_not_prefer()
|
||||
{
|
||||
Mocker.GetMock<IConfigService>()
|
||||
.Setup(s => s.DownloadPropersAndRepacks)
|
||||
.Returns(ProperDownloadTypes.DoNotPrefer);
|
||||
|
||||
var remoteEpisode1 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.WEBDL1080p, new Revision(1)), Language.English);
|
||||
var remoteEpisode2 = GivenRemoteEpisode(new List<Episode> { GivenEpisode(1) }, new QualityModel(Quality.WEBDL1080p, new Revision(2)), Language.English);
|
||||
|
||||
remoteEpisode1.PreferredWordScore = 10;
|
||||
remoteEpisode2.PreferredWordScore = 0;
|
||||
|
||||
var decisions = new List<DownloadDecision>();
|
||||
decisions.Add(new DownloadDecision(remoteEpisode1));
|
||||
decisions.Add(new DownloadDecision(remoteEpisode2));
|
||||
|
||||
var qualifiedReports = Subject.PrioritizeDecisions(decisions);
|
||||
qualifiedReports.First().RemoteEpisode.ParsedEpisodeInfo.Quality.Quality.Should().Be(Quality.WEBDL1080p);
|
||||
qualifiedReports.First().RemoteEpisode.ParsedEpisodeInfo.Quality.Revision.Version.Should().Be(1);
|
||||
qualifiedReports.First().RemoteEpisode.PreferredWordScore.Should().Be(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@
|
||||
using NzbDrone.Core.Profiles.Qualities;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
@ -61,13 +60,6 @@ private void WithFirstFileUpgradable()
|
||||
_firstFile.Quality = new QualityModel(Quality.SDTV);
|
||||
}
|
||||
|
||||
private void GivenAutoDownloadPropers()
|
||||
{
|
||||
Mocker.GetMock<IConfigService>()
|
||||
.Setup(s => s.AutoDownloadPropers)
|
||||
.Returns(true);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_when_episodeFile_was_added_more_than_7_days_ago()
|
||||
{
|
||||
@ -118,6 +110,10 @@ public void should_return_true_when_episodeFile_was_added_more_than_7_days_ago_b
|
||||
[Test]
|
||||
public void should_return_false_when_proper_but_auto_download_propers_is_false()
|
||||
{
|
||||
Mocker.GetMock<IConfigService>()
|
||||
.Setup(s => s.DownloadPropersAndRepacks)
|
||||
.Returns(ProperDownloadTypes.DoNotUpgrade);
|
||||
|
||||
_firstFile.Quality.Quality = Quality.DVD;
|
||||
|
||||
_firstFile.DateAdded = DateTime.Today;
|
||||
@ -127,7 +123,22 @@ public void should_return_false_when_proper_but_auto_download_propers_is_false()
|
||||
[Test]
|
||||
public void should_return_true_when_episodeFile_was_added_today()
|
||||
{
|
||||
GivenAutoDownloadPropers();
|
||||
Mocker.GetMock<IConfigService>()
|
||||
.Setup(s => s.DownloadPropersAndRepacks)
|
||||
.Returns(ProperDownloadTypes.PreferAndUpgrade);
|
||||
|
||||
_firstFile.Quality.Quality = Quality.DVD;
|
||||
|
||||
_firstFile.DateAdded = DateTime.Today;
|
||||
Subject.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_true_when_propers_are_not_preferred()
|
||||
{
|
||||
Mocker.GetMock<IConfigService>()
|
||||
.Setup(s => s.DownloadPropersAndRepacks)
|
||||
.Returns(ProperDownloadTypes.DoNotPrefer);
|
||||
|
||||
_firstFile.Quality.Quality = Quality.DVD;
|
||||
|
||||
|
@ -38,17 +38,17 @@ public class UpgradeSpecificationFixture : CoreTest<UpgradableSpecification>
|
||||
|
||||
private static readonly int NoPreferredWordScore = 0;
|
||||
|
||||
private void GivenAutoDownloadPropers(bool autoDownloadPropers)
|
||||
private void GivenAutoDownloadPropers(ProperDownloadTypes type)
|
||||
{
|
||||
Mocker.GetMock<IConfigService>()
|
||||
.SetupGet(s => s.AutoDownloadPropers)
|
||||
.Returns(autoDownloadPropers);
|
||||
.SetupGet(s => s.DownloadPropersAndRepacks)
|
||||
.Returns(type);
|
||||
}
|
||||
|
||||
[Test, TestCaseSource(nameof(IsUpgradeTestCases))]
|
||||
public void IsUpgradeTest(Quality current, int currentVersion, Quality newQuality, int newVersion, Quality cutoff, bool expected)
|
||||
{
|
||||
GivenAutoDownloadPropers(true);
|
||||
GivenAutoDownloadPropers(ProperDownloadTypes.PreferAndUpgrade);
|
||||
|
||||
|
||||
var profile = new QualityProfile
|
||||
@ -79,7 +79,7 @@ public void IsUpgradeTest(Quality current, int currentVersion, Quality newQualit
|
||||
[Test, TestCaseSource("IsUpgradeTestCasesLanguages")]
|
||||
public void IsUpgradeTestLanguage(Quality current, int currentVersion, Language currentLanguage, Quality newQuality, int newVersion, Language newLanguage, Quality cutoff, Language languageCutoff, bool expected)
|
||||
{
|
||||
GivenAutoDownloadPropers(true);
|
||||
GivenAutoDownloadPropers(ProperDownloadTypes.PreferAndUpgrade);
|
||||
|
||||
var profile = new QualityProfile
|
||||
{
|
||||
@ -108,9 +108,9 @@ public void IsUpgradeTestLanguage(Quality current, int currentVersion, Language
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_if_proper_and_autoDownloadPropers_is_false()
|
||||
public void should_return_true_if_proper_and_download_propers_is_do_not_download()
|
||||
{
|
||||
GivenAutoDownloadPropers(false);
|
||||
GivenAutoDownloadPropers(ProperDownloadTypes.DoNotUpgrade);
|
||||
|
||||
var profile = new QualityProfile
|
||||
{
|
||||
@ -127,13 +127,42 @@ public void should_return_false_if_proper_and_autoDownloadPropers_is_false()
|
||||
Subject.IsUpgradable(
|
||||
profile,
|
||||
langProfile,
|
||||
new QualityModel(Quality.DVD, new Revision(version: 2)),
|
||||
Language.English,
|
||||
NoPreferredWordScore,
|
||||
new QualityModel(Quality.DVD, new Revision(version: 1)),
|
||||
Language.English,
|
||||
NoPreferredWordScore,
|
||||
new QualityModel(Quality.DVD, new Revision(version: 2)),
|
||||
Language.English,
|
||||
NoPreferredWordScore)
|
||||
.Should().BeFalse();
|
||||
.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_false_if_proper_and_autoDownloadPropers_is_do_not_prefer()
|
||||
{
|
||||
GivenAutoDownloadPropers(ProperDownloadTypes.DoNotPrefer);
|
||||
|
||||
var profile = new QualityProfile
|
||||
{
|
||||
Items = Qualities.QualityFixture.GetDefaultQualities(),
|
||||
};
|
||||
|
||||
var langProfile = new LanguageProfile
|
||||
{
|
||||
Languages = LanguageFixture.GetDefaultLanguages(),
|
||||
Cutoff = Language.English
|
||||
};
|
||||
|
||||
|
||||
Subject.IsUpgradable(
|
||||
profile,
|
||||
langProfile,
|
||||
new QualityModel(Quality.DVD, new Revision(version: 1)),
|
||||
Language.English,
|
||||
NoPreferredWordScore,
|
||||
new QualityModel(Quality.DVD, new Revision(version: 2)),
|
||||
Language.English,
|
||||
NoPreferredWordScore)
|
||||
.Should().BeFalse();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
using NzbDrone.Common.Http.Proxy;
|
||||
using NzbDrone.Core.MediaFiles.EpisodeImport;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Security;
|
||||
|
||||
namespace NzbDrone.Core.Configuration
|
||||
@ -113,11 +114,11 @@ public int MinimumAge
|
||||
set { SetValue("MinimumAge", value); }
|
||||
}
|
||||
|
||||
public bool AutoDownloadPropers
|
||||
public ProperDownloadTypes DownloadPropersAndRepacks
|
||||
{
|
||||
get { return GetValueBoolean("AutoDownloadPropers", true); }
|
||||
get { return GetValueEnum("DownloadPropersAndRepacks", ProperDownloadTypes.PreferAndUpgrade); }
|
||||
|
||||
set { SetValue("AutoDownloadPropers", value); }
|
||||
set { SetValue("DownloadPropersAndRepacks", value); }
|
||||
}
|
||||
|
||||
public bool EnableCompletedDownloadHandling
|
||||
|
@ -2,6 +2,7 @@
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Common.Http.Proxy;
|
||||
using NzbDrone.Core.MediaFiles.EpisodeImport;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Security;
|
||||
|
||||
namespace NzbDrone.Core.Configuration
|
||||
@ -26,7 +27,7 @@ public interface IConfigService
|
||||
//Media Management
|
||||
bool AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; }
|
||||
string RecycleBin { get; set; }
|
||||
bool AutoDownloadPropers { get; set; }
|
||||
ProperDownloadTypes DownloadPropersAndRepacks { get; set; }
|
||||
bool CreateEmptySeriesFolders { get; set; }
|
||||
bool DeleteEmptyFolders { get; set; }
|
||||
FileDateType FileDate { get; set; }
|
||||
|
@ -0,0 +1,43 @@
|
||||
using System.Data;
|
||||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(131)]
|
||||
public class download_propers_config : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Execute.WithConnection(SetMetadataFileExtension);
|
||||
Execute.Sql("DELETE FROM Config WHERE Key = 'autodownloadpropers'");
|
||||
}
|
||||
|
||||
private void SetMetadataFileExtension(IDbConnection conn, IDbTransaction tran)
|
||||
{
|
||||
using (var cmd = conn.CreateCommand())
|
||||
{
|
||||
cmd.Transaction = tran;
|
||||
cmd.CommandText = "SELECT Value FROM Config WHERE Key = 'autodownloadpropers'";
|
||||
|
||||
using (var reader = cmd.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var value = reader.GetString(0);
|
||||
var newValue = bool.Parse(value) ? "PreferAndUpgrade" : "DoNotUpgrade";
|
||||
|
||||
using (var updateCmd = conn.CreateCommand())
|
||||
{
|
||||
updateCmd.Transaction = tran;
|
||||
updateCmd.CommandText = "INSERT INTO Config (key, value) VALUES ('downloadpropersandrepacks', ?)";
|
||||
updateCmd.AddParameter(newValue);
|
||||
|
||||
updateCmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Profiles.Delay;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine
|
||||
{
|
||||
public class DownloadDecisionComparer : IComparer<DownloadDecision>
|
||||
{
|
||||
private readonly IConfigService _configService;
|
||||
private readonly IDelayProfileService _delayProfileService;
|
||||
|
||||
public delegate int CompareDelegate(DownloadDecision x, DownloadDecision y);
|
||||
public delegate int CompareDelegate<TSubject, TValue>(DownloadDecision x, DownloadDecision y);
|
||||
|
||||
public DownloadDecisionComparer(IDelayProfileService delayProfileService)
|
||||
public DownloadDecisionComparer(IConfigService configService, IDelayProfileService delayProfileService)
|
||||
{
|
||||
_configService = configService;
|
||||
_delayProfileService = delayProfileService;
|
||||
}
|
||||
|
||||
@ -59,6 +64,12 @@ private int CompareAll(params int[] comparers)
|
||||
|
||||
private int CompareQuality(DownloadDecision x, DownloadDecision y)
|
||||
{
|
||||
if (_configService.DownloadPropersAndRepacks == ProperDownloadTypes.DoNotPrefer)
|
||||
{
|
||||
return CompareAll(CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.Series.QualityProfile.Value.GetIndex(remoteEpisode.ParsedEpisodeInfo.Quality.Quality)),
|
||||
CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.ParsedEpisodeInfo.Quality.Revision.Real));
|
||||
}
|
||||
|
||||
return CompareAll(CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.Series.QualityProfile.Value.GetIndex(remoteEpisode.ParsedEpisodeInfo.Quality.Quality)),
|
||||
CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.ParsedEpisodeInfo.Quality.Revision.Real),
|
||||
CompareBy(x.RemoteEpisode, y.RemoteEpisode, remoteEpisode => remoteEpisode.ParsedEpisodeInfo.Quality.Revision.Version));
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Profiles.Delay;
|
||||
using NzbDrone.Core.Languages;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine
|
||||
{
|
||||
@ -12,10 +12,12 @@ public interface IPrioritizeDownloadDecision
|
||||
|
||||
public class DownloadDecisionPriorizationService : IPrioritizeDownloadDecision
|
||||
{
|
||||
private readonly IConfigService _configService;
|
||||
private readonly IDelayProfileService _delayProfileService;
|
||||
|
||||
public DownloadDecisionPriorizationService(IDelayProfileService delayProfileService)
|
||||
public DownloadDecisionPriorizationService(IConfigService configService, IDelayProfileService delayProfileService)
|
||||
{
|
||||
_configService = configService;
|
||||
_delayProfileService = delayProfileService;
|
||||
}
|
||||
|
||||
@ -24,7 +26,7 @@ public List<DownloadDecision> PrioritizeDecisions(List<DownloadDecision> decisio
|
||||
return decisions.Where(c => c.RemoteEpisode.Series != null)
|
||||
.GroupBy(c => c.RemoteEpisode.Series.Id, (seriesId, downloadDecisions) =>
|
||||
{
|
||||
return downloadDecisions.OrderByDescending(decision => decision, new DownloadDecisionComparer(_delayProfileService));
|
||||
return downloadDecisions.OrderByDescending(decision => decision, new DownloadDecisionComparer(_configService, _delayProfileService));
|
||||
})
|
||||
.SelectMany(c => c)
|
||||
.Union(decisions.Where(c => c.RemoteEpisode.Series == null))
|
||||
|
@ -4,6 +4,7 @@
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Qualities;
|
||||
|
||||
namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
|
||||
{
|
||||
@ -30,21 +31,29 @@ public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase
|
||||
return Decision.Accept();
|
||||
}
|
||||
|
||||
var downloadPropersAndRepacks = _configService.DownloadPropersAndRepacks;
|
||||
|
||||
if (downloadPropersAndRepacks == ProperDownloadTypes.DoNotPrefer)
|
||||
{
|
||||
_logger.Debug("Propers are not preferred, skipping check");
|
||||
return Decision.Accept();
|
||||
}
|
||||
|
||||
foreach (var file in subject.Episodes.Where(c => c.EpisodeFileId != 0).Select(c => c.EpisodeFile.Value))
|
||||
{
|
||||
if (_upgradableSpecification.IsRevisionUpgrade(file.Quality, subject.ParsedEpisodeInfo.Quality))
|
||||
{
|
||||
if (downloadPropersAndRepacks == ProperDownloadTypes.DoNotUpgrade)
|
||||
{
|
||||
_logger.Debug("Auto downloading of propers is disabled");
|
||||
return Decision.Reject("Proper downloading is disabled");
|
||||
}
|
||||
|
||||
if (file.DateAdded < DateTime.Today.AddDays(-7))
|
||||
{
|
||||
_logger.Debug("Proper for old file, rejecting: {0}", subject);
|
||||
return Decision.Reject("Proper for old file");
|
||||
}
|
||||
|
||||
if (!_configService.AutoDownloadPropers)
|
||||
{
|
||||
_logger.Debug("Auto downloading of propers is disabled");
|
||||
return Decision.Reject("Proper downloading is disabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using NLog;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Profiles.Languages;
|
||||
using NzbDrone.Core.Profiles.Qualities;
|
||||
@ -18,41 +19,15 @@ public interface IUpgradableSpecification
|
||||
|
||||
public class UpgradableSpecification : IUpgradableSpecification
|
||||
{
|
||||
private readonly IConfigService _configService;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public UpgradableSpecification(Logger logger)
|
||||
public UpgradableSpecification(IConfigService configService, Logger logger)
|
||||
{
|
||||
_configService = configService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
private bool IsLanguageUpgradable(LanguageProfile profile, Language currentLanguage, Language newLanguage = null)
|
||||
{
|
||||
if (newLanguage != null)
|
||||
{
|
||||
var compare = new LanguageComparer(profile).Compare(newLanguage, currentLanguage);
|
||||
if (compare <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool IsQualityUpgradable(QualityProfile profile, QualityModel currentQuality, QualityModel newQuality = null)
|
||||
{
|
||||
if (newQuality != null)
|
||||
{
|
||||
var compare = new QualityModelComparer(profile).Compare(newQuality, currentQuality);
|
||||
|
||||
if (compare <= 0)
|
||||
{
|
||||
_logger.Debug("Existing item has better quality, skipping");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool IsPreferredWordUpgradable(int currentScore, int newScore)
|
||||
{
|
||||
return newScore > currentScore;
|
||||
@ -60,23 +35,36 @@ private bool IsPreferredWordUpgradable(int currentScore, int newScore)
|
||||
|
||||
public bool IsUpgradable(QualityProfile qualityProfile, LanguageProfile languageProfile, QualityModel currentQuality, Language currentLanguage, int currentScore, QualityModel newQuality, Language newLanguage, int newScore)
|
||||
{
|
||||
if (IsQualityUpgradable(qualityProfile, currentQuality, newQuality))
|
||||
var qualityComparer = new QualityModelComparer(qualityProfile);
|
||||
var qualityCompare = qualityComparer.Compare(newQuality?.Quality, currentQuality.Quality);
|
||||
|
||||
if (qualityCompare > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (new QualityModelComparer(qualityProfile).Compare(newQuality, currentQuality) < 0)
|
||||
if (qualityCompare < 0)
|
||||
{
|
||||
_logger.Debug("Existing item has better quality, skipping");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsLanguageUpgradable(languageProfile, currentLanguage, newLanguage))
|
||||
// Accept unless the user doesn't want to prefer propers, optionally they can
|
||||
// use preferred words to prefer propers/repacks over non-propers/repacks.
|
||||
if (_configService.DownloadPropersAndRepacks != ProperDownloadTypes.DoNotPrefer &&
|
||||
newQuality?.Revision.CompareTo(currentQuality.Revision) > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (new LanguageComparer(languageProfile).Compare(newLanguage, currentLanguage) < 0)
|
||||
var languageCompare = new LanguageComparer(languageProfile).Compare(newLanguage, currentLanguage);
|
||||
|
||||
if (languageCompare > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (languageCompare < 0)
|
||||
{
|
||||
_logger.Debug("Existing item has better language, skipping");
|
||||
return false;
|
||||
|
@ -136,6 +136,7 @@
|
||||
<Compile Include="Configuration\InvalidConfigFileException.cs" />
|
||||
<Compile Include="Configuration\RescanAfterRefreshType.cs" />
|
||||
<Compile Include="Configuration\ResetApiKeyCommand.cs" />
|
||||
<Compile Include="Datastore\Migration\131_download_propers_config.cs" />
|
||||
<Compile Include="Datastore\Migration\130_episode_last_searched_time.cs" />
|
||||
<Compile Include="Datastore\Migration\129_add_relative_original_path_to_episode_file.cs" />
|
||||
<Compile Include="Datastore\Migration\128_rename_quality_profiles_add_upgrade_allowed.cs" />
|
||||
@ -1034,6 +1035,7 @@
|
||||
<Compile Include="Profiles\Releases\TermMatchers\ITermMatcher.cs" />
|
||||
<Compile Include="Profiles\Releases\TermMatchers\RegexTermMatcher.cs" />
|
||||
<Compile Include="ProgressMessaging\ProgressMessageContext.cs" />
|
||||
<Compile Include="Qualities\ProperDownloadTypes.cs" />
|
||||
<Compile Include="Qualities\QualityDetectionSource.cs" />
|
||||
<Compile Include="Qualities\QualityFinder.cs" />
|
||||
<Compile Include="Qualities\QualitySource.cs" />
|
||||
|
9
src/NzbDrone.Core/Qualities/ProperDownloadTypes.cs
Normal file
9
src/NzbDrone.Core/Qualities/ProperDownloadTypes.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace NzbDrone.Core.Qualities
|
||||
{
|
||||
public enum ProperDownloadTypes
|
||||
{
|
||||
PreferAndUpgrade,
|
||||
DoNotUpgrade,
|
||||
DoNotPrefer
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
using NzbDrone.Core.MediaFiles.EpisodeImport;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using Sonarr.Http.REST;
|
||||
|
||||
namespace Sonarr.Api.V3.Config
|
||||
@ -9,7 +10,7 @@ public class MediaManagementConfigResource : RestResource
|
||||
{
|
||||
public bool AutoUnmonitorPreviouslyDownloadedEpisodes { get; set; }
|
||||
public string RecycleBin { get; set; }
|
||||
public bool AutoDownloadPropers { get; set; }
|
||||
public ProperDownloadTypes DownloadPropersAndRepacks { get; set; }
|
||||
public bool CreateEmptySeriesFolders { get; set; }
|
||||
public bool DeleteEmptyFolders { get; set; }
|
||||
public FileDateType FileDate { get; set; }
|
||||
@ -37,7 +38,7 @@ public static MediaManagementConfigResource ToResource(IConfigService model)
|
||||
{
|
||||
AutoUnmonitorPreviouslyDownloadedEpisodes = model.AutoUnmonitorPreviouslyDownloadedEpisodes,
|
||||
RecycleBin = model.RecycleBin,
|
||||
AutoDownloadPropers = model.AutoDownloadPropers,
|
||||
DownloadPropersAndRepacks = model.DownloadPropersAndRepacks,
|
||||
CreateEmptySeriesFolders = model.CreateEmptySeriesFolders,
|
||||
DeleteEmptyFolders = model.DeleteEmptyFolders,
|
||||
FileDate = model.FileDate,
|
||||
|
Loading…
Reference in New Issue
Block a user