1
0
mirror of https://github.com/Radarr/Radarr.git synced 2026-04-17 21:26:22 -04:00

New: Quality Preferred Setting

This commit is contained in:
Qstick
2020-02-11 20:31:44 -05:00
parent ea18a366c4
commit 43c48bf833
12 changed files with 370 additions and 138 deletions

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using FizzWare.NBuilder;
@@ -37,9 +37,20 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
_customFormat2 = new CustomFormat("My Format 2", new LanguageSpecification { Value = (int)Language.French }) { Id = 2 };
CustomFormatsFixture.GivenCustomFormats(_customFormat1, _customFormat2);
Mocker.GetMock<IQualityDefinitionService>()
.Setup(s => s.Get(It.IsAny<Quality>()))
.Returns(new QualityDefinition { PreferredSize = null });
}
private RemoteMovie GivenRemoteMovie(QualityModel quality, int age = 0, long size = 0, DownloadProtocol downloadProtocol = DownloadProtocol.Usenet)
private void GivenPreferredSize(double? size)
{
Mocker.GetMock<IQualityDefinitionService>()
.Setup(s => s.Get(It.IsAny<Quality>()))
.Returns(new QualityDefinition { PreferredSize = size });
}
private RemoteMovie GivenRemoteMovie(QualityModel quality, int age = 0, long size = 0, DownloadProtocol downloadProtocol = DownloadProtocol.Usenet, int runtime = 150)
{
var remoteMovie = new RemoteMovie();
remoteMovie.ParsedMovieInfo = new ParsedMovieInfo();
@@ -54,7 +65,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
FormatItems = CustomFormatsFixture.GetSampleFormatItems(_customFormat1.Name, _customFormat2.Name),
MinFormatScore = 0
})
.With(m => m.Title = "A Movie").Build();
.With(m => m.Title = "A Movie")
.With(m => m.Runtime = runtime).Build();
remoteMovie.Release = new ReleaseInfo();
remoteMovie.Release.PublishDate = DateTime.Now.AddDays(-age);
@@ -81,12 +93,12 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test]
public void should_put_propers_before_non_propers()
{
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p, new Revision(version: 1)));
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p, new Revision(version: 2)));
var remoteMovie1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p, new Revision(version: 1)));
var remoteMovie2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p, new Revision(version: 2)));
var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode1));
decisions.Add(new DownloadDecision(remoteEpisode2));
decisions.Add(new DownloadDecision(remoteMovie1));
decisions.Add(new DownloadDecision(remoteMovie2));
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
qualifiedReports.First().RemoteMovie.ParsedMovieInfo.Quality.Revision.Version.Should().Be(2);
@@ -95,12 +107,12 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test]
public void should_put_higher_quality_before_lower()
{
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.SDTV));
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var remoteMovie1 = GivenRemoteMovie(new QualityModel(Quality.SDTV));
var remoteMovie2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode1));
decisions.Add(new DownloadDecision(remoteEpisode2));
decisions.Add(new DownloadDecision(remoteMovie1));
decisions.Add(new DownloadDecision(remoteMovie2));
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
qualifiedReports.First().RemoteMovie.ParsedMovieInfo.Quality.Quality.Should().Be(Quality.HDTV720p);
@@ -109,33 +121,105 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test]
public void should_order_by_age_then_largest_rounded_to_200mb()
{
var remoteEpisodeSd = GivenRemoteMovie(new QualityModel(Quality.SDTV), size: 100.Megabytes(), age: 1);
var remoteEpisodeHdSmallOld = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 1200.Megabytes(), age: 1000);
var remoteEpisodeSmallYoung = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 1250.Megabytes(), age: 10);
var remoteEpisodeHdLargeYoung = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 3000.Megabytes(), age: 1);
var remoteMovieSd = GivenRemoteMovie(new QualityModel(Quality.SDTV), size: 100.Megabytes(), age: 1);
var remoteMovieHdSmallOld = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 1200.Megabytes(), age: 1000);
var remoteMovieSmallYoung = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 1250.Megabytes(), age: 10);
var remoteMovieHdLargeYoung = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 3000.Megabytes(), age: 1);
var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisodeSd));
decisions.Add(new DownloadDecision(remoteEpisodeHdSmallOld));
decisions.Add(new DownloadDecision(remoteEpisodeSmallYoung));
decisions.Add(new DownloadDecision(remoteEpisodeHdLargeYoung));
decisions.Add(new DownloadDecision(remoteMovieSd));
decisions.Add(new DownloadDecision(remoteMovieHdSmallOld));
decisions.Add(new DownloadDecision(remoteMovieSmallYoung));
decisions.Add(new DownloadDecision(remoteMovieHdLargeYoung));
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
qualifiedReports.First().RemoteMovie.Should().Be(remoteEpisodeHdLargeYoung);
qualifiedReports.First().RemoteMovie.Should().Be(remoteMovieHdLargeYoung);
}
[Test]
public void should_order_by_closest_to_preferred_size_if_both_over()
{
// 2 MB/Min * 150 Min Runtime = 300 MB
GivenPreferredSize(2);
var remoteMovieSmall = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 400.Megabytes(), age: 1);
var remoteMovieLarge = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 15000.Megabytes(), age: 1);
var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteMovieSmall));
decisions.Add(new DownloadDecision(remoteMovieLarge));
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
qualifiedReports.First().RemoteMovie.Should().Be(remoteMovieSmall);
}
[Test]
public void should_order_by_largest_to_if_zero_runtime()
{
// 2 MB/Min * 150 Min Runtime = 300 MB
GivenPreferredSize(2);
var remoteMovieSmall = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 400.Megabytes(), age: 1, runtime: 0);
var remoteMovieLarge = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 15000.Megabytes(), age: 1, runtime: 0);
var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteMovieSmall));
decisions.Add(new DownloadDecision(remoteMovieLarge));
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
qualifiedReports.First().RemoteMovie.Should().Be(remoteMovieLarge);
}
[Test]
public void should_order_by_closest_to_preferred_size_if_both_under()
{
// 390 MB/Min * 150 Min Runtime = 58,500 MB
GivenPreferredSize(390);
var remoteMovieSmall = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 100.Megabytes(), age: 1);
var remoteMovieLarge = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 15000.Megabytes(), age: 1);
var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteMovieSmall));
decisions.Add(new DownloadDecision(remoteMovieLarge));
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
qualifiedReports.First().RemoteMovie.Should().Be(remoteMovieLarge);
}
[Test]
public void should_order_by_closest_to_preferred_size_if_preferred_is_in_between()
{
// 46 MB/Min * 150 Min Runtime = 6900 MB
GivenPreferredSize(46);
var remoteMovie1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 100.Megabytes(), age: 1);
var remoteMovie2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 500.Megabytes(), age: 1);
var remoteMovie3 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 7000.Megabytes(), age: 1);
var remoteMovie4 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 15000.Megabytes(), age: 1);
var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteMovie1));
decisions.Add(new DownloadDecision(remoteMovie2));
decisions.Add(new DownloadDecision(remoteMovie3));
decisions.Add(new DownloadDecision(remoteMovie4));
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
qualifiedReports.First().RemoteMovie.Should().Be(remoteMovie3);
}
[Test]
public void should_order_by_youngest()
{
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), age: 10);
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), age: 5);
var remoteMovie1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), age: 10);
var remoteMovie2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), age: 5);
var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode1));
decisions.Add(new DownloadDecision(remoteEpisode2));
decisions.Add(new DownloadDecision(remoteMovie1));
decisions.Add(new DownloadDecision(remoteMovie2));
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
qualifiedReports.First().RemoteMovie.Should().Be(remoteEpisode2);
qualifiedReports.First().RemoteMovie.Should().Be(remoteMovie2);
}
[Test]
@@ -143,12 +227,12 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{
GivenPreferredDownloadProtocol(DownloadProtocol.Usenet);
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), downloadProtocol: DownloadProtocol.Torrent);
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), downloadProtocol: DownloadProtocol.Usenet);
var remoteMovie1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), downloadProtocol: DownloadProtocol.Torrent);
var remoteMovie2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), downloadProtocol: DownloadProtocol.Usenet);
var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode1));
decisions.Add(new DownloadDecision(remoteEpisode2));
decisions.Add(new DownloadDecision(remoteMovie1));
decisions.Add(new DownloadDecision(remoteMovie2));
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
qualifiedReports.First().RemoteMovie.Release.DownloadProtocol.Should().Be(DownloadProtocol.Usenet);
@@ -159,12 +243,12 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{
GivenPreferredDownloadProtocol(DownloadProtocol.Torrent);
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), downloadProtocol: DownloadProtocol.Torrent);
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), downloadProtocol: DownloadProtocol.Usenet);
var remoteMovie1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), downloadProtocol: DownloadProtocol.Torrent);
var remoteMovie2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), downloadProtocol: DownloadProtocol.Usenet);
var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode1));
decisions.Add(new DownloadDecision(remoteEpisode2));
decisions.Add(new DownloadDecision(remoteMovie1));
decisions.Add(new DownloadDecision(remoteMovie2));
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
qualifiedReports.First().RemoteMovie.Release.DownloadProtocol.Should().Be(DownloadProtocol.Torrent);
@@ -173,8 +257,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test]
public void should_prefer_releases_with_more_seeders()
{
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var remoteMovie1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var remoteMovie2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var torrentInfo1 = new TorrentInfo();
torrentInfo1.PublishDate = DateTime.Now;
@@ -185,14 +269,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
var torrentInfo2 = torrentInfo1.JsonClone();
torrentInfo2.Seeders = 100;
remoteEpisode1.Release = torrentInfo1;
remoteEpisode1.Release.Title = "A Movie 1998";
remoteEpisode2.Release = torrentInfo2;
remoteEpisode2.Release.Title = "A Movie 1998";
remoteMovie1.Release = torrentInfo1;
remoteMovie1.Release.Title = "A Movie 1998";
remoteMovie2.Release = torrentInfo2;
remoteMovie2.Release.Title = "A Movie 1998";
var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode1));
decisions.Add(new DownloadDecision(remoteEpisode2));
decisions.Add(new DownloadDecision(remoteMovie1));
decisions.Add(new DownloadDecision(remoteMovie2));
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
((TorrentInfo)qualifiedReports.First().RemoteMovie.Release).Seeders.Should().Be(torrentInfo2.Seeders);
@@ -201,8 +285,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test]
public void should_prefer_releases_with_more_peers_given_equal_number_of_seeds()
{
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var remoteMovie1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var remoteMovie2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var torrentInfo1 = new TorrentInfo();
torrentInfo1.PublishDate = DateTime.Now;
@@ -214,14 +298,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
var torrentInfo2 = torrentInfo1.JsonClone();
torrentInfo2.Peers = 100;
remoteEpisode1.Release = torrentInfo1;
remoteEpisode1.Release.Title = "A Movie 1998";
remoteEpisode2.Release = torrentInfo2;
remoteEpisode2.Release.Title = "A Movie 1998";
remoteMovie1.Release = torrentInfo1;
remoteMovie1.Release.Title = "A Movie 1998";
remoteMovie2.Release = torrentInfo2;
remoteMovie2.Release.Title = "A Movie 1998";
var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode1));
decisions.Add(new DownloadDecision(remoteEpisode2));
decisions.Add(new DownloadDecision(remoteMovie1));
decisions.Add(new DownloadDecision(remoteMovie2));
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
((TorrentInfo)qualifiedReports.First().RemoteMovie.Release).Peers.Should().Be(torrentInfo2.Peers);
@@ -230,8 +314,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test]
public void should_prefer_releases_with_more_peers_no_seeds()
{
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var remoteMovie1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var remoteMovie2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var torrentInfo1 = new TorrentInfo();
torrentInfo1.PublishDate = DateTime.Now;
@@ -244,14 +328,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
torrentInfo2.Seeders = 0;
torrentInfo2.Peers = 100;
remoteEpisode1.Release = torrentInfo1;
remoteEpisode1.Release.Title = "A Movie 1998";
remoteEpisode2.Release = torrentInfo2;
remoteEpisode2.Release.Title = "A Movie 1998";
remoteMovie1.Release = torrentInfo1;
remoteMovie1.Release.Title = "A Movie 1998";
remoteMovie2.Release = torrentInfo2;
remoteMovie2.Release.Title = "A Movie 1998";
var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode1));
decisions.Add(new DownloadDecision(remoteEpisode2));
decisions.Add(new DownloadDecision(remoteMovie1));
decisions.Add(new DownloadDecision(remoteMovie2));
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
((TorrentInfo)qualifiedReports.First().RemoteMovie.Release).Peers.Should().Be(torrentInfo2.Peers);
@@ -260,8 +344,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test]
public void should_prefer_first_release_if_peers_and_size_are_too_similar()
{
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var remoteMovie1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var remoteMovie2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var torrentInfo1 = new TorrentInfo();
torrentInfo1.PublishDate = DateTime.Now;
@@ -275,14 +359,14 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
torrentInfo2.Peers = 10;
torrentInfo1.Size = 250.Megabytes();
remoteEpisode1.Release = torrentInfo1;
remoteEpisode1.Release.Title = "A Movie 1998";
remoteEpisode2.Release = torrentInfo2;
remoteEpisode2.Release.Title = "A Movie 1998";
remoteMovie1.Release = torrentInfo1;
remoteMovie1.Release.Title = "A Movie 1998";
remoteMovie2.Release = torrentInfo2;
remoteMovie2.Release.Title = "A Movie 1998";
var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode1));
decisions.Add(new DownloadDecision(remoteEpisode2));
decisions.Add(new DownloadDecision(remoteMovie1));
decisions.Add(new DownloadDecision(remoteMovie2));
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
((TorrentInfo)qualifiedReports.First().RemoteMovie.Release).Should().Be(torrentInfo1);
@@ -291,38 +375,38 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
[Test]
public void should_prefer_first_release_if_age_and_size_are_too_similar()
{
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var remoteMovie1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var remoteMovie2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
remoteEpisode1.Release.PublishDate = DateTime.UtcNow.AddDays(-100);
remoteEpisode1.Release.Size = 200.Megabytes();
remoteMovie1.Release.PublishDate = DateTime.UtcNow.AddDays(-100);
remoteMovie1.Release.Size = 200.Megabytes();
remoteEpisode2.Release.PublishDate = DateTime.UtcNow.AddDays(-150);
remoteEpisode2.Release.Size = 250.Megabytes();
remoteMovie2.Release.PublishDate = DateTime.UtcNow.AddDays(-150);
remoteMovie2.Release.Size = 250.Megabytes();
var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode1));
decisions.Add(new DownloadDecision(remoteEpisode2));
decisions.Add(new DownloadDecision(remoteMovie1));
decisions.Add(new DownloadDecision(remoteMovie2));
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
qualifiedReports.First().RemoteMovie.Release.Should().Be(remoteEpisode1.Release);
qualifiedReports.First().RemoteMovie.Release.Should().Be(remoteMovie1.Release);
}
[Test]
public void should_prefer_more_prioritized_words()
{
var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var remoteMovie1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
var remoteMovie2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p));
remoteEpisode1.Release.Title += " DTS-HD";
remoteEpisode2.Release.Title += " DTS-HD SPARKS";
remoteMovie1.Release.Title += " DTS-HD";
remoteMovie2.Release.Title += " DTS-HD SPARKS";
var decisions = new List<DownloadDecision>();
decisions.Add(new DownloadDecision(remoteEpisode1));
decisions.Add(new DownloadDecision(remoteEpisode2));
decisions.Add(new DownloadDecision(remoteMovie1));
decisions.Add(new DownloadDecision(remoteMovie2));
var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions);
qualifiedReports.First().RemoteMovie.Release.Should().Be(remoteEpisode2.Release);
qualifiedReports.First().RemoteMovie.Release.Should().Be(remoteMovie2.Release);
}
[Test]

View File

@@ -0,0 +1,56 @@
using System.Collections.Generic;
using System.Data;
using Dapper;
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(171)]
public class quality_definition_preferred_size : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("QualityDefinitions").AddColumn("PreferredSize").AsDouble().Nullable();
Execute.WithConnection(UpdateQualityDefinitions);
}
private void UpdateQualityDefinitions(IDbConnection conn, IDbTransaction tran)
{
var existing = conn.Query<QualityDefinition170>("SELECT Id, MaxSize FROM QualityDefinitions");
var updated = new List<QualityDefinition171>();
foreach (var row in existing)
{
var maxSize = row.MaxSize;
var preferredSize = maxSize;
if (maxSize.HasValue && maxSize.Value > 5)
{
preferredSize = maxSize.Value - 5;
}
updated.Add(new QualityDefinition171
{
Id = row.Id,
PreferredSize = preferredSize
});
}
var updateSql = "UPDATE QualityDefinitions SET PreferredSize = @PreferredSize WHERE Id = @Id";
conn.Execute(updateSql, updated, transaction: tran);
}
private class QualityDefinition170 : ModelBase
{
public int? MaxSize { get; set; }
}
private class QualityDefinition171 : ModelBase
{
public int? PreferredSize { get; set; }
}
}
}

View File

@@ -5,6 +5,7 @@ using NzbDrone.Core.Configuration;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Profiles.Delay;
using NzbDrone.Core.Qualities;
namespace NzbDrone.Core.DecisionEngine
{
@@ -12,14 +13,16 @@ namespace NzbDrone.Core.DecisionEngine
{
private readonly IConfigService _configService;
private readonly IDelayProfileService _delayProfileService;
private readonly IQualityDefinitionService _qualityDefinitionService;
public delegate int CompareDelegate(DownloadDecision x, DownloadDecision y);
public delegate int CompareDelegate<TSubject, TValue>(DownloadDecision x, DownloadDecision y);
public DownloadDecisionComparer(IConfigService configService, IDelayProfileService delayProfileService)
public DownloadDecisionComparer(IConfigService configService, IDelayProfileService delayProfileService, IQualityDefinitionService qualityDefinitionService)
{
_configService = configService;
_delayProfileService = delayProfileService;
_qualityDefinitionService = qualityDefinitionService;
}
public int Compare(DownloadDecision x, DownloadDecision y)
@@ -164,8 +167,25 @@ namespace NzbDrone.Core.DecisionEngine
private int CompareSize(DownloadDecision x, DownloadDecision y)
{
// TODO: Is smaller better? Smaller for usenet could mean no par2 files.
return CompareBy(x.RemoteMovie, y.RemoteMovie, remoteEpisode => remoteEpisode.Release.Size.Round(200.Megabytes()));
var sizeCompare = CompareBy(x.RemoteMovie, y.RemoteMovie, remoteMovie =>
{
var preferredSize = _qualityDefinitionService.Get(remoteMovie.ParsedMovieInfo.Quality.Quality).PreferredSize;
// If no value for preferred it means unlimited so fallback to sort largest is best
if (preferredSize.HasValue && remoteMovie.Movie.Runtime > 0)
{
var preferredMovieSize = remoteMovie.Movie.Runtime * preferredSize.Value.Megabytes();
// Calculate closest to the preferred size
return Math.Abs((remoteMovie.Release.Size - preferredMovieSize).Round(200.Megabytes())) * (-1);
}
else
{
return remoteMovie.Release.Size.Round(200.Megabytes());
}
});
return sizeCompare;
}
private int ScoreFlags(IndexerFlags flags)

View File

@@ -3,6 +3,7 @@ using System.Linq;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Profiles.Delay;
using NzbDrone.Core.Qualities;
namespace NzbDrone.Core.DecisionEngine
{
@@ -15,11 +16,13 @@ namespace NzbDrone.Core.DecisionEngine
{
private readonly IConfigService _configService;
private readonly IDelayProfileService _delayProfileService;
private readonly IQualityDefinitionService _qualityDefinitionService;
public DownloadDecisionPriorizationService(IConfigService configService, IDelayProfileService delayProfileService)
public DownloadDecisionPriorizationService(IConfigService configService, IDelayProfileService delayProfileService, IQualityDefinitionService qualityDefinitionService)
{
_configService = configService;
_delayProfileService = delayProfileService;
_qualityDefinitionService = qualityDefinitionService;
}
public List<DownloadDecision> PrioritizeDecisionsForMovies(List<DownloadDecision> decisions)
@@ -27,7 +30,7 @@ namespace NzbDrone.Core.DecisionEngine
return decisions.Where(c => c.RemoteMovie.MappingResult == MappingResultType.Success || c.RemoteMovie.MappingResult == MappingResultType.SuccessLenientMapping)
.GroupBy(c => c.RemoteMovie.Movie.Id, (movieId, downloadDecisions) =>
{
return downloadDecisions.OrderByDescending(decision => decision, new DownloadDecisionComparer(_configService, _delayProfileService));
return downloadDecisions.OrderByDescending(decision => decision, new DownloadDecisionComparer(_configService, _delayProfileService, _qualityDefinitionService));
})
.SelectMany(c => c)
.Union(decisions.Where(c => c.RemoteMovie.MappingResult != MappingResultType.Success || c.RemoteMovie.MappingResult != MappingResultType.SuccessLenientMapping))

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.Datastore;
@@ -167,41 +167,41 @@ namespace NzbDrone.Core.Qualities
#if !LIBRARY
DefaultQualityDefinitions = new HashSet<QualityDefinition>
{
new QualityDefinition(Quality.Unknown) { Weight = 1, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.WORKPRINT) { Weight = 2, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.CAM) { Weight = 3, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.TELESYNC) { Weight = 4, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.TELECINE) { Weight = 5, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.REGIONAL) { Weight = 6, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.DVDSCR) { Weight = 7, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.SDTV) { Weight = 8, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.DVD) { Weight = 9, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.DVDR) { Weight = 10, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.Unknown) { Weight = 1, MinSize = 0, MaxSize = 100, PreferredSize = 95 },
new QualityDefinition(Quality.WORKPRINT) { Weight = 2, MinSize = 0, MaxSize = 100, PreferredSize = 95 },
new QualityDefinition(Quality.CAM) { Weight = 3, MinSize = 0, MaxSize = 100, PreferredSize = 95 },
new QualityDefinition(Quality.TELESYNC) { Weight = 4, MinSize = 0, MaxSize = 100, PreferredSize = 95 },
new QualityDefinition(Quality.TELECINE) { Weight = 5, MinSize = 0, MaxSize = 100, PreferredSize = 95 },
new QualityDefinition(Quality.REGIONAL) { Weight = 6, MinSize = 0, MaxSize = 100, PreferredSize = 95 },
new QualityDefinition(Quality.DVDSCR) { Weight = 7, MinSize = 0, MaxSize = 100, PreferredSize = 95 },
new QualityDefinition(Quality.SDTV) { Weight = 8, MinSize = 0, MaxSize = 100, PreferredSize = 95 },
new QualityDefinition(Quality.DVD) { Weight = 9, MinSize = 0, MaxSize = 100, PreferredSize = 95 },
new QualityDefinition(Quality.DVDR) { Weight = 10, MinSize = 0, MaxSize = 100, PreferredSize = 95 },
new QualityDefinition(Quality.WEBDL480p) { Weight = 11, MinSize = 0, MaxSize = 100, GroupName = "WEB 480p" },
new QualityDefinition(Quality.WEBRip480p) { Weight = 11, MinSize = 0, MaxSize = 100, GroupName = "WEB 480p" },
new QualityDefinition(Quality.Bluray480p) { Weight = 12, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.Bluray576p) { Weight = 13, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.WEBDL480p) { Weight = 11, MinSize = 0, MaxSize = 100, PreferredSize = 95, GroupName = "WEB 480p" },
new QualityDefinition(Quality.WEBRip480p) { Weight = 11, MinSize = 0, MaxSize = 100, PreferredSize = 95, GroupName = "WEB 480p" },
new QualityDefinition(Quality.Bluray480p) { Weight = 12, MinSize = 0, MaxSize = 100, PreferredSize = 95 },
new QualityDefinition(Quality.Bluray576p) { Weight = 13, MinSize = 0, MaxSize = 100, PreferredSize = 95 },
new QualityDefinition(Quality.HDTV720p) { Weight = 14, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.WEBDL720p) { Weight = 15, MinSize = 0, MaxSize = 100, GroupName = "WEB 720p" },
new QualityDefinition(Quality.WEBRip720p) { Weight = 15, MinSize = 0, MaxSize = 100, GroupName = "WEB 720p" },
new QualityDefinition(Quality.Bluray720p) { Weight = 16, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.HDTV720p) { Weight = 14, MinSize = 0, MaxSize = 100, PreferredSize = 95 },
new QualityDefinition(Quality.WEBDL720p) { Weight = 15, MinSize = 0, MaxSize = 100, PreferredSize = 95, GroupName = "WEB 720p" },
new QualityDefinition(Quality.WEBRip720p) { Weight = 15, MinSize = 0, MaxSize = 100, PreferredSize = 95, GroupName = "WEB 720p" },
new QualityDefinition(Quality.Bluray720p) { Weight = 16, MinSize = 0, MaxSize = 100, PreferredSize = 95 },
new QualityDefinition(Quality.HDTV1080p) { Weight = 17, MinSize = 0, MaxSize = 100 },
new QualityDefinition(Quality.WEBDL1080p) { Weight = 18, MinSize = 0, MaxSize = 100, GroupName = "WEB 1080p" },
new QualityDefinition(Quality.WEBRip1080p) { Weight = 18, MinSize = 0, MaxSize = 100, GroupName = "WEB 1080p" },
new QualityDefinition(Quality.Bluray1080p) { Weight = 19, MinSize = 0, MaxSize = null },
new QualityDefinition(Quality.Remux1080p) { Weight = 20, MinSize = 0, MaxSize = null },
new QualityDefinition(Quality.HDTV1080p) { Weight = 17, MinSize = 0, MaxSize = 100, PreferredSize = 95 },
new QualityDefinition(Quality.WEBDL1080p) { Weight = 18, MinSize = 0, MaxSize = 100, PreferredSize = 95, GroupName = "WEB 1080p" },
new QualityDefinition(Quality.WEBRip1080p) { Weight = 18, MinSize = 0, MaxSize = 100, PreferredSize = 95, GroupName = "WEB 1080p" },
new QualityDefinition(Quality.Bluray1080p) { Weight = 19, MinSize = 0, MaxSize = null, PreferredSize = null },
new QualityDefinition(Quality.Remux1080p) { Weight = 20, MinSize = 0, MaxSize = null, PreferredSize = null },
new QualityDefinition(Quality.HDTV2160p) { Weight = 21, MinSize = 0, MaxSize = null },
new QualityDefinition(Quality.WEBDL2160p) { Weight = 22, MinSize = 0, MaxSize = null, GroupName = "WEB 2160p" },
new QualityDefinition(Quality.WEBRip2160p) { Weight = 22, MinSize = 0, MaxSize = null, GroupName = "WEB 2160p" },
new QualityDefinition(Quality.Bluray2160p) { Weight = 23, MinSize = 0, MaxSize = null },
new QualityDefinition(Quality.Remux2160p) { Weight = 24, MinSize = 0, MaxSize = null },
new QualityDefinition(Quality.HDTV2160p) { Weight = 21, MinSize = 0, MaxSize = null, PreferredSize = null },
new QualityDefinition(Quality.WEBDL2160p) { Weight = 22, MinSize = 0, MaxSize = null, PreferredSize = null, GroupName = "WEB 2160p" },
new QualityDefinition(Quality.WEBRip2160p) { Weight = 22, MinSize = 0, MaxSize = null, PreferredSize = null, GroupName = "WEB 2160p" },
new QualityDefinition(Quality.Bluray2160p) { Weight = 23, MinSize = 0, MaxSize = null, PreferredSize = null },
new QualityDefinition(Quality.Remux2160p) { Weight = 24, MinSize = 0, MaxSize = null, PreferredSize = null },
new QualityDefinition(Quality.BRDISK) { Weight = 25, MinSize = 0, MaxSize = null },
new QualityDefinition(Quality.RAWHD) { Weight = 26, MinSize = 0, MaxSize = null }
new QualityDefinition(Quality.BRDISK) { Weight = 25, MinSize = 0, MaxSize = null, PreferredSize = null },
new QualityDefinition(Quality.RAWHD) { Weight = 26, MinSize = 0, MaxSize = null, PreferredSize = null }
};
#endif
}

View File

@@ -12,6 +12,7 @@ namespace NzbDrone.Core.Qualities
public double? MinSize { get; set; }
public double? MaxSize { get; set; }
public double? PreferredSize { get; set; }
public QualityDefinition()
{

View File

@@ -15,6 +15,7 @@ namespace Radarr.Api.V3.Qualities
public double? MinSize { get; set; }
public double? MaxSize { get; set; }
public double? PreferredSize { get; set; }
}
public static class QualityDefinitionResourceMapper
@@ -38,6 +39,7 @@ namespace Radarr.Api.V3.Qualities
MinSize = model.MinSize,
MaxSize = model.MaxSize,
PreferredSize = model.PreferredSize
};
}
@@ -60,6 +62,7 @@ namespace Radarr.Api.V3.Qualities
MinSize = resource.MinSize,
MaxSize = resource.MaxSize,
PreferredSize = resource.PreferredSize
};
}