New: Use release quality source if not in downloaded file and resolution matches
This commit is contained in:
parent
0ff08dbe8d
commit
430af0401c
|
@ -44,7 +44,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
Series = _series
|
Series = _series
|
||||||
};
|
};
|
||||||
|
|
||||||
Subject.Aggregate(localEpisode, false);
|
Subject.Aggregate(localEpisode, null, false);
|
||||||
|
|
||||||
Mocker.GetMock<IParsingService>()
|
Mocker.GetMock<IParsingService>()
|
||||||
.Verify(v => v.GetEpisodes(fileEpisodeInfo, _series, localEpisode.SceneSource, null), Times.Once());
|
.Verify(v => v.GetEpisodes(fileEpisodeInfo, _series, localEpisode.SceneSource, null), Times.Once());
|
||||||
|
@ -63,7 +63,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
Series = _series
|
Series = _series
|
||||||
};
|
};
|
||||||
|
|
||||||
Subject.Aggregate(localEpisode, true);
|
Subject.Aggregate(localEpisode, null, true);
|
||||||
|
|
||||||
Mocker.GetMock<IParsingService>()
|
Mocker.GetMock<IParsingService>()
|
||||||
.Verify(v => v.GetEpisodes(fileEpisodeInfo, _series, localEpisode.SceneSource, null), Times.Once());
|
.Verify(v => v.GetEpisodes(fileEpisodeInfo, _series, localEpisode.SceneSource, null), Times.Once());
|
||||||
|
@ -82,7 +82,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
Series = _series
|
Series = _series
|
||||||
};
|
};
|
||||||
|
|
||||||
Subject.Aggregate(localEpisode, false);
|
Subject.Aggregate(localEpisode, null, false);
|
||||||
|
|
||||||
Mocker.GetMock<IParsingService>()
|
Mocker.GetMock<IParsingService>()
|
||||||
.Verify(v => v.GetEpisodes(fileEpisodeInfo, _series, localEpisode.SceneSource, null), Times.Once());
|
.Verify(v => v.GetEpisodes(fileEpisodeInfo, _series, localEpisode.SceneSource, null), Times.Once());
|
||||||
|
@ -101,7 +101,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
Series = _series
|
Series = _series
|
||||||
};
|
};
|
||||||
|
|
||||||
Subject.Aggregate(localEpisode, false);
|
Subject.Aggregate(localEpisode, null, false);
|
||||||
|
|
||||||
Mocker.GetMock<IParsingService>()
|
Mocker.GetMock<IParsingService>()
|
||||||
.Verify(v => v.GetEpisodes(folderEpisodeInfo, _series, localEpisode.SceneSource, null), Times.Once());
|
.Verify(v => v.GetEpisodes(folderEpisodeInfo, _series, localEpisode.SceneSource, null), Times.Once());
|
||||||
|
@ -120,7 +120,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
Series = _series
|
Series = _series
|
||||||
};
|
};
|
||||||
|
|
||||||
Subject.Aggregate(localEpisode, false);
|
Subject.Aggregate(localEpisode, null, false);
|
||||||
|
|
||||||
Mocker.GetMock<IParsingService>()
|
Mocker.GetMock<IParsingService>()
|
||||||
.Verify(v => v.GetEpisodes(fileEpisodeInfo, _series, localEpisode.SceneSource, null), Times.Once());
|
.Verify(v => v.GetEpisodes(fileEpisodeInfo, _series, localEpisode.SceneSource, null), Times.Once());
|
||||||
|
@ -143,7 +143,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
.Setup(s => s.ParseSpecialEpisodeTitle(fileEpisodeInfo, It.IsAny<string>(), _series))
|
.Setup(s => s.ParseSpecialEpisodeTitle(fileEpisodeInfo, It.IsAny<string>(), _series))
|
||||||
.Returns(specialEpisodeInfo);
|
.Returns(specialEpisodeInfo);
|
||||||
|
|
||||||
Subject.Aggregate(localEpisode, false);
|
Subject.Aggregate(localEpisode, null, false);
|
||||||
|
|
||||||
Mocker.GetMock<IParsingService>()
|
Mocker.GetMock<IParsingService>()
|
||||||
.Verify(v => v.GetEpisodes(specialEpisodeInfo, _series, localEpisode.SceneSource, null), Times.Once());
|
.Verify(v => v.GetEpisodes(specialEpisodeInfo, _series, localEpisode.SceneSource, null), Times.Once());
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
{
|
{
|
||||||
_localEpisode.FileEpisodeInfo = GetParsedEpisodeInfo(Language.English);
|
_localEpisode.FileEpisodeInfo = GetParsedEpisodeInfo(Language.English);
|
||||||
|
|
||||||
Subject.Aggregate(_localEpisode, false).Language.Should().Be(_localEpisode.FileEpisodeInfo.Language);
|
Subject.Aggregate(_localEpisode, null, false).Language.Should().Be(_localEpisode.FileEpisodeInfo.Language);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -45,7 +45,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
_localEpisode.FolderEpisodeInfo = GetParsedEpisodeInfo(Language.English);
|
_localEpisode.FolderEpisodeInfo = GetParsedEpisodeInfo(Language.English);
|
||||||
_localEpisode.FileEpisodeInfo = GetParsedEpisodeInfo(Language.English);
|
_localEpisode.FileEpisodeInfo = GetParsedEpisodeInfo(Language.English);
|
||||||
|
|
||||||
Subject.Aggregate(_localEpisode, false).Language.Should().Be(_localEpisode.FolderEpisodeInfo.Language);
|
Subject.Aggregate(_localEpisode, null, false).Language.Should().Be(_localEpisode.FolderEpisodeInfo.Language);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -55,7 +55,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
_localEpisode.FolderEpisodeInfo = GetParsedEpisodeInfo(Language.English);
|
_localEpisode.FolderEpisodeInfo = GetParsedEpisodeInfo(Language.English);
|
||||||
_localEpisode.FileEpisodeInfo = GetParsedEpisodeInfo(Language.English);
|
_localEpisode.FileEpisodeInfo = GetParsedEpisodeInfo(Language.English);
|
||||||
|
|
||||||
Subject.Aggregate(_localEpisode, false).Language.Should().Be(_localEpisode.DownloadClientEpisodeInfo.Language);
|
Subject.Aggregate(_localEpisode, null, false).Language.Should().Be(_localEpisode.DownloadClientEpisodeInfo.Language);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
_localEpisode.FolderEpisodeInfo = GetParsedEpisodeInfo(Language.English);
|
_localEpisode.FolderEpisodeInfo = GetParsedEpisodeInfo(Language.English);
|
||||||
_localEpisode.FileEpisodeInfo = GetParsedEpisodeInfo(Language.French);
|
_localEpisode.FileEpisodeInfo = GetParsedEpisodeInfo(Language.French);
|
||||||
|
|
||||||
Subject.Aggregate(_localEpisode, false).Language.Should().Be(_localEpisode.FileEpisodeInfo.Language);
|
Subject.Aggregate(_localEpisode, null, false).Language.Should().Be(_localEpisode.FileEpisodeInfo.Language);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ using System.Linq;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators;
|
using NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators;
|
||||||
using NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality;
|
using NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
@ -12,11 +13,12 @@ using NzbDrone.Core.Test.Framework;
|
||||||
namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class AugmentQualityFixture : CoreTest<AggregateQuality>
|
public class AggregateQualityFixture : CoreTest<AggregateQuality>
|
||||||
{
|
{
|
||||||
private Mock<IAugmentQuality> _mediaInfoAugmenter;
|
private Mock<IAugmentQuality> _mediaInfoAugmenter;
|
||||||
private Mock<IAugmentQuality> _fileExtensionAugmenter;
|
private Mock<IAugmentQuality> _fileExtensionAugmenter;
|
||||||
private Mock<IAugmentQuality> _nameAugmenter;
|
private Mock<IAugmentQuality> _nameAugmenter;
|
||||||
|
private Mock<IAugmentQuality> _releaseNameAugmenter;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
|
@ -24,15 +26,24 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
_mediaInfoAugmenter = new Mock<IAugmentQuality>();
|
_mediaInfoAugmenter = new Mock<IAugmentQuality>();
|
||||||
_fileExtensionAugmenter = new Mock<IAugmentQuality>();
|
_fileExtensionAugmenter = new Mock<IAugmentQuality>();
|
||||||
_nameAugmenter = new Mock<IAugmentQuality>();
|
_nameAugmenter = new Mock<IAugmentQuality>();
|
||||||
|
_releaseNameAugmenter = new Mock<IAugmentQuality>();
|
||||||
|
|
||||||
_mediaInfoAugmenter.Setup(s => s.AugmentQuality(It.IsAny<LocalEpisode>()))
|
_fileExtensionAugmenter.SetupGet(s => s.Order).Returns(1);
|
||||||
|
_nameAugmenter.SetupGet(s => s.Order).Returns(2);
|
||||||
|
_mediaInfoAugmenter.SetupGet(s => s.Order).Returns(4);
|
||||||
|
_releaseNameAugmenter.SetupGet(s => s.Order).Returns(5);
|
||||||
|
|
||||||
|
_mediaInfoAugmenter.Setup(s => s.AugmentQuality(It.IsAny<LocalEpisode>(), It.IsAny<DownloadClientItem>()))
|
||||||
.Returns(AugmentQualityResult.ResolutionOnly(1080, Confidence.MediaInfo));
|
.Returns(AugmentQualityResult.ResolutionOnly(1080, Confidence.MediaInfo));
|
||||||
|
|
||||||
_fileExtensionAugmenter.Setup(s => s.AugmentQuality(It.IsAny<LocalEpisode>()))
|
_fileExtensionAugmenter.Setup(s => s.AugmentQuality(It.IsAny<LocalEpisode>(), It.IsAny<DownloadClientItem>()))
|
||||||
.Returns(new AugmentQualityResult(QualitySource.Television, Confidence.Fallback, 720, Confidence.Fallback, new Revision()));
|
.Returns(new AugmentQualityResult(QualitySource.Television, Confidence.Fallback, 720, Confidence.Fallback, new Revision()));
|
||||||
|
|
||||||
_nameAugmenter.Setup(s => s.AugmentQuality(It.IsAny<LocalEpisode>()))
|
_nameAugmenter.Setup(s => s.AugmentQuality(It.IsAny<LocalEpisode>(), It.IsAny<DownloadClientItem>()))
|
||||||
.Returns(new AugmentQualityResult(QualitySource.Television, Confidence.Default, 480, Confidence.Default, new Revision()));
|
.Returns(new AugmentQualityResult(QualitySource.Television, Confidence.Default, 480, Confidence.Default, new Revision()));
|
||||||
|
|
||||||
|
_releaseNameAugmenter.Setup(s => s.AugmentQuality(It.IsAny<LocalEpisode>(), It.IsAny<DownloadClientItem>()))
|
||||||
|
.Returns(AugmentQualityResult.SourceOnly(QualitySource.Web, Confidence.MediaInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GivenAugmenters(params Mock<IAugmentQuality>[] mocks)
|
private void GivenAugmenters(params Mock<IAugmentQuality>[] mocks)
|
||||||
|
@ -44,14 +55,15 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
public void should_return_HDTV720_from_extension_when_other_augments_are_null()
|
public void should_return_HDTV720_from_extension_when_other_augments_are_null()
|
||||||
{
|
{
|
||||||
var nullMock = new Mock<IAugmentQuality>();
|
var nullMock = new Mock<IAugmentQuality>();
|
||||||
nullMock.Setup(s => s.AugmentQuality(It.IsAny<LocalEpisode>()))
|
nullMock.Setup(s => s.AugmentQuality(It.IsAny<LocalEpisode>(), It.IsAny<DownloadClientItem>()))
|
||||||
.Returns<LocalEpisode>(l => null);
|
.Returns<LocalEpisode, DownloadClientItem>((l, d) => null);
|
||||||
|
|
||||||
GivenAugmenters(_fileExtensionAugmenter, nullMock);
|
GivenAugmenters(_fileExtensionAugmenter, nullMock);
|
||||||
|
|
||||||
var result = Subject.Aggregate(new LocalEpisode(), false);
|
var result = Subject.Aggregate(new LocalEpisode(), null, false);
|
||||||
|
|
||||||
result.Quality.QualityDetectionSource.Should().Be(QualityDetectionSource.Extension);
|
result.Quality.SourceDetectionSource.Should().Be(QualityDetectionSource.Extension);
|
||||||
|
result.Quality.ResolutionDetectionSource.Should().Be(QualityDetectionSource.Extension);
|
||||||
result.Quality.Quality.Should().Be(Quality.HDTV720p);
|
result.Quality.Quality.Should().Be(Quality.HDTV720p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,9 +72,10 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
{
|
{
|
||||||
GivenAugmenters(_fileExtensionAugmenter, _nameAugmenter);
|
GivenAugmenters(_fileExtensionAugmenter, _nameAugmenter);
|
||||||
|
|
||||||
var result = Subject.Aggregate(new LocalEpisode(), false);
|
var result = Subject.Aggregate(new LocalEpisode(), null, false);
|
||||||
|
|
||||||
result.Quality.QualityDetectionSource.Should().Be(QualityDetectionSource.Name);
|
result.Quality.SourceDetectionSource.Should().Be(QualityDetectionSource.Name);
|
||||||
|
result.Quality.ResolutionDetectionSource.Should().Be(QualityDetectionSource.Name);
|
||||||
result.Quality.Quality.Should().Be(Quality.SDTV);
|
result.Quality.Quality.Should().Be(Quality.SDTV);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,9 +84,10 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
{
|
{
|
||||||
GivenAugmenters(_fileExtensionAugmenter, _mediaInfoAugmenter);
|
GivenAugmenters(_fileExtensionAugmenter, _mediaInfoAugmenter);
|
||||||
|
|
||||||
var result = Subject.Aggregate(new LocalEpisode(), false);
|
var result = Subject.Aggregate(new LocalEpisode(), null, false);
|
||||||
|
|
||||||
result.Quality.QualityDetectionSource.Should().Be(QualityDetectionSource.MediaInfo);
|
result.Quality.SourceDetectionSource.Should().Be(QualityDetectionSource.Extension);
|
||||||
|
result.Quality.ResolutionDetectionSource.Should().Be(QualityDetectionSource.MediaInfo);
|
||||||
result.Quality.Quality.Should().Be(Quality.HDTV1080p);
|
result.Quality.Quality.Should().Be(Quality.HDTV1080p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,10 +96,23 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
{
|
{
|
||||||
GivenAugmenters(_nameAugmenter, _mediaInfoAugmenter);
|
GivenAugmenters(_nameAugmenter, _mediaInfoAugmenter);
|
||||||
|
|
||||||
var result = Subject.Aggregate(new LocalEpisode(), false);
|
var result = Subject.Aggregate(new LocalEpisode(), null, false);
|
||||||
|
|
||||||
result.Quality.QualityDetectionSource.Should().Be(QualityDetectionSource.MediaInfo);
|
result.Quality.SourceDetectionSource.Should().Be(QualityDetectionSource.Name);
|
||||||
|
result.Quality.ResolutionDetectionSource.Should().Be(QualityDetectionSource.MediaInfo);
|
||||||
result.Quality.Quality.Should().Be(Quality.HDTV1080p);
|
result.Quality.Quality.Should().Be(Quality.HDTV1080p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_WEBDL480p_when_file_name_has_HDTV480p_but_release_name_indicates_webdl_source()
|
||||||
|
{
|
||||||
|
GivenAugmenters(_nameAugmenter, _releaseNameAugmenter);
|
||||||
|
|
||||||
|
var result = Subject.Aggregate(new LocalEpisode(), new DownloadClientItem(), false);
|
||||||
|
|
||||||
|
result.Quality.SourceDetectionSource.Should().Be(QualityDetectionSource.Name);
|
||||||
|
result.Quality.ResolutionDetectionSource.Should().Be(QualityDetectionSource.Name);
|
||||||
|
result.Quality.Quality.Should().Be(Quality.WEBDL480p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using FizzWare.NBuilder;
|
using FizzWare.NBuilder;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using Moq;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators;
|
using NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
@ -36,7 +34,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
Series = _series
|
Series = _series
|
||||||
};
|
};
|
||||||
|
|
||||||
Subject.Aggregate(localEpisode, false);
|
Subject.Aggregate(localEpisode, null, false);
|
||||||
|
|
||||||
localEpisode.ReleaseGroup.Should().Be("Wizzy");
|
localEpisode.ReleaseGroup.Should().Be("Wizzy");
|
||||||
}
|
}
|
||||||
|
@ -54,7 +52,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
Series = _series
|
Series = _series
|
||||||
};
|
};
|
||||||
|
|
||||||
Subject.Aggregate(localEpisode, false);
|
Subject.Aggregate(localEpisode, null, false);
|
||||||
|
|
||||||
localEpisode.ReleaseGroup.Should().Be("Wizzy");
|
localEpisode.ReleaseGroup.Should().Be("Wizzy");
|
||||||
}
|
}
|
||||||
|
@ -74,7 +72,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
Series = _series
|
Series = _series
|
||||||
};
|
};
|
||||||
|
|
||||||
Subject.Aggregate(localEpisode, false);
|
Subject.Aggregate(localEpisode, null, false);
|
||||||
|
|
||||||
localEpisode.ReleaseGroup.Should().Be("Viva");
|
localEpisode.ReleaseGroup.Should().Be("Viva");
|
||||||
}
|
}
|
||||||
|
@ -94,7 +92,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
Series = _series
|
Series = _series
|
||||||
};
|
};
|
||||||
|
|
||||||
Subject.Aggregate(localEpisode, false);
|
Subject.Aggregate(localEpisode, null, false);
|
||||||
|
|
||||||
localEpisode.ReleaseGroup.Should().Be("Drone");
|
localEpisode.ReleaseGroup.Should().Be("Drone");
|
||||||
}
|
}
|
||||||
|
@ -114,7 +112,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
Series = _series
|
Series = _series
|
||||||
};
|
};
|
||||||
|
|
||||||
Subject.Aggregate(localEpisode, false);
|
Subject.Aggregate(localEpisode, null, false);
|
||||||
|
|
||||||
localEpisode.ReleaseGroup.Should().Be("Wizzy");
|
localEpisode.ReleaseGroup.Should().Be("Wizzy");
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators.Au
|
||||||
.With(l => l.MediaInfo = null)
|
.With(l => l.MediaInfo = null)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
Subject.AugmentQuality(localEpisode).Should().Be(null);
|
Subject.AugmentQuality(localEpisode, null).Should().Be(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -32,7 +32,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators.Au
|
||||||
.With(l => l.MediaInfo = mediaInfo)
|
.With(l => l.MediaInfo = mediaInfo)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
Subject.AugmentQuality(localEpisode).Should().Be(null);
|
Subject.AugmentQuality(localEpisode, null).Should().Be(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(4096, 2160)] // True 4K
|
[TestCase(4096, 2160)] // True 4K
|
||||||
|
@ -59,7 +59,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators.Au
|
||||||
.With(l => l.MediaInfo = mediaInfo)
|
.With(l => l.MediaInfo = mediaInfo)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var result = Subject.AugmentQuality(localEpisode);
|
var result = Subject.AugmentQuality(localEpisode, null);
|
||||||
|
|
||||||
result.Should().NotBe(null);
|
result.Should().NotBe(null);
|
||||||
result.Resolution.Should().Be(expectedResolution);
|
result.Resolution.Should().Be(expectedResolution);
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
|
using NzbDrone.Core.Download.History;
|
||||||
|
using NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class AugmentQualityFromReleaseNameFixture : CoreTest<AugmentQualityFromReleaseName>
|
||||||
|
{
|
||||||
|
private LocalEpisode _localEpisode;
|
||||||
|
private DownloadClientItem _downloadClientItem;
|
||||||
|
private ParsedEpisodeInfo _hdtvParsedEpisodeInfo;
|
||||||
|
private ParsedEpisodeInfo _webdlParsedEpisodeInfo;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_hdtvParsedEpisodeInfo = Builder<ParsedEpisodeInfo>.CreateNew()
|
||||||
|
.With(p => p.Quality =
|
||||||
|
new QualityModel(Core.Qualities.Quality.HDTV720p))
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_webdlParsedEpisodeInfo = Builder<ParsedEpisodeInfo>.CreateNew()
|
||||||
|
.With(p => p.Quality =
|
||||||
|
new QualityModel(Core.Qualities.Quality.WEBDL720p))
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_localEpisode = Builder<LocalEpisode>.CreateNew()
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
_downloadClientItem = Builder<DownloadClientItem>.CreateNew()
|
||||||
|
.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_null_if_download_client_item_is_null()
|
||||||
|
{
|
||||||
|
Subject.AugmentQuality(_localEpisode, null).Should().BeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_null_if_no_grabbed_history()
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IDownloadHistoryService>()
|
||||||
|
.Setup(s => s.GetLatestGrab(It.IsAny<string>()))
|
||||||
|
.Returns((DownloadHistory)null);
|
||||||
|
|
||||||
|
Subject.AugmentQuality(_localEpisode, _downloadClientItem).Should().BeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("Series.Title.S01E01.1080p.WEB.x264", QualitySource.Web, Confidence.Tag, 1080, Confidence.Tag)]
|
||||||
|
[TestCase("Series.Title.S01E01.WEB.x264", QualitySource.Web, Confidence.Tag, 480, Confidence.Fallback)]
|
||||||
|
[TestCase("Series.Title.S01E01.720p.x264", QualitySource.Television, Confidence.Fallback, 720, Confidence.Tag)]
|
||||||
|
public void should_return_augmented_quality(string title, QualitySource source, Confidence sourceConfidence, int resolution, Confidence resolutionConfidence)
|
||||||
|
{
|
||||||
|
Mocker.GetMock<IDownloadHistoryService>()
|
||||||
|
.Setup(s => s.GetLatestGrab(It.IsAny<string>()))
|
||||||
|
.Returns(Builder<DownloadHistory>.CreateNew()
|
||||||
|
.With(h => h.SourceTitle = title)
|
||||||
|
.Build()
|
||||||
|
);
|
||||||
|
|
||||||
|
var result = Subject.AugmentQuality(_localEpisode, _downloadClientItem);
|
||||||
|
|
||||||
|
result.Should().NotBe(null);
|
||||||
|
result.Source.Should().Be(source);
|
||||||
|
result.SourceConfidence.Should().Be(sourceConfidence);
|
||||||
|
result.Resolution.Should().Be(resolution);
|
||||||
|
result.ResolutionConfidence.Should().Be(resolutionConfidence);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
{
|
{
|
||||||
private List<string> _videoFiles;
|
private List<string> _videoFiles;
|
||||||
private LocalEpisode _localEpisode;
|
private LocalEpisode _localEpisode;
|
||||||
|
private DownloadClientItem _downloadClientItem;
|
||||||
private Series _series;
|
private Series _series;
|
||||||
private QualityModel _quality;
|
private QualityModel _quality;
|
||||||
|
|
||||||
|
@ -92,8 +93,8 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
private void GivenAugmentationSuccess()
|
private void GivenAugmentationSuccess()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IAggregationService>()
|
Mocker.GetMock<IAggregationService>()
|
||||||
.Setup(s => s.Augment(It.IsAny<LocalEpisode>(), It.IsAny<bool>()))
|
.Setup(s => s.Augment(It.IsAny<LocalEpisode>(), It.IsAny<DownloadClientItem>(), It.IsAny<bool>()))
|
||||||
.Callback<LocalEpisode, bool>((localEpisode, otherFiles) =>
|
.Callback<LocalEpisode, DownloadClientItem, bool>((localEpisode, downloadClientItem, otherFiles) =>
|
||||||
{
|
{
|
||||||
localEpisode.Episodes = _localEpisode.Episodes;
|
localEpisode.Episodes = _localEpisode.Episodes;
|
||||||
});
|
});
|
||||||
|
@ -163,7 +164,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
GivenSpecifications(_pass1);
|
GivenSpecifications(_pass1);
|
||||||
|
|
||||||
Mocker.GetMock<IAggregationService>()
|
Mocker.GetMock<IAggregationService>()
|
||||||
.Setup(c => c.Augment(It.IsAny<LocalEpisode>(), It.IsAny<bool>()))
|
.Setup(c => c.Augment(It.IsAny<LocalEpisode>(), It.IsAny<DownloadClientItem>(), It.IsAny<bool>()))
|
||||||
.Throws<TestException>();
|
.Throws<TestException>();
|
||||||
|
|
||||||
_videoFiles = new List<string>
|
_videoFiles = new List<string>
|
||||||
|
@ -178,7 +179,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
Subject.GetImportDecisions(_videoFiles, _series);
|
Subject.GetImportDecisions(_videoFiles, _series);
|
||||||
|
|
||||||
Mocker.GetMock<IAggregationService>()
|
Mocker.GetMock<IAggregationService>()
|
||||||
.Verify(c => c.Augment(It.IsAny<LocalEpisode>(), It.IsAny<bool>()), Times.Exactly(_videoFiles.Count));
|
.Verify(c => c.Augment(It.IsAny<LocalEpisode>(), It.IsAny<DownloadClientItem>(), It.IsAny<bool>()), Times.Exactly(_videoFiles.Count));
|
||||||
|
|
||||||
ExceptionVerification.ExpectedErrors(3);
|
ExceptionVerification.ExpectedErrors(3);
|
||||||
}
|
}
|
||||||
|
@ -199,7 +200,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
var decisions = Subject.GetImportDecisions(_videoFiles, _series);
|
var decisions = Subject.GetImportDecisions(_videoFiles, _series);
|
||||||
|
|
||||||
Mocker.GetMock<IAggregationService>()
|
Mocker.GetMock<IAggregationService>()
|
||||||
.Verify(c => c.Augment(It.IsAny<LocalEpisode>(), It.IsAny<bool>()), Times.Exactly(_videoFiles.Count));
|
.Verify(c => c.Augment(It.IsAny<LocalEpisode>(), It.IsAny<DownloadClientItem>(), It.IsAny<bool>()), Times.Exactly(_videoFiles.Count));
|
||||||
|
|
||||||
decisions.Should().HaveCount(3);
|
decisions.Should().HaveCount(3);
|
||||||
decisions.First().Rejections.Should().NotBeEmpty();
|
decisions.First().Rejections.Should().NotBeEmpty();
|
||||||
|
@ -209,7 +210,7 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
|
||||||
public void should_return_a_decision_when_exception_is_caught()
|
public void should_return_a_decision_when_exception_is_caught()
|
||||||
{
|
{
|
||||||
Mocker.GetMock<IAggregationService>()
|
Mocker.GetMock<IAggregationService>()
|
||||||
.Setup(c => c.Augment(It.IsAny<LocalEpisode>(), It.IsAny<bool>()))
|
.Setup(c => c.Augment(It.IsAny<LocalEpisode>(), It.IsAny<DownloadClientItem>(), It.IsAny<bool>()))
|
||||||
.Throws<TestException>();
|
.Throws<TestException>();
|
||||||
|
|
||||||
_videoFiles = new List<string>
|
_videoFiles = new List<string>
|
||||||
|
|
|
@ -1,106 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using FizzWare.NBuilder;
|
|
||||||
using FluentAssertions;
|
|
||||||
using Marr.Data;
|
|
||||||
using Moq;
|
|
||||||
using NUnit.Framework;
|
|
||||||
using NzbDrone.Core.Download;
|
|
||||||
using NzbDrone.Core.History;
|
|
||||||
using NzbDrone.Core.MediaFiles.EpisodeImport.Specifications;
|
|
||||||
using NzbDrone.Core.Parser.Model;
|
|
||||||
using NzbDrone.Core.Profiles.Qualities;
|
|
||||||
using NzbDrone.Core.Qualities;
|
|
||||||
using NzbDrone.Core.Test.Framework;
|
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class DifferentQualitySpecificationFixture : CoreTest<DifferentQualitySpecification>
|
|
||||||
{
|
|
||||||
private LocalEpisode _localEpisode;
|
|
||||||
private DownloadClientItem _downloadClientItem;
|
|
||||||
|
|
||||||
[SetUp]
|
|
||||||
public void Setup()
|
|
||||||
{
|
|
||||||
var qualityProfile = new QualityProfile
|
|
||||||
{
|
|
||||||
Cutoff = Quality.Bluray1080p.Id,
|
|
||||||
Items = Qualities.QualityFixture.GetDefaultQualities(Quality.DVD, Quality.HDTV720p, Quality.Bluray1080p)
|
|
||||||
};
|
|
||||||
|
|
||||||
var fakeSeries = Builder<Series>.CreateNew()
|
|
||||||
.With(c => c.QualityProfile = qualityProfile)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_localEpisode = Builder<LocalEpisode>.CreateNew()
|
|
||||||
.With(l => l.Quality = new QualityModel(Quality.Bluray1080p))
|
|
||||||
.With(l => l.DownloadClientEpisodeInfo = new ParsedEpisodeInfo())
|
|
||||||
.With(l => l.Series = fakeSeries)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
_downloadClientItem = Builder<DownloadClientItem>.CreateNew()
|
|
||||||
.Build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GivenGrabbedEpisodeHistory(QualityModel quality)
|
|
||||||
{
|
|
||||||
var history = Builder<EpisodeHistory>.CreateListOfSize(1)
|
|
||||||
.TheFirst(1)
|
|
||||||
.With(h => h.Quality = quality)
|
|
||||||
.With(h => h.EventType = EpisodeHistoryEventType.Grabbed)
|
|
||||||
.BuildList();
|
|
||||||
|
|
||||||
Mocker.GetMock<IHistoryService>()
|
|
||||||
.Setup(s => s.FindByDownloadId(It.IsAny<string>()))
|
|
||||||
.Returns(history);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_be_accepted_if_no_download_client_item()
|
|
||||||
{
|
|
||||||
Subject.IsSatisfiedBy(_localEpisode, null).Accepted.Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_be_accepted_if_quality_does_not_match_for_full_season_pack()
|
|
||||||
{
|
|
||||||
GivenGrabbedEpisodeHistory(new QualityModel(Quality.SDTV));
|
|
||||||
_localEpisode.DownloadClientEpisodeInfo.FullSeason = true;
|
|
||||||
|
|
||||||
Subject.IsSatisfiedBy(_localEpisode, _downloadClientItem).Accepted.Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_be_accepted_if_no_grabbed_episode_history()
|
|
||||||
{
|
|
||||||
Mocker.GetMock<IHistoryService>()
|
|
||||||
.Setup(s => s.FindByDownloadId(It.IsAny<string>()))
|
|
||||||
.Returns(new List<EpisodeHistory>());
|
|
||||||
|
|
||||||
_localEpisode.Episodes = Builder<Episode>.CreateListOfSize(1)
|
|
||||||
.TheFirst(1)
|
|
||||||
.With(e => e.EpisodeFileId = 0)
|
|
||||||
.BuildList();
|
|
||||||
|
|
||||||
Subject.IsSatisfiedBy(_localEpisode, _downloadClientItem).Accepted.Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_be_accepted_if_quality_matches()
|
|
||||||
{
|
|
||||||
GivenGrabbedEpisodeHistory(_localEpisode.Quality);
|
|
||||||
|
|
||||||
Subject.IsSatisfiedBy(_localEpisode, _downloadClientItem).Accepted.Should().BeTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_be_rejected_if_quality_does_not_match()
|
|
||||||
{
|
|
||||||
GivenGrabbedEpisodeHistory(new QualityModel(Quality.SDTV));
|
|
||||||
|
|
||||||
Subject.IsSatisfiedBy(_localEpisode, _downloadClientItem).Accepted.Should().BeFalse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -73,7 +73,9 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||||
public void should_parse_quality_from_extension(string title)
|
public void should_parse_quality_from_extension(string title)
|
||||||
{
|
{
|
||||||
Parser.Parser.ParseTitle(title).Quality.Quality.Should().NotBe(Quality.Unknown);
|
Parser.Parser.ParseTitle(title).Quality.Quality.Should().NotBe(Quality.Unknown);
|
||||||
Parser.Parser.ParseTitle(title).Quality.QualityDetectionSource.Should().Be(QualityDetectionSource.Extension);
|
Parser.Parser.ParseTitle(title).Quality.SourceDetectionSource.Should().Be(QualityDetectionSource.Extension);
|
||||||
|
Parser.Parser.ParseTitle(title).Quality.ResolutionDetectionSource.Should().Be(QualityDetectionSource.Extension);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -366,13 +366,45 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("Saturday.Night.Live.Vintage.S10E09.Eddie.Murphy.The.Honeydrippers.1080i.UPSCALE.HDTV.DD5.1.MPEG2-zebra")]
|
|
||||||
[TestCase("Dexter - S01E01 - Title [HDTV-1080p]")]
|
[TestCase("Dexter - S01E01 - Title [HDTV-1080p]")]
|
||||||
[TestCase("[CR] Sailor Moon - 004 [480p][48CE2D0F]")]
|
[TestCase("Saturday.Night.Live.Vintage.S10E09.Eddie.Murphy.The.Honeydrippers.1080i.UPSCALE.HDTV.DD5.1.MPEG2-zebra")]
|
||||||
[TestCase("White.Van.Man.2011.S02E01.WS.PDTV.x264-REPACK-TLA")]
|
[TestCase("Series.Title.S01E01.Bluray720p")]
|
||||||
public void should_parse_quality_from_name(string title)
|
[TestCase("Series.Title.S01E01.Bluray1080p")]
|
||||||
|
[TestCase("Series.Title.S01E01.Bluray2160p")]
|
||||||
|
[TestCase("Series.Title.S01E01.848x480.dvd")]
|
||||||
|
[TestCase("Series.Title.S01E01.848x480.Bluray")]
|
||||||
|
[TestCase("Series.Title.S01E01.1280x720.Bluray")]
|
||||||
|
[TestCase("Series.Title.S01E01.1920x1080.Bluray")]
|
||||||
|
public void should_parse_full_quality_from_name(string title)
|
||||||
{
|
{
|
||||||
QualityParser.ParseQuality(title).QualityDetectionSource.Should().Be(QualityDetectionSource.Name);
|
var result = QualityParser.ParseQuality(title);
|
||||||
|
|
||||||
|
result.SourceDetectionSource.Should().Be(QualityDetectionSource.Name);
|
||||||
|
result.ResolutionDetectionSource.Should().Be(QualityDetectionSource.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("[CR] Sailor Moon - 004 [480p][48CE2D0F]")]
|
||||||
|
[TestCase("Series.Title.S01E01.848x480")]
|
||||||
|
[TestCase("Series.Title.S01E01.1280x720")]
|
||||||
|
[TestCase("Series.Title.S01E01.1920x1080")]
|
||||||
|
public void should_parse_resolution_from_name(string title)
|
||||||
|
{
|
||||||
|
var result = QualityParser.ParseQuality(title);
|
||||||
|
|
||||||
|
result.SourceDetectionSource.Should().Be(QualityDetectionSource.Unknown);
|
||||||
|
result.ResolutionDetectionSource.Should().Be(QualityDetectionSource.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("White.Van.Man.2011.S02E01.WS.PDTV.x264-REPACK-TLA")]
|
||||||
|
[TestCase("Series.Title.S01E01.Bluray")]
|
||||||
|
[TestCase("Series.Title.S01E01.HD.TV")]
|
||||||
|
[TestCase("Series.Title.S01E01.SD.TV")]
|
||||||
|
public void should_parse_source_from_name(string title)
|
||||||
|
{
|
||||||
|
var result = QualityParser.ParseQuality(title);
|
||||||
|
|
||||||
|
result.SourceDetectionSource.Should().Be(QualityDetectionSource.Name);
|
||||||
|
result.ResolutionDetectionSource.Should().Be(QualityDetectionSource.Unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("Revolution.S01E02.Chained.Heat.mkv")]
|
[TestCase("Revolution.S01E02.Chained.Heat.mkv")]
|
||||||
|
@ -381,7 +413,20 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||||
[TestCase("[CR] Sailor Moon - 004 [48CE2D0F].avi")]
|
[TestCase("[CR] Sailor Moon - 004 [48CE2D0F].avi")]
|
||||||
public void should_parse_quality_from_extension(string title)
|
public void should_parse_quality_from_extension(string title)
|
||||||
{
|
{
|
||||||
QualityParser.ParseQuality(title).QualityDetectionSource.Should().Be(QualityDetectionSource.Extension);
|
var result = QualityParser.ParseQuality(title);
|
||||||
|
|
||||||
|
result.SourceDetectionSource.Should().Be(QualityDetectionSource.Extension);
|
||||||
|
result.ResolutionDetectionSource.Should().Be(QualityDetectionSource.Extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase("Revolution.S01E02.Chained.Heat.1080p.mkv")]
|
||||||
|
[TestCase("Dexter - S01E01 - Title.720p.avi")]
|
||||||
|
public void should_parse_resolution_from_name_and_source_from_extension(string title)
|
||||||
|
{
|
||||||
|
var result = QualityParser.ParseQuality(title);
|
||||||
|
|
||||||
|
result.SourceDetectionSource.Should().Be(QualityDetectionSource.Extension);
|
||||||
|
result.ResolutionDetectionSource.Should().Be(QualityDetectionSource.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("Series Title S04E87 REPACK 720p HDTV x264 aAF", true)]
|
[TestCase("Series Title S04E87 REPACK 720p HDTV x264 aAF", true)]
|
||||||
|
|
|
@ -84,7 +84,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only based on title because a release with the same title on another indexer/released at
|
// Only based on title because a release with the same title on another indexer/released at
|
||||||
// a different time very likely has the exact same content and we don't need to also try it.
|
// a different time very likely has the exact same content and we don't need to also try it.
|
||||||
|
|
||||||
if (release.Title.Equals(lastGrabbed.SourceTitle, StringComparison.InvariantCultureIgnoreCase))
|
if (release.Title.Equals(lastGrabbed.SourceTitle, StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
|
|
@ -13,7 +13,6 @@ namespace NzbDrone.Core.Download
|
||||||
public string DownloadId { get; set; }
|
public string DownloadId { get; set; }
|
||||||
public string Category { get; set; }
|
public string Category { get; set; }
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
|
|
||||||
public long TotalSize { get; set; }
|
public long TotalSize { get; set; }
|
||||||
public long RemainingSize { get; set; }
|
public long RemainingSize { get; set; }
|
||||||
public TimeSpan? RemainingTime { get; set; }
|
public TimeSpan? RemainingTime { get; set; }
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Core.History;
|
using NzbDrone.Core.History;
|
||||||
using NzbDrone.Core.MediaFiles.Events;
|
using NzbDrone.Core.MediaFiles.Events;
|
||||||
|
@ -13,6 +14,7 @@ namespace NzbDrone.Core.Download.History
|
||||||
{
|
{
|
||||||
bool DownloadAlreadyImported(string downloadId);
|
bool DownloadAlreadyImported(string downloadId);
|
||||||
DownloadHistory GetLatestDownloadHistoryItem(string downloadId);
|
DownloadHistory GetLatestDownloadHistoryItem(string downloadId);
|
||||||
|
DownloadHistory GetLatestGrab(string downloadId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DownloadHistoryService : IDownloadHistoryService,
|
public class DownloadHistoryService : IDownloadHistoryService,
|
||||||
|
@ -86,6 +88,12 @@ namespace NzbDrone.Core.Download.History
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DownloadHistory GetLatestGrab(string downloadId)
|
||||||
|
{
|
||||||
|
return _repository.FindByDownloadId(downloadId)
|
||||||
|
.FirstOrDefault(d => d.EventType == DownloadHistoryEventType.DownloadGrabbed);
|
||||||
|
}
|
||||||
|
|
||||||
public void Handle(EpisodeGrabbedEvent message)
|
public void Handle(EpisodeGrabbedEvent message)
|
||||||
{
|
{
|
||||||
// Don't store grabbed events for clients that don't download IDs
|
// Don't store grabbed events for clients that don't download IDs
|
||||||
|
|
|
@ -71,7 +71,7 @@ namespace NzbDrone.Core.Extras.Metadata
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_aggregationService.Augment(localEpisode, false);
|
_aggregationService.Augment(localEpisode, null, false);
|
||||||
}
|
}
|
||||||
catch (AugmentingFailedException)
|
catch (AugmentingFailedException)
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,7 +56,7 @@ namespace NzbDrone.Core.Extras.Others
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_aggregationService.Augment(localEpisode, false);
|
_aggregationService.Augment(localEpisode, null, false);
|
||||||
}
|
}
|
||||||
catch (AugmentingFailedException)
|
catch (AugmentingFailedException)
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace NzbDrone.Core.Extras.Subtitles
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_aggregationService.Augment(localEpisode, false);
|
_aggregationService.Augment(localEpisode, null, false);
|
||||||
}
|
}
|
||||||
catch (AugmentingFailedException)
|
catch (AugmentingFailedException)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,6 +4,7 @@ using System.IO;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
using NzbDrone.Core.Configuration;
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators;
|
using NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators;
|
||||||
using NzbDrone.Core.MediaFiles.MediaInfo;
|
using NzbDrone.Core.MediaFiles.MediaInfo;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
@ -12,7 +13,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation
|
||||||
{
|
{
|
||||||
public interface IAggregationService
|
public interface IAggregationService
|
||||||
{
|
{
|
||||||
LocalEpisode Augment(LocalEpisode localEpisode, bool otherFiles);
|
LocalEpisode Augment(LocalEpisode localEpisode, DownloadClientItem downloadClientItem, bool otherFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AggregationService : IAggregationService
|
public class AggregationService : IAggregationService
|
||||||
|
@ -36,7 +37,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalEpisode Augment(LocalEpisode localEpisode, bool otherFiles)
|
public LocalEpisode Augment(LocalEpisode localEpisode, DownloadClientItem downloadClientItem, bool otherFiles)
|
||||||
{
|
{
|
||||||
var isMediaFile = MediaFileExtensions.Extensions.Contains(Path.GetExtension(localEpisode.Path));
|
var isMediaFile = MediaFileExtensions.Extensions.Contains(Path.GetExtension(localEpisode.Path));
|
||||||
|
|
||||||
|
@ -61,7 +62,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
augmenter.Aggregate(localEpisode, otherFiles);
|
augmenter.Aggregate(localEpisode, downloadClientItem, otherFiles);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Parser;
|
using NzbDrone.Core.Parser;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
@ -15,7 +16,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
_parsingService = parsingService;
|
_parsingService = parsingService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalEpisode Aggregate(LocalEpisode localEpisode, bool otherFiles)
|
public LocalEpisode Aggregate(LocalEpisode localEpisode, DownloadClientItem downloadClientItem, bool otherFiles)
|
||||||
{
|
{
|
||||||
localEpisode.Episodes = GetEpisodes(localEpisode, otherFiles);
|
localEpisode.Episodes = GetEpisodes(localEpisode, otherFiles);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Languages;
|
using NzbDrone.Core.Languages;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
@ -15,7 +16,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalEpisode Aggregate(LocalEpisode localEpisode, bool otherFiles)
|
public LocalEpisode Aggregate(LocalEpisode localEpisode, DownloadClientItem downloadClientItem, bool otherFiles)
|
||||||
{
|
{
|
||||||
// Get languages in preferred order, download client item, folder and finally file.
|
// Get languages in preferred order, download client item, folder and finally file.
|
||||||
// Non-English languages will be preferred later, in the event there is a conflict
|
// Non-English languages will be preferred later, in the event there is a conflict
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality;
|
using NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
|
@ -19,55 +20,65 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalEpisode Aggregate(LocalEpisode localEpisode, bool otherFiles)
|
public LocalEpisode Aggregate(LocalEpisode localEpisode, DownloadClientItem downloadClientItem, bool otherFiles)
|
||||||
{
|
{
|
||||||
var augmentedQualities = _augmentQualities.Select(a => a.AugmentQuality(localEpisode))
|
var augmentedQualities = _augmentQualities.OrderBy(a => a.Order)
|
||||||
|
.Select(a => a.AugmentQuality(localEpisode, downloadClientItem))
|
||||||
.Where(a => a != null)
|
.Where(a => a != null)
|
||||||
.OrderBy(a => a.SourceConfidence);
|
.ToList();
|
||||||
|
|
||||||
var source = QualitySource.Unknown;
|
var source = QualitySource.Unknown;
|
||||||
var sourceConfidence = Confidence.Default;
|
var sourceConfidence = Confidence.Default;
|
||||||
var resolution = 0;
|
var resolution = 0;
|
||||||
var resolutionConfidence = Confidence.Default;
|
var resolutionConfidence = Confidence.Default;
|
||||||
var revison = new Revision();
|
var revision = new Revision();
|
||||||
|
|
||||||
foreach (var augmentedQuality in augmentedQualities)
|
foreach (var augmentedQuality in augmentedQualities)
|
||||||
{
|
{
|
||||||
if (augmentedQuality.Source > source ||
|
if (source == QualitySource.Unknown ||
|
||||||
augmentedQuality.SourceConfidence > sourceConfidence && augmentedQuality.Source != QualitySource.Unknown)
|
augmentedQuality.SourceConfidence > sourceConfidence && augmentedQuality.Source != QualitySource.Unknown)
|
||||||
{
|
{
|
||||||
source = augmentedQuality.Source;
|
source = augmentedQuality.Source;
|
||||||
sourceConfidence = augmentedQuality.SourceConfidence;
|
sourceConfidence = augmentedQuality.SourceConfidence;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (augmentedQuality.Resolution > resolution ||
|
if (resolution == 0 ||
|
||||||
augmentedQuality.ResolutionConfidence > resolutionConfidence && augmentedQuality.Resolution > 0)
|
augmentedQuality.ResolutionConfidence > resolutionConfidence && augmentedQuality.Resolution > 0)
|
||||||
{
|
{
|
||||||
resolution = augmentedQuality.Resolution;
|
resolution = augmentedQuality.Resolution;
|
||||||
resolutionConfidence = augmentedQuality.ResolutionConfidence;
|
resolutionConfidence = augmentedQuality.ResolutionConfidence;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (augmentedQuality.Revision != null && augmentedQuality.Revision > revison)
|
if (augmentedQuality.Revision != null && augmentedQuality.Revision > revision)
|
||||||
{
|
{
|
||||||
revison = augmentedQuality.Revision;
|
revision = augmentedQuality.Revision;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Trace("Finding quality. Source: {0}. Resolution: {1}", source, resolution);
|
_logger.Trace("Finding quality. Source: {0}. Resolution: {1}", source, resolution);
|
||||||
|
|
||||||
var quality = new QualityModel(QualityFinder.FindBySourceAndResolution(source, resolution), revison);
|
var quality = new QualityModel(QualityFinder.FindBySourceAndResolution(source, resolution), revision);
|
||||||
|
|
||||||
if (resolutionConfidence == Confidence.MediaInfo)
|
if (resolutionConfidence == Confidence.MediaInfo)
|
||||||
{
|
{
|
||||||
quality.QualityDetectionSource = QualityDetectionSource.MediaInfo;
|
quality.ResolutionDetectionSource = QualityDetectionSource.MediaInfo;
|
||||||
}
|
}
|
||||||
else if (sourceConfidence == Confidence.Fallback || resolutionConfidence == Confidence.Fallback)
|
else if (resolutionConfidence == Confidence.Fallback)
|
||||||
{
|
{
|
||||||
quality.QualityDetectionSource = QualityDetectionSource.Extension;
|
quality.ResolutionDetectionSource = QualityDetectionSource.Extension;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
quality.QualityDetectionSource = QualityDetectionSource.Name;
|
quality.ResolutionDetectionSource = QualityDetectionSource.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sourceConfidence == Confidence.Fallback)
|
||||||
|
{
|
||||||
|
quality.SourceDetectionSource = QualityDetectionSource.Extension;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
quality.SourceDetectionSource = QualityDetectionSource.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Debug("Using quality: {0}", quality);
|
_logger.Debug("Using quality: {0}", quality);
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
{
|
{
|
||||||
public class AggregateReleaseGroup : IAggregateLocalEpisode
|
public class AggregateReleaseGroup : IAggregateLocalEpisode
|
||||||
{
|
{
|
||||||
public LocalEpisode Aggregate(LocalEpisode localEpisode, bool otherFiles)
|
public LocalEpisode Aggregate(LocalEpisode localEpisode, DownloadClientItem downloadClientItem, bool otherFiles)
|
||||||
{
|
{
|
||||||
// Prefer ReleaseGroup from DownloadClient/Folder if they're not a season pack
|
// Prefer ReleaseGroup from DownloadClient/Folder if they're not a season pack
|
||||||
var releaseGroup = GetReleaseGroup(localEpisode.DownloadClientEpisodeInfo, true);
|
var releaseGroup = GetReleaseGroup(localEpisode.DownloadClientEpisodeInfo, true);
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
|
||||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality
|
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality
|
||||||
{
|
{
|
||||||
public class AugmentQualityFromDownloadClientItem : IAugmentQuality
|
public class AugmentQualityFromDownloadClientItem : IAugmentQuality
|
||||||
{
|
{
|
||||||
public AugmentQualityResult AugmentQuality(LocalEpisode localEpisode)
|
public int Order => 3;
|
||||||
|
|
||||||
|
public AugmentQualityResult AugmentQuality(LocalEpisode localEpisode, DownloadClientItem downloadClientItem)
|
||||||
{
|
{
|
||||||
var quality = localEpisode.DownloadClientEpisodeInfo?.Quality;
|
var quality = localEpisode.DownloadClientEpisodeInfo?.Quality;
|
||||||
|
|
||||||
|
@ -13,10 +17,18 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augment
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sourceConfidence = quality.SourceDetectionSource == QualityDetectionSource.Name
|
||||||
|
? Confidence.Tag
|
||||||
|
: Confidence.Fallback;
|
||||||
|
|
||||||
|
var resolutionConfidence = quality.ResolutionDetectionSource == QualityDetectionSource.Name
|
||||||
|
? Confidence.Tag
|
||||||
|
: Confidence.Fallback;
|
||||||
|
|
||||||
return new AugmentQualityResult(quality.Quality.Source,
|
return new AugmentQualityResult(quality.Quality.Source,
|
||||||
Confidence.Tag,
|
sourceConfidence,
|
||||||
quality.Quality.Resolution,
|
quality.Quality.Resolution,
|
||||||
Confidence.Tag,
|
resolutionConfidence,
|
||||||
quality.Revision);
|
quality.Revision);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Core.Qualities;
|
using NzbDrone.Core.Qualities;
|
||||||
|
|
||||||
|
@ -5,7 +6,9 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augment
|
||||||
{
|
{
|
||||||
public class AugmentQualityFromFileName : IAugmentQuality
|
public class AugmentQualityFromFileName : IAugmentQuality
|
||||||
{
|
{
|
||||||
public AugmentQualityResult AugmentQuality(LocalEpisode localEpisode)
|
public int Order => 1;
|
||||||
|
|
||||||
|
public AugmentQualityResult AugmentQuality(LocalEpisode localEpisode, DownloadClientItem downloadClientItem)
|
||||||
{
|
{
|
||||||
var quality = localEpisode.FileEpisodeInfo?.Quality;
|
var quality = localEpisode.FileEpisodeInfo?.Quality;
|
||||||
|
|
||||||
|
@ -14,14 +17,18 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augment
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var confidence = quality.QualityDetectionSource == QualityDetectionSource.Extension
|
var sourceConfidence = quality.SourceDetectionSource == QualityDetectionSource.Name
|
||||||
? Confidence.Fallback
|
? Confidence.Tag
|
||||||
: Confidence.Tag;
|
: Confidence.Fallback;
|
||||||
|
|
||||||
|
var resolutionConfidence = quality.ResolutionDetectionSource == QualityDetectionSource.Name
|
||||||
|
? Confidence.Tag
|
||||||
|
: Confidence.Fallback;
|
||||||
|
|
||||||
return new AugmentQualityResult(quality.Quality.Source,
|
return new AugmentQualityResult(quality.Quality.Source,
|
||||||
confidence,
|
sourceConfidence,
|
||||||
quality.Quality.Resolution,
|
quality.Quality.Resolution,
|
||||||
confidence,
|
resolutionConfidence,
|
||||||
quality.Revision);
|
quality.Revision);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
|
||||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality
|
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality
|
||||||
{
|
{
|
||||||
public class AugmentQualityFromFolder : IAugmentQuality
|
public class AugmentQualityFromFolder : IAugmentQuality
|
||||||
{
|
{
|
||||||
public AugmentQualityResult AugmentQuality(LocalEpisode localEpisode)
|
public int Order => 2;
|
||||||
|
|
||||||
|
public AugmentQualityResult AugmentQuality(LocalEpisode localEpisode, DownloadClientItem downloadClientItem)
|
||||||
{
|
{
|
||||||
var quality = localEpisode.FolderEpisodeInfo?.Quality;
|
var quality = localEpisode.FolderEpisodeInfo?.Quality;
|
||||||
|
|
||||||
|
@ -13,10 +17,18 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augment
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sourceConfidence = quality.SourceDetectionSource == QualityDetectionSource.Name
|
||||||
|
? Confidence.Tag
|
||||||
|
: Confidence.Fallback;
|
||||||
|
|
||||||
|
var resolutionConfidence = quality.ResolutionDetectionSource == QualityDetectionSource.Name
|
||||||
|
? Confidence.Tag
|
||||||
|
: Confidence.Fallback;
|
||||||
|
|
||||||
return new AugmentQualityResult(quality.Quality.Source,
|
return new AugmentQualityResult(quality.Quality.Source,
|
||||||
Confidence.Tag,
|
sourceConfidence,
|
||||||
quality.Quality.Resolution,
|
quality.Quality.Resolution,
|
||||||
Confidence.Tag,
|
resolutionConfidence,
|
||||||
quality.Revision);
|
quality.Revision);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality
|
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality
|
||||||
{
|
{
|
||||||
public class AugmentQualityFromMediaInfo : IAugmentQuality
|
public class AugmentQualityFromMediaInfo : IAugmentQuality
|
||||||
{
|
{
|
||||||
public AugmentQualityResult AugmentQuality(LocalEpisode localEpisode)
|
public int Order => 4;
|
||||||
|
|
||||||
|
public AugmentQualityResult AugmentQuality(LocalEpisode localEpisode, DownloadClientItem downloadClientItem)
|
||||||
{
|
{
|
||||||
if (localEpisode.MediaInfo == null)
|
if (localEpisode.MediaInfo == null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
|
using NzbDrone.Core.Download.History;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality
|
||||||
|
{
|
||||||
|
public class AugmentQualityFromReleaseName : IAugmentQuality
|
||||||
|
{
|
||||||
|
public int Order => 5;
|
||||||
|
|
||||||
|
private readonly IDownloadHistoryService _downloadHistoryService;
|
||||||
|
|
||||||
|
public AugmentQualityFromReleaseName(IDownloadHistoryService downloadHistoryService)
|
||||||
|
{
|
||||||
|
_downloadHistoryService = downloadHistoryService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AugmentQualityResult AugmentQuality(LocalEpisode localEpisode, DownloadClientItem downloadClientItem)
|
||||||
|
{
|
||||||
|
// Don't try to augment if we can't lookup the grabbed history by downloadId
|
||||||
|
if (downloadClientItem == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var history = _downloadHistoryService.GetLatestGrab(downloadClientItem.DownloadId);
|
||||||
|
|
||||||
|
if (history == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var historyQuality = QualityParser.ParseQuality(history.SourceTitle);
|
||||||
|
|
||||||
|
var sourceConfidence = historyQuality.SourceDetectionSource == QualityDetectionSource.Name
|
||||||
|
? Confidence.Tag
|
||||||
|
: Confidence.Fallback;
|
||||||
|
|
||||||
|
var resolutionConfidence = historyQuality.ResolutionDetectionSource == QualityDetectionSource.Name
|
||||||
|
? Confidence.Tag
|
||||||
|
: Confidence.Fallback;
|
||||||
|
|
||||||
|
return new AugmentQualityResult(historyQuality.Quality.Source, sourceConfidence, historyQuality.Quality.Resolution, resolutionConfidence, historyQuality.Revision);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,11 @@
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality
|
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality
|
||||||
{
|
{
|
||||||
public interface IAugmentQuality
|
public interface IAugmentQuality
|
||||||
{
|
{
|
||||||
AugmentQualityResult AugmentQuality(LocalEpisode localEpisode);
|
int Order { get; }
|
||||||
|
AugmentQualityResult AugmentQuality(LocalEpisode localEpisode, DownloadClientItem downloadClientItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
|
using NzbDrone.Core.Download;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||||
{
|
{
|
||||||
public interface IAggregateLocalEpisode
|
public interface IAggregateLocalEpisode
|
||||||
{
|
{
|
||||||
LocalEpisode Aggregate(LocalEpisode localEpisode, bool otherFiles);
|
LocalEpisode Aggregate(LocalEpisode localEpisode, DownloadClientItem downloadClientItem, bool otherFiles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_aggregationService.Augment(localEpisode, otherFiles);
|
_aggregationService.Augment(localEpisode, downloadClientItem, otherFiles);
|
||||||
|
|
||||||
if (localEpisode.Episodes.Empty())
|
if (localEpisode.Episodes.Empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -319,7 +319,7 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport.Manual
|
||||||
localEpisode.FolderEpisodeInfo = Parser.Parser.ParseTitle(file.FolderName);
|
localEpisode.FolderEpisodeInfo = Parser.Parser.ParseTitle(file.FolderName);
|
||||||
}
|
}
|
||||||
|
|
||||||
localEpisode = _aggregationService.Augment(localEpisode, false);
|
localEpisode = _aggregationService.Augment(localEpisode, trackedDownload?.DownloadItem, false);
|
||||||
|
|
||||||
// Apply the user-chosen values.
|
// Apply the user-chosen values.
|
||||||
localEpisode.Series = series;
|
localEpisode.Series = series;
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
using System.Linq;
|
|
||||||
using NLog;
|
|
||||||
using NzbDrone.Core.DecisionEngine;
|
|
||||||
using NzbDrone.Core.Download;
|
|
||||||
using NzbDrone.Core.History;
|
|
||||||
using NzbDrone.Core.Parser.Model;
|
|
||||||
using NzbDrone.Core.Qualities;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Specifications
|
|
||||||
{
|
|
||||||
public class DifferentQualitySpecification : IImportDecisionEngineSpecification
|
|
||||||
{
|
|
||||||
private readonly IHistoryService _historyService;
|
|
||||||
private readonly Logger _logger;
|
|
||||||
|
|
||||||
public DifferentQualitySpecification(IHistoryService historyService, Logger logger)
|
|
||||||
{
|
|
||||||
_historyService = historyService;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
public Decision IsSatisfiedBy(LocalEpisode localEpisode, DownloadClientItem downloadClientItem)
|
|
||||||
{
|
|
||||||
if (downloadClientItem == null)
|
|
||||||
{
|
|
||||||
_logger.Debug("No download client item, skipping");
|
|
||||||
return Decision.Accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (localEpisode.DownloadClientEpisodeInfo?.FullSeason == true)
|
|
||||||
{
|
|
||||||
_logger.Debug("Full season download, skipping");
|
|
||||||
return Decision.Accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
var grabbedEpisodeHistory = _historyService.FindByDownloadId(downloadClientItem.DownloadId)
|
|
||||||
.OrderByDescending(h => h.Date)
|
|
||||||
.FirstOrDefault(h => h.EventType == EpisodeHistoryEventType.Grabbed);
|
|
||||||
|
|
||||||
if (grabbedEpisodeHistory == null)
|
|
||||||
{
|
|
||||||
_logger.Debug("No grabbed history for this download item, skipping");
|
|
||||||
return Decision.Accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
var qualityComparer = new QualityModelComparer(localEpisode.Series.QualityProfile);
|
|
||||||
var qualityCompare = qualityComparer.Compare(localEpisode.Quality, grabbedEpisodeHistory.Quality);
|
|
||||||
|
|
||||||
if (qualityCompare != 0)
|
|
||||||
{
|
|
||||||
_logger.Debug("Quality of file ({0}) does not match quality of grabbed release ({1})", localEpisode.Quality, grabbedEpisodeHistory.Quality);
|
|
||||||
return Decision.Reject("Quality of file ({0}) does not match quality of grabbed release ({1})", localEpisode.Quality, grabbedEpisodeHistory.Quality);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Decision.Accept();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,6 +2,7 @@ using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Web.UI;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Instrumentation;
|
using NzbDrone.Common.Instrumentation;
|
||||||
|
@ -72,7 +73,8 @@ namespace NzbDrone.Core.Parser
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result.Quality = MediaFileExtensions.GetQualityForExtension(Path.GetExtension(name));
|
result.Quality = MediaFileExtensions.GetQualityForExtension(Path.GetExtension(name));
|
||||||
result.QualityDetectionSource = QualityDetectionSource.Extension;
|
result.SourceDetectionSource = QualityDetectionSource.Extension;
|
||||||
|
result.ResolutionDetectionSource = QualityDetectionSource.Extension;
|
||||||
}
|
}
|
||||||
catch (ArgumentException)
|
catch (ArgumentException)
|
||||||
{
|
{
|
||||||
|
@ -91,7 +93,10 @@ namespace NzbDrone.Core.Parser
|
||||||
|
|
||||||
if (RawHDRegex.IsMatch(normalizedName))
|
if (RawHDRegex.IsMatch(normalizedName))
|
||||||
{
|
{
|
||||||
|
result.SourceDetectionSource = QualityDetectionSource.Name;
|
||||||
|
result.ResolutionDetectionSource = QualityDetectionSource.Name;
|
||||||
result.Quality = Quality.RAWHD;
|
result.Quality = Quality.RAWHD;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,8 +106,15 @@ namespace NzbDrone.Core.Parser
|
||||||
var codecRegex = CodecRegex.Match(normalizedName);
|
var codecRegex = CodecRegex.Match(normalizedName);
|
||||||
var remuxMatch = RemuxRegex.IsMatch(normalizedName);
|
var remuxMatch = RemuxRegex.IsMatch(normalizedName);
|
||||||
|
|
||||||
|
if (resolution != Resolution.Unknown)
|
||||||
|
{
|
||||||
|
result.ResolutionDetectionSource = QualityDetectionSource.Name;
|
||||||
|
}
|
||||||
|
|
||||||
if (sourceMatch != null && sourceMatch.Success)
|
if (sourceMatch != null && sourceMatch.Success)
|
||||||
{
|
{
|
||||||
|
result.SourceDetectionSource = QualityDetectionSource.Name;
|
||||||
|
|
||||||
if (sourceMatch.Groups["bluray"].Success)
|
if (sourceMatch.Groups["bluray"].Success)
|
||||||
{
|
{
|
||||||
if (codecRegex.Groups["xvid"].Success || codecRegex.Groups["divx"].Success)
|
if (codecRegex.Groups["xvid"].Success || codecRegex.Groups["divx"].Success)
|
||||||
|
@ -267,6 +279,7 @@ namespace NzbDrone.Core.Parser
|
||||||
|
|
||||||
if (HighDefPdtvRegex.IsMatch(normalizedName))
|
if (HighDefPdtvRegex.IsMatch(normalizedName))
|
||||||
{
|
{
|
||||||
|
result.ResolutionDetectionSource = QualityDetectionSource.Name;
|
||||||
result.Quality = Quality.HDTV720p;
|
result.Quality = Quality.HDTV720p;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -276,26 +289,33 @@ namespace NzbDrone.Core.Parser
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Anime Bluray matching
|
// Anime Bluray matching
|
||||||
if (AnimeBlurayRegex.Match(normalizedName).Success)
|
if (AnimeBlurayRegex.Match(normalizedName).Success)
|
||||||
{
|
{
|
||||||
|
result.SourceDetectionSource = QualityDetectionSource.Name;
|
||||||
|
|
||||||
if (resolution == Resolution.R360P || resolution == Resolution.R480P ||
|
if (resolution == Resolution.R360P || resolution == Resolution.R480P ||
|
||||||
resolution == Resolution.R576p || normalizedName.ContainsIgnoreCase("480p"))
|
resolution == Resolution.R576p || normalizedName.ContainsIgnoreCase("480p"))
|
||||||
{
|
{
|
||||||
|
result.ResolutionDetectionSource = QualityDetectionSource.Name;
|
||||||
result.Quality = Quality.DVD;
|
result.Quality = Quality.DVD;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resolution == Resolution.R1080p || normalizedName.ContainsIgnoreCase("1080p"))
|
if (resolution == Resolution.R1080p || normalizedName.ContainsIgnoreCase("1080p"))
|
||||||
{
|
{
|
||||||
|
result.ResolutionDetectionSource = QualityDetectionSource.Name;
|
||||||
result.Quality = remuxMatch ? Quality.Bluray1080pRemux : Quality.Bluray1080p;
|
result.Quality = remuxMatch ? Quality.Bluray1080pRemux : Quality.Bluray1080p;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resolution == Resolution.R2160p || normalizedName.ContainsIgnoreCase("2160p"))
|
if (resolution == Resolution.R2160p || normalizedName.ContainsIgnoreCase("2160p"))
|
||||||
{
|
{
|
||||||
|
result.ResolutionDetectionSource = QualityDetectionSource.Name;
|
||||||
result.Quality = remuxMatch ? Quality.Bluray2160pRemux : Quality.Bluray2160p;
|
result.Quality = remuxMatch ? Quality.Bluray2160pRemux : Quality.Bluray2160p;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,85 +330,167 @@ namespace NzbDrone.Core.Parser
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resolution == Resolution.R2160p)
|
if (resolution != Resolution.Unknown)
|
||||||
{
|
{
|
||||||
result.Quality = remuxMatch ? Quality.Bluray2160pRemux : Quality.HDTV2160p;
|
var source = QualitySource.Unknown;
|
||||||
return result;
|
|
||||||
|
if (remuxMatch)
|
||||||
|
{
|
||||||
|
result.SourceDetectionSource = QualityDetectionSource.Name;
|
||||||
|
source = QualitySource.BlurayRaw;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var quality = MediaFileExtensions.GetQualityForExtension(Path.GetExtension(name));
|
||||||
|
|
||||||
|
if (quality != Quality.Unknown)
|
||||||
|
{
|
||||||
|
result.SourceDetectionSource = QualityDetectionSource.Extension;
|
||||||
|
source = quality.Source;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resolution == Resolution.R2160p)
|
||||||
|
{
|
||||||
|
result.ResolutionDetectionSource = QualityDetectionSource.Name;
|
||||||
|
|
||||||
|
result.Quality = source == QualitySource.Unknown
|
||||||
|
? Quality.HDTV2160p
|
||||||
|
: QualityFinder.FindBySourceAndResolution(source, 2160);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resolution == Resolution.R1080p)
|
||||||
|
{
|
||||||
|
result.ResolutionDetectionSource = QualityDetectionSource.Name;
|
||||||
|
|
||||||
|
result.Quality = source == QualitySource.Unknown
|
||||||
|
? Quality.HDTV1080p
|
||||||
|
: QualityFinder.FindBySourceAndResolution(source, 1080);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resolution == Resolution.R720p)
|
||||||
|
{
|
||||||
|
result.ResolutionDetectionSource = QualityDetectionSource.Name;
|
||||||
|
|
||||||
|
result.Quality = source == QualitySource.Unknown
|
||||||
|
? Quality.HDTV720p
|
||||||
|
: QualityFinder.FindBySourceAndResolution(source, 720);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resolution == Resolution.R360P || resolution == Resolution.R480P)
|
||||||
|
{
|
||||||
|
result.ResolutionDetectionSource = QualityDetectionSource.Name;
|
||||||
|
|
||||||
|
result.Quality = source == QualitySource.Unknown
|
||||||
|
? Quality.SDTV
|
||||||
|
: QualityFinder.FindBySourceAndResolution(source, 480);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resolution == Resolution.R1080p)
|
|
||||||
{
|
|
||||||
result.Quality = remuxMatch ? Quality.Bluray1080pRemux : Quality.HDTV1080p;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resolution == Resolution.R720p)
|
|
||||||
{
|
|
||||||
result.Quality = Quality.HDTV720p;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resolution == Resolution.R360P || resolution == Resolution.R480P)
|
|
||||||
{
|
|
||||||
result.Quality = Quality.SDTV;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (codecRegex.Groups["x264"].Success)
|
if (codecRegex.Groups["x264"].Success)
|
||||||
{
|
{
|
||||||
result.Quality = Quality.SDTV;
|
result.Quality = Quality.SDTV;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normalizedName.Contains("848x480"))
|
if (normalizedName.Contains("848x480"))
|
||||||
{
|
{
|
||||||
|
result.ResolutionDetectionSource = QualityDetectionSource.Name;
|
||||||
|
|
||||||
if (normalizedName.Contains("dvd"))
|
if (normalizedName.Contains("dvd"))
|
||||||
{
|
{
|
||||||
|
result.SourceDetectionSource = QualityDetectionSource.Name;
|
||||||
result.Quality = Quality.DVD;
|
result.Quality = Quality.DVD;
|
||||||
}
|
}
|
||||||
|
else if (normalizedName.ContainsIgnoreCase("bluray"))
|
||||||
|
{
|
||||||
|
result.SourceDetectionSource = QualityDetectionSource.Name;
|
||||||
|
result.Quality = Quality.Bluray480p;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.Quality = Quality.SDTV;
|
||||||
|
}
|
||||||
|
|
||||||
result.Quality = Quality.SDTV;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normalizedName.ContainsIgnoreCase("1280x720"))
|
if (normalizedName.ContainsIgnoreCase("1280x720"))
|
||||||
{
|
{
|
||||||
|
result.ResolutionDetectionSource = QualityDetectionSource.Name;
|
||||||
|
|
||||||
if (normalizedName.ContainsIgnoreCase("bluray"))
|
if (normalizedName.ContainsIgnoreCase("bluray"))
|
||||||
{
|
{
|
||||||
|
result.SourceDetectionSource = QualityDetectionSource.Name;
|
||||||
result.Quality = Quality.Bluray720p;
|
result.Quality = Quality.Bluray720p;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.Quality = Quality.HDTV720p;
|
||||||
|
}
|
||||||
|
|
||||||
result.Quality = Quality.HDTV720p;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normalizedName.ContainsIgnoreCase("1920x1080"))
|
if (normalizedName.ContainsIgnoreCase("1920x1080"))
|
||||||
{
|
{
|
||||||
|
result.ResolutionDetectionSource = QualityDetectionSource.Name;
|
||||||
|
|
||||||
if (normalizedName.ContainsIgnoreCase("bluray"))
|
if (normalizedName.ContainsIgnoreCase("bluray"))
|
||||||
{
|
{
|
||||||
|
result.SourceDetectionSource = QualityDetectionSource.Name;
|
||||||
result.Quality = Quality.Bluray1080p;
|
result.Quality = Quality.Bluray1080p;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.Quality = Quality.HDTV1080p;
|
||||||
|
}
|
||||||
|
|
||||||
result.Quality = Quality.HDTV1080p;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normalizedName.ContainsIgnoreCase("bluray720p"))
|
if (normalizedName.ContainsIgnoreCase("bluray720p"))
|
||||||
{
|
{
|
||||||
|
result.SourceDetectionSource = QualityDetectionSource.Name;
|
||||||
|
result.ResolutionDetectionSource = QualityDetectionSource.Name;
|
||||||
result.Quality = Quality.Bluray720p;
|
result.Quality = Quality.Bluray720p;
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normalizedName.ContainsIgnoreCase("bluray1080p"))
|
if (normalizedName.ContainsIgnoreCase("bluray1080p"))
|
||||||
{
|
{
|
||||||
|
result.SourceDetectionSource = QualityDetectionSource.Name;
|
||||||
|
result.ResolutionDetectionSource = QualityDetectionSource.Name;
|
||||||
result.Quality = Quality.Bluray1080p;
|
result.Quality = Quality.Bluray1080p;
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normalizedName.ContainsIgnoreCase("bluray2160p"))
|
if (normalizedName.ContainsIgnoreCase("bluray2160p"))
|
||||||
{
|
{
|
||||||
|
result.SourceDetectionSource = QualityDetectionSource.Name;
|
||||||
|
result.ResolutionDetectionSource = QualityDetectionSource.Name;
|
||||||
result.Quality = Quality.Bluray2160p;
|
result.Quality = Quality.Bluray2160p;
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
var otherSourceMatch = OtherSourceMatch(normalizedName);
|
var otherSourceMatch = OtherSourceMatch(normalizedName);
|
||||||
|
|
||||||
if (otherSourceMatch != Quality.Unknown)
|
if (otherSourceMatch != Quality.Unknown)
|
||||||
{
|
{
|
||||||
|
result.SourceDetectionSource = QualityDetectionSource.Name;
|
||||||
result.Quality = otherSourceMatch;
|
result.Quality = otherSourceMatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
{
|
{
|
||||||
public enum QualityDetectionSource
|
public enum QualityDetectionSource
|
||||||
{
|
{
|
||||||
|
Unknown,
|
||||||
Name,
|
Name,
|
||||||
Extension,
|
Extension,
|
||||||
MediaInfo
|
MediaInfo
|
||||||
|
|
|
@ -11,7 +11,10 @@ namespace NzbDrone.Core.Qualities
|
||||||
public Revision Revision { get; set; }
|
public Revision Revision { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public QualityDetectionSource QualityDetectionSource { get; set; }
|
public QualityDetectionSource SourceDetectionSource { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public QualityDetectionSource ResolutionDetectionSource { get; set; }
|
||||||
|
|
||||||
public QualityModel()
|
public QualityModel()
|
||||||
: this(Quality.Unknown, new Revision())
|
: this(Quality.Unknown, new Revision())
|
||||||
|
|
Loading…
Reference in New Issue