New: Option to not prefer repacks/propers (for use with Preferred Words)

Closes #3084
pull/3105/head
Mark McDowall 6 years ago
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 @@ namespace NzbDrone.Api.Config
{
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 @@ namespace NzbDrone.Api.Config
{
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 NUnit.Framework;
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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
}
[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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
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.Parser.Model;
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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
_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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
[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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
[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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
}
[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 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
Subject.IsUpgradable(
profile,
langProfile,
new QualityModel(Quality.DVD, new Revision(version: 2)),
new QualityModel(Quality.DVD, new Revision(version: 1)),
Language.English,
NoPreferredWordScore,
new QualityModel(Quality.DVD, new Revision(version: 2)),
Language.English,
NoPreferredWordScore)
.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();
.Should().BeFalse();
}
}
}

@ -9,6 +9,7 @@ using NzbDrone.Core.MediaFiles;
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 @@ namespace NzbDrone.Core.Configuration
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 System.Collections.Generic;
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 @@ namespace NzbDrone.Core.Configuration
//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 @@ namespace NzbDrone.Core.DecisionEngine
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 @@ namespace NzbDrone.Core.DecisionEngine
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 @@ namespace NzbDrone.Core.DecisionEngine
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 NLog;
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,20 +31,28 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
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 (file.DateAdded < DateTime.Today.AddDays(-7))
if (downloadPropersAndRepacks == ProperDownloadTypes.DoNotUpgrade)
{
_logger.Debug("Proper for old file, rejecting: {0}", subject);
return Decision.Reject("Proper for old file");
_logger.Debug("Auto downloading of propers is disabled");
return Decision.Reject("Proper downloading is disabled");
}
if (!_configService.AutoDownloadPropers)
if (file.DateAdded < DateTime.Today.AddDays(-7))
{
_logger.Debug("Auto downloading of propers is disabled");
return Decision.Reject("Proper downloading is disabled");
_logger.Debug("Proper for old file, rejecting: {0}", subject);
return Decision.Reject("Proper for old file");
}
}
}

@ -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 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
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 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
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;
}
var languageCompare = new LanguageComparer(languageProfile).Compare(newLanguage, currentLanguage);
if (languageCompare > 0)
{
return true;
}
if (new LanguageComparer(languageProfile).Compare(newLanguage, currentLanguage) < 0)
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" />

@ -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 @@ namespace Sonarr.Api.V3.Config
{
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 @@ namespace Sonarr.Api.V3.Config
{
AutoUnmonitorPreviouslyDownloadedEpisodes = model.AutoUnmonitorPreviouslyDownloadedEpisodes,
RecycleBin = model.RecycleBin,
AutoDownloadPropers = model.AutoDownloadPropers,
DownloadPropersAndRepacks = model.DownloadPropersAndRepacks,
CreateEmptySeriesFolders = model.CreateEmptySeriesFolders,
DeleteEmptyFolders = model.DeleteEmptyFolders,
FileDate = model.FileDate,

Loading…
Cancel
Save