mirror of
https://github.com/Radarr/Radarr.git
synced 2024-09-17 15:02:34 +02:00
parent
e5278a0243
commit
ab1e82414b
@ -8,11 +8,11 @@ public class QualityDefinitionResource : RestResource
|
||||
{
|
||||
public Quality Quality { get; set; }
|
||||
|
||||
public String Title { get; set; }
|
||||
public string Title { get; set; }
|
||||
|
||||
public Int32 Weight { get; set; }
|
||||
public int Weight { get; set; }
|
||||
|
||||
public Int32 MinSize { get; set; }
|
||||
public Int32 MaxSize { get; set; }
|
||||
public double? MinSize { get; set; }
|
||||
public double? MaxSize { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
[TestFixture]
|
||||
public class update_quality_minmax_size : MigrationTest<Core.Datastore.Migration.update_quality_minmax_size>
|
||||
{
|
||||
[Test]
|
||||
public void should_not_fail_if_empty()
|
||||
{
|
||||
WithTestDb(c =>
|
||||
{
|
||||
|
||||
});
|
||||
|
||||
var items = Mocker.Resolve<QualityDefinitionRepository>().All();
|
||||
|
||||
items.Should().HaveCount(0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_set_rawhd_to_null()
|
||||
{
|
||||
WithTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("QualityDefinitions").Row(new
|
||||
{
|
||||
Quality = 1,
|
||||
Title = "SDTV",
|
||||
MinSize = 0,
|
||||
MaxSize = 100
|
||||
})
|
||||
.Row(new
|
||||
{
|
||||
Quality = 10,
|
||||
Title = "RawHD",
|
||||
MinSize = 0,
|
||||
MaxSize = 100
|
||||
});
|
||||
});
|
||||
|
||||
var items = Mocker.Resolve<QualityDefinitionRepository>().All();
|
||||
|
||||
items.Should().HaveCount(2);
|
||||
|
||||
items.First(v => v.Quality.Id == 10).MaxSize.Should().NotHaveValue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_set_zero_maxsize_to_null()
|
||||
{
|
||||
WithTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("QualityDefinitions").Row(new
|
||||
{
|
||||
Quality = 1,
|
||||
Title = "SDTV",
|
||||
MinSize = 0,
|
||||
MaxSize = 0
|
||||
});
|
||||
});
|
||||
|
||||
var items = Mocker.Resolve<QualityDefinitionRepository>().All();
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
|
||||
items.First(v => v.Quality.Id == 1).MaxSize.Should().NotHaveValue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_preserve_values()
|
||||
{
|
||||
WithTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("QualityDefinitions").Row(new
|
||||
{
|
||||
Quality = 1,
|
||||
Title = "SDTV",
|
||||
MinSize = 0,
|
||||
MaxSize = 100
|
||||
})
|
||||
.Row(new
|
||||
{
|
||||
Quality = 10,
|
||||
Title = "RawHD",
|
||||
MinSize = 0,
|
||||
MaxSize = 100
|
||||
});
|
||||
});
|
||||
|
||||
var items = Mocker.Resolve<QualityDefinitionRepository>().All();
|
||||
|
||||
items.Should().HaveCount(2);
|
||||
|
||||
items.First(v => v.Quality.Id == 1).MaxSize.Should().Be(100);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
@ -6,8 +7,8 @@
|
||||
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
{
|
||||
@ -52,6 +53,10 @@ public void Setup()
|
||||
|
||||
};
|
||||
|
||||
Mocker.GetMock<IQualityDefinitionService>()
|
||||
.Setup(v => v.Get(It.IsAny<Quality>()))
|
||||
.Returns<Quality>(v => Quality.DefaultQualityDefinitions.First(c => c.Quality == v));
|
||||
|
||||
qualityType = Builder<QualityDefinition>.CreateNew()
|
||||
.With(q => q.MinSize = 2)
|
||||
.With(q => q.MaxSize = 10)
|
||||
@ -144,7 +149,7 @@ public void should_return_true_if_unlimited_30_minute()
|
||||
series.Runtime = 30;
|
||||
parseResultSingle.Series = series;
|
||||
parseResultSingle.Release.Size = 18457280000;
|
||||
qualityType.MaxSize = 0;
|
||||
qualityType.MaxSize = null;
|
||||
|
||||
Subject.IsSatisfiedBy(parseResultSingle, null).Accepted.Should().BeTrue();
|
||||
}
|
||||
@ -157,9 +162,9 @@ public void should_return_true_if_unlimited_60_minute()
|
||||
series.Runtime = 60;
|
||||
parseResultSingle.Series = series;
|
||||
parseResultSingle.Release.Size = 36857280000;
|
||||
qualityType.MaxSize = 0;
|
||||
qualityType.MaxSize = null;
|
||||
|
||||
Subject.IsSatisfiedBy(parseResultSingle, null).Accepted.Should().BeTrue(); ;
|
||||
Subject.IsSatisfiedBy(parseResultSingle, null).Accepted.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -180,12 +185,14 @@ public void should_treat_daily_series_as_single_episode()
|
||||
[Test]
|
||||
public void should_return_true_if_RAWHD()
|
||||
{
|
||||
var parseResult = new RemoteEpisode
|
||||
{
|
||||
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.RAWHD) },
|
||||
};
|
||||
parseResultSingle.ParsedEpisodeInfo.Quality = new QualityModel(Quality.RAWHD);
|
||||
|
||||
series.Runtime = 45;
|
||||
parseResultSingle.Series = series;
|
||||
parseResultSingle.Series.SeriesType = SeriesTypes.Daily;
|
||||
parseResultSingle.Release.Size = 8000.Megabytes();
|
||||
|
||||
Subject.IsSatisfiedBy(parseResult, null).Accepted.Should().BeTrue();
|
||||
Subject.IsSatisfiedBy(parseResultSingle, null).Accepted.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -121,6 +121,7 @@
|
||||
<Compile Include="Datastore\Migration\074_disable_eztv.cs" />
|
||||
<Compile Include="Datastore\Migration\072_history_grabIdFixture.cs" />
|
||||
<Compile Include="Datastore\Migration\070_delay_profileFixture.cs" />
|
||||
<Compile Include="Datastore\Migration\084_update_quality_minmax_sizeFixture.cs" />
|
||||
<Compile Include="Datastore\Migration\081_move_dot_prefix_to_transmission_categoryFixture.cs" />
|
||||
<Compile Include="Datastore\Migration\079_dedupe_tagsFixture.cs" />
|
||||
<Compile Include="Datastore\Migration\075_force_lib_updateFixture.cs" />
|
||||
|
46
src/NzbDrone.Core/Datastore/Converters/DoubleConverter.cs
Normal file
46
src/NzbDrone.Core/Datastore/Converters/DoubleConverter.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using Marr.Data.Converters;
|
||||
using Marr.Data.Mapping;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Converters
|
||||
{
|
||||
public class DoubleConverter : IConverter
|
||||
{
|
||||
public object FromDB(ConverterContext context)
|
||||
{
|
||||
if (context.DbValue == DBNull.Value)
|
||||
{
|
||||
return DBNull.Value;
|
||||
}
|
||||
|
||||
if (context.DbValue is Double)
|
||||
{
|
||||
return context.DbValue;
|
||||
}
|
||||
|
||||
return Convert.ToDouble(context.DbValue);
|
||||
}
|
||||
|
||||
public object FromDB(ColumnMap map, object dbValue)
|
||||
{
|
||||
if (dbValue == DBNull.Value)
|
||||
{
|
||||
return DBNull.Value;
|
||||
}
|
||||
|
||||
if (dbValue is Double)
|
||||
{
|
||||
return dbValue;
|
||||
}
|
||||
|
||||
return Convert.ToDouble(dbValue);
|
||||
}
|
||||
|
||||
public object ToDB(object clrValue)
|
||||
{
|
||||
return clrValue;
|
||||
}
|
||||
|
||||
public Type DbType { get; private set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
using System.Data;
|
||||
using FluentMigrator;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Migration
|
||||
{
|
||||
[Migration(84)]
|
||||
public class update_quality_minmax_size : NzbDroneMigrationBase
|
||||
{
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Alter.Table("QualityDefinitions").AlterColumn("MinSize").AsDouble().Nullable();
|
||||
Alter.Table("QualityDefinitions").AlterColumn("MaxSize").AsDouble().Nullable();
|
||||
|
||||
Execute.Sql("UPDATE QualityDefinitions SET MaxSize = NULL WHERE Quality = 10 OR MaxSize = 0");
|
||||
}
|
||||
}
|
||||
}
|
@ -114,6 +114,7 @@ private static void RegisterMappers()
|
||||
RegisterProviderSettingConverter();
|
||||
|
||||
MapRepository.Instance.RegisterTypeConverter(typeof(Int32), new Int32Converter());
|
||||
MapRepository.Instance.RegisterTypeConverter(typeof(Double), new DoubleConverter());
|
||||
MapRepository.Instance.RegisterTypeConverter(typeof(DateTime), new UtcConverter());
|
||||
MapRepository.Instance.RegisterTypeConverter(typeof(Boolean), new BooleanIntConverter());
|
||||
MapRepository.Instance.RegisterTypeConverter(typeof(Enum), new EnumIntConverter());
|
||||
|
@ -30,12 +30,6 @@ public Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCr
|
||||
|
||||
var quality = subject.ParsedEpisodeInfo.Quality.Quality;
|
||||
|
||||
if (quality == Quality.RAWHD)
|
||||
{
|
||||
_logger.Debug("Raw-HD release found, skipping size check.");
|
||||
return Decision.Accept();
|
||||
}
|
||||
|
||||
if (subject.ParsedEpisodeInfo.Special)
|
||||
{
|
||||
_logger.Debug("Special release found, skipping size check.");
|
||||
@ -43,24 +37,27 @@ public Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCr
|
||||
}
|
||||
|
||||
var qualityDefinition = _qualityDefinitionService.Get(quality);
|
||||
var minSize = qualityDefinition.MinSize.Megabytes();
|
||||
|
||||
//Multiply maxSize by Series.Runtime
|
||||
minSize = minSize * subject.Series.Runtime * subject.Episodes.Count;
|
||||
|
||||
//If the parsed size is smaller than minSize we don't want it
|
||||
if (subject.Release.Size < minSize)
|
||||
if (qualityDefinition.MinSize.HasValue)
|
||||
{
|
||||
_logger.Debug("Item: {0}, Size: {1:0n} is smaller than minimum allowed size ({2:0}), rejecting.", subject, subject.Release.Size, minSize);
|
||||
return Decision.Reject("{0} is smaller than minimum allowed: {1}", subject.Release.Size.SizeSuffix(), minSize.SizeSuffix());
|
||||
var minSize = qualityDefinition.MinSize.Value.Megabytes();
|
||||
|
||||
//Multiply maxSize by Series.Runtime
|
||||
minSize = minSize * subject.Series.Runtime * subject.Episodes.Count;
|
||||
|
||||
//If the parsed size is smaller than minSize we don't want it
|
||||
if (subject.Release.Size < minSize)
|
||||
{
|
||||
_logger.Debug("Item: {0}, Size: {1:0n} is smaller than minimum allowed size ({2:0}), rejecting.", subject, subject.Release.Size, minSize);
|
||||
return Decision.Reject("{0} is smaller than minimum allowed: {1}", subject.Release.Size.SizeSuffix(), minSize.SizeSuffix());
|
||||
}
|
||||
}
|
||||
if (qualityDefinition.MaxSize == 0)
|
||||
if (!qualityDefinition.MaxSize.HasValue)
|
||||
{
|
||||
_logger.Debug("Max size is 0 (unlimited) - skipping check.");
|
||||
_logger.Debug("Max size is unlimited - skipping check.");
|
||||
}
|
||||
else
|
||||
{
|
||||
var maxSize = qualityDefinition.MaxSize.Megabytes();
|
||||
var maxSize = qualityDefinition.MaxSize.Value.Megabytes();
|
||||
|
||||
//Multiply maxSize by Series.Runtime
|
||||
maxSize = maxSize * subject.Series.Runtime * subject.Episodes.Count;
|
||||
|
@ -30,6 +30,16 @@ public static Int64 Gigabytes(this int gigabytes)
|
||||
return Convert.ToInt64(gigabytes * 1024L * 1024L * 1024L);
|
||||
}
|
||||
|
||||
public static Int64 Megabytes(this double megabytes)
|
||||
{
|
||||
return Convert.ToInt64(megabytes * 1024L * 1024L);
|
||||
}
|
||||
|
||||
public static Int64 Gigabytes(this double gigabytes)
|
||||
{
|
||||
return Convert.ToInt64(gigabytes * 1024L * 1024L * 1024L);
|
||||
}
|
||||
|
||||
|
||||
public static Int64 Round(this long number, long level)
|
||||
{
|
||||
|
@ -151,6 +151,7 @@
|
||||
<Compile Include="Datastore\BasicRepository.cs" />
|
||||
<Compile Include="Datastore\ConnectionStringFactory.cs" />
|
||||
<Compile Include="Datastore\Converters\BooleanIntConverter.cs" />
|
||||
<Compile Include="Datastore\Converters\DoubleConverter.cs" />
|
||||
<Compile Include="Datastore\Converters\EmbeddedDocumentConverter.cs" />
|
||||
<Compile Include="Datastore\Converters\EnumIntConverter.cs" />
|
||||
<Compile Include="Datastore\Converters\TimeSpanConverter.cs" />
|
||||
@ -251,6 +252,7 @@
|
||||
<Compile Include="Datastore\Migration\081_move_dot_prefix_to_transmission_category.cs" />
|
||||
<Compile Include="Datastore\Migration\079_dedupe_tags.cs" />
|
||||
<Compile Include="Datastore\Migration\070_delay_profile.cs" />
|
||||
<Compile Include="Datastore\Migration\084_update_quality_minmax_size.cs" />
|
||||
<Compile Include="Datastore\Migration\083_additonal_blacklist_columns.cs" />
|
||||
<Compile Include="Datastore\Migration\082_add_fanzub_settings.cs" />
|
||||
<Compile Include="Datastore\Migration\Framework\MigrationContext.cs" />
|
||||
|
@ -101,7 +101,7 @@ public static HashSet<QualityDefinition> DefaultQualityDefinitions
|
||||
new QualityDefinition(Quality.DVD) { Weight = 4, MinSize = 0, MaxSize = 100 },
|
||||
new QualityDefinition(Quality.HDTV720p) { Weight = 5, MinSize = 0, MaxSize = 100 },
|
||||
new QualityDefinition(Quality.HDTV1080p) { Weight = 6, MinSize = 0, MaxSize = 100 },
|
||||
new QualityDefinition(Quality.RAWHD) { Weight = 7, MinSize = 0, MaxSize = 100 },
|
||||
new QualityDefinition(Quality.RAWHD) { Weight = 7, MinSize = 0, MaxSize = null },
|
||||
new QualityDefinition(Quality.WEBDL720p) { Weight = 8, MinSize = 0, MaxSize = 100 },
|
||||
new QualityDefinition(Quality.Bluray720p) { Weight = 9, MinSize = 0, MaxSize = 100 },
|
||||
new QualityDefinition(Quality.WEBDL1080p) { Weight = 10, MinSize = 0, MaxSize = 100 },
|
||||
|
@ -11,8 +11,8 @@ public class QualityDefinition : ModelBase
|
||||
|
||||
public int Weight { get; set; }
|
||||
|
||||
public int MinSize { get; set; }
|
||||
public int MaxSize { get; set; }
|
||||
public double? MinSize { get; set; }
|
||||
public double? MaxSize { get; set; }
|
||||
|
||||
public QualityDefinition()
|
||||
{
|
||||
|
@ -6,7 +6,7 @@
|
||||
<div class="row">
|
||||
<span class="col-md-2 col-sm-3">Quality</span>
|
||||
<span class="col-md-2 col-sm-3">Title</span>
|
||||
<span class="col-md-4 col-sm-6">Size Limit</span>
|
||||
<span class="col-md-4 col-sm-6">Size Limit <i class="icon-sonarr-info" title="Limits are automatically adjusted for the series runtime and number of episodes in the file." /></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rows x-rows">
|
||||
|
@ -6,6 +6,12 @@ require('jquery-ui');
|
||||
var view = Marionette.ItemView.extend({
|
||||
template : 'Settings/Quality/Definition/QualityDefinitionItemViewTemplate',
|
||||
className : 'row',
|
||||
|
||||
slider : {
|
||||
min : 0,
|
||||
max : 200,
|
||||
step : 0.1
|
||||
},
|
||||
|
||||
ui : {
|
||||
sizeSlider : '.x-slider',
|
||||
@ -31,11 +37,12 @@ var view = Marionette.ItemView.extend({
|
||||
|
||||
this.ui.sizeSlider.slider({
|
||||
range : true,
|
||||
min : 0,
|
||||
max : 200,
|
||||
min : this.slider.min,
|
||||
max : this.slider.max,
|
||||
step : this.slider.step,
|
||||
values : [
|
||||
this.model.get('minSize'),
|
||||
this.model.get('maxSize')
|
||||
this.model.get('minSize') || this.slider.min,
|
||||
this.model.get('maxSize') || this.slider.max
|
||||
]
|
||||
});
|
||||
|
||||
@ -43,15 +50,22 @@ var view = Marionette.ItemView.extend({
|
||||
},
|
||||
|
||||
_updateSize : function(event, ui) {
|
||||
this.model.set('minSize', ui.values[0]);
|
||||
this.model.set('maxSize', ui.values[1]);
|
||||
var minSize = ui.values[0];
|
||||
var maxSize = ui.values[1];
|
||||
|
||||
if (maxSize === this.slider.max) {
|
||||
maxSize = null;
|
||||
}
|
||||
|
||||
this.model.set('minSize', minSize);
|
||||
this.model.set('maxSize', maxSize);
|
||||
|
||||
this._changeSize();
|
||||
},
|
||||
|
||||
_changeSize : function() {
|
||||
var minSize = this.model.get('minSize');
|
||||
var maxSize = this.model.get('maxSize');
|
||||
var minSize = this.model.get('minSize') || this.slider.min;
|
||||
var maxSize = this.model.get('maxSize') || null;
|
||||
|
||||
{
|
||||
var minBytes = minSize * 1024 * 1024;
|
||||
@ -63,24 +77,18 @@ var view = Marionette.ItemView.extend({
|
||||
}
|
||||
|
||||
{
|
||||
if (maxSize === 0) {
|
||||
if (maxSize === 0 || maxSize === null) {
|
||||
this.ui.thirtyMinuteMaxSize.html('Unlimited');
|
||||
this.ui.sixtyMinuteMaxSize.html('Unlimited');
|
||||
} else {
|
||||
var maxBytes = maxSize * 1024 * 1024;
|
||||
var maxThirty = fileSize(maxBytes * 30, 1, false);
|
||||
var maxSixty = fileSize(maxBytes * 60, 1, false);
|
||||
|
||||
return;
|
||||
this.ui.thirtyMinuteMaxSize.html(maxThirty);
|
||||
this.ui.sixtyMinuteMaxSize.html(maxSixty);
|
||||
}
|
||||
|
||||
var maxBytes = maxSize * 1024 * 1024;
|
||||
var maxThirty = fileSize(maxBytes * 30, 1, false);
|
||||
var maxSixty = fileSize(maxBytes * 60, 1, false);
|
||||
|
||||
this.ui.thirtyMinuteMaxSize.html(maxThirty);
|
||||
this.ui.sixtyMinuteMaxSize.html(maxSixty);
|
||||
}
|
||||
/*if (parseInt(maxSize, 10) === 0) {
|
||||
thirty = 'No Limit';
|
||||
sixty = 'No Limit';
|
||||
}*/
|
||||
}
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user