Closes #448 Closes #1105pull/2463/head
parent
650d18797a
commit
81e385bebf
@ -0,0 +1,109 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Core.Tv;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||
{
|
||||
[TestFixture]
|
||||
public class AugmentEpisodesFixture : CoreTest<AggregateEpisodes>
|
||||
{
|
||||
private Series _series;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_series = Builder<Series>.CreateNew().Build();
|
||||
|
||||
var augmenters = new List<Mock<IAggregateLocalEpisode>>
|
||||
{
|
||||
new Mock<IAggregateLocalEpisode>()
|
||||
};
|
||||
|
||||
Mocker.SetConstant(augmenters.Select(c => c.Object));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_use_folder_for_full_season()
|
||||
{
|
||||
var fileEpisodeInfo = Parser.Parser.ParseTitle("Series.Title.S01E01");
|
||||
var folderEpisodeInfo = Parser.Parser.ParseTitle("Series.Title.S01");
|
||||
var localEpisode = new LocalEpisode
|
||||
{
|
||||
FileEpisodeInfo = fileEpisodeInfo,
|
||||
FolderEpisodeInfo = folderEpisodeInfo,
|
||||
Path = @"C:\Test\Unsorted TV\Series.Title.S01\Series.Title.S01E01.mkv".AsOsAgnostic(),
|
||||
Series = _series
|
||||
};
|
||||
|
||||
Subject.Aggregate(localEpisode, false);
|
||||
|
||||
Mocker.GetMock<IParsingService>()
|
||||
.Verify(v => v.GetEpisodes(fileEpisodeInfo, _series, localEpisode.SceneSource, null), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_use_folder_when_it_contains_more_than_one_valid_video_file()
|
||||
{
|
||||
var fileEpisodeInfo = Parser.Parser.ParseTitle("Series.Title.S01E01");
|
||||
var folderEpisodeInfo = Parser.Parser.ParseTitle("Series.Title.S01");
|
||||
var localEpisode = new LocalEpisode
|
||||
{
|
||||
FileEpisodeInfo = fileEpisodeInfo,
|
||||
FolderEpisodeInfo = folderEpisodeInfo,
|
||||
Path = @"C:\Test\Unsorted TV\Series.Title.S01\Series.Title.S01E01.mkv".AsOsAgnostic(),
|
||||
Series = _series
|
||||
};
|
||||
|
||||
Subject.Aggregate(localEpisode, true);
|
||||
|
||||
Mocker.GetMock<IParsingService>()
|
||||
.Verify(v => v.GetEpisodes(fileEpisodeInfo, _series, localEpisode.SceneSource, null), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_use_folder_name_if_file_name_is_scene_name()
|
||||
{
|
||||
var fileEpisodeInfo = Parser.Parser.ParseTitle("Series.Title.S01E01");
|
||||
var folderEpisodeInfo = Parser.Parser.ParseTitle("Series.Title.S01E01");
|
||||
var localEpisode = new LocalEpisode
|
||||
{
|
||||
FileEpisodeInfo = fileEpisodeInfo,
|
||||
FolderEpisodeInfo = folderEpisodeInfo,
|
||||
Path = @"C:\Test\Unsorted TV\Series.Title.S01E01\Series.Title.S01E01.720p.HDTV-Sonarr.mkv".AsOsAgnostic(),
|
||||
Series = _series
|
||||
};
|
||||
|
||||
Subject.Aggregate(localEpisode, false);
|
||||
|
||||
Mocker.GetMock<IParsingService>()
|
||||
.Verify(v => v.GetEpisodes(fileEpisodeInfo, _series, localEpisode.SceneSource, null), Times.Once());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_use_folder_when_only_one_video_file()
|
||||
{
|
||||
var fileEpisodeInfo = Parser.Parser.ParseTitle("Series.Title.S01E01");
|
||||
var folderEpisodeInfo = Parser.Parser.ParseTitle("Series.Title.S01E01");
|
||||
var localEpisode = new LocalEpisode
|
||||
{
|
||||
FileEpisodeInfo = fileEpisodeInfo,
|
||||
FolderEpisodeInfo = folderEpisodeInfo,
|
||||
Path = @"C:\Test\Unsorted TV\Series.Title.S01E01\Series.Title.S01E01.mkv".AsOsAgnostic(),
|
||||
Series = _series
|
||||
};
|
||||
|
||||
Subject.Aggregate(localEpisode, false);
|
||||
|
||||
Mocker.GetMock<IParsingService>()
|
||||
.Verify(v => v.GetEpisodes(folderEpisodeInfo, _series, localEpisode.SceneSource, null), Times.Once());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators;
|
||||
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
|
||||
{
|
||||
[TestFixture]
|
||||
public class AugmentQualityFixture : CoreTest<AggregateQuality>
|
||||
{
|
||||
private Mock<IAugmentQuality> _mediaInfoAugmenter;
|
||||
private Mock<IAugmentQuality> _fileExtensionAugmenter;
|
||||
private Mock<IAugmentQuality> _nameAugmenter;
|
||||
|
||||
private IEnumerable<IAugmentQuality> _qualityAugmenters;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_mediaInfoAugmenter = new Mock<IAugmentQuality>();
|
||||
_fileExtensionAugmenter = new Mock<IAugmentQuality>();
|
||||
_nameAugmenter = new Mock<IAugmentQuality>();
|
||||
|
||||
_mediaInfoAugmenter.Setup(s => s.AugmentQuality(It.IsAny<LocalEpisode>()))
|
||||
.Returns(AugmentQualityResult.ResolutionOnly(1080, Confidence.MediaInfo));
|
||||
|
||||
_fileExtensionAugmenter.Setup(s => s.AugmentQuality(It.IsAny<LocalEpisode>()))
|
||||
.Returns(new AugmentQualityResult(QualitySource.Television, Confidence.Fallback, 720, Confidence.Fallback, new Revision()));
|
||||
|
||||
_nameAugmenter.Setup(s => s.AugmentQuality(It.IsAny<LocalEpisode>()))
|
||||
.Returns(new AugmentQualityResult(QualitySource.Television, Confidence.Default, 480, Confidence.Default, new Revision()));
|
||||
}
|
||||
|
||||
private void GivenAugmenters(params Mock<IAugmentQuality>[] mocks)
|
||||
{
|
||||
Mocker.SetConstant<IEnumerable<IAugmentQuality>>(mocks.Select(c => c.Object));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_HDTV720_from_extension_when_other_augments_are_null()
|
||||
{
|
||||
var nullMock = new Mock<IAugmentQuality>();
|
||||
nullMock.Setup(s => s.AugmentQuality(It.IsAny<LocalEpisode>()))
|
||||
.Returns<LocalEpisode>(l => null);
|
||||
|
||||
GivenAugmenters(_fileExtensionAugmenter, nullMock);
|
||||
|
||||
var result = Subject.Aggregate(new LocalEpisode(), false);
|
||||
|
||||
result.Quality.QualityDetectionSource.Should().Be(QualityDetectionSource.Extension);
|
||||
result.Quality.Quality.Should().Be(Quality.HDTV720p);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_SDTV_when_HDTV720_came_from_extension()
|
||||
{
|
||||
GivenAugmenters(_fileExtensionAugmenter, _nameAugmenter);
|
||||
|
||||
var result = Subject.Aggregate(new LocalEpisode(), false);
|
||||
|
||||
result.Quality.QualityDetectionSource.Should().Be(QualityDetectionSource.Name);
|
||||
result.Quality.Quality.Should().Be(Quality.SDTV);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_HDTV1080p_when_HDTV720_came_from_extension_and_mediainfo_indicates_1080()
|
||||
{
|
||||
GivenAugmenters(_fileExtensionAugmenter, _mediaInfoAugmenter);
|
||||
|
||||
var result = Subject.Aggregate(new LocalEpisode(), false);
|
||||
|
||||
result.Quality.QualityDetectionSource.Should().Be(QualityDetectionSource.MediaInfo);
|
||||
result.Quality.Quality.Should().Be(Quality.HDTV1080p);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_HDTV1080p_when_SDTV_came_from_name_and_mediainfo_indicates_1080()
|
||||
{
|
||||
GivenAugmenters(_nameAugmenter, _mediaInfoAugmenter);
|
||||
|
||||
var result = Subject.Aggregate(new LocalEpisode(), false);
|
||||
|
||||
result.Quality.QualityDetectionSource.Should().Be(QualityDetectionSource.MediaInfo);
|
||||
result.Quality.Quality.Should().Be(Quality.HDTV1080p);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality;
|
||||
using NzbDrone.Core.MediaFiles.MediaInfo;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality
|
||||
{
|
||||
[TestFixture]
|
||||
public class AugmentQualityFromMediaInfoFixture : CoreTest<AugmentQualityFromMediaInfo>
|
||||
{
|
||||
[Test]
|
||||
public void should_return_null_if_media_info_is_null()
|
||||
{
|
||||
var localEpisode = Builder<LocalEpisode>.CreateNew()
|
||||
.With(l => l.MediaInfo = null)
|
||||
.Build();
|
||||
|
||||
Subject.AugmentQuality(localEpisode).Should().Be(null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_null_if_media_info_width_is_zero()
|
||||
{
|
||||
var mediaInfo = Builder<MediaInfoModel>.CreateNew()
|
||||
.With(m => m.Width = 0)
|
||||
.Build();
|
||||
|
||||
var localEpisode = Builder<LocalEpisode>.CreateNew()
|
||||
.With(l => l.MediaInfo = mediaInfo)
|
||||
.Build();
|
||||
|
||||
Subject.AugmentQuality(localEpisode).Should().Be(null);
|
||||
}
|
||||
|
||||
[TestCase(4096, 2160)] // True 4K
|
||||
[TestCase(4000, 2160)]
|
||||
[TestCase(3840, 2160)] // 4K UHD
|
||||
[TestCase(3200, 2160)]
|
||||
[TestCase(2000, 1080)]
|
||||
[TestCase(1920, 1080)] // Full HD
|
||||
[TestCase(1800, 1080)]
|
||||
[TestCase(1490, 720)]
|
||||
[TestCase(1280, 720)] // HD
|
||||
[TestCase(1200, 720)]
|
||||
[TestCase(800, 480)]
|
||||
[TestCase(720, 480)] // SDTV
|
||||
[TestCase(600, 480)]
|
||||
[TestCase(100, 480)]
|
||||
public void should_return_closest_resolution(int mediaInfoWidth, int expectedResolution)
|
||||
{
|
||||
var mediaInfo = Builder<MediaInfoModel>.CreateNew()
|
||||
.With(m => m.Width = mediaInfoWidth)
|
||||
.Build();
|
||||
|
||||
var localEpisode = Builder<LocalEpisode>.CreateNew()
|
||||
.With(l => l.MediaInfo = mediaInfo)
|
||||
.Build();
|
||||
|
||||
var result = Subject.AugmentQuality(localEpisode);
|
||||
|
||||
result.Should().NotBe(null);
|
||||
result.Resolution.Should().Be(expectedResolution);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using NzbDrone.Common.Exceptions;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation
|
||||
{
|
||||
public class AugmentingFailedException : NzbDroneException
|
||||
{
|
||||
public AugmentingFailedException(string message, params object[] args) : base(message, args)
|
||||
{
|
||||
}
|
||||
|
||||
public AugmentingFailedException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public AugmentingFailedException(string message, Exception innerException, params object[] args) : base(message, innerException, args)
|
||||
{
|
||||
}
|
||||
|
||||
public AugmentingFailedException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators;
|
||||
using NzbDrone.Core.MediaFiles.MediaInfo;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation
|
||||
{
|
||||
public interface IAugmentingService
|
||||
{
|
||||
LocalEpisode Augment(LocalEpisode localEpisode, bool otherFiles);
|
||||
}
|
||||
|
||||
public class AugmentingService : IAugmentingService
|
||||
{
|
||||
private readonly IEnumerable<IAggregateLocalEpisode> _augmenters;
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly IVideoFileInfoReader _videoFileInfoReader;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public AugmentingService(IEnumerable<IAggregateLocalEpisode> augmenters,
|
||||
IDiskProvider diskProvider,
|
||||
IVideoFileInfoReader videoFileInfoReader,
|
||||
Logger logger)
|
||||
{
|
||||
_augmenters = augmenters;
|
||||
_diskProvider = diskProvider;
|
||||
_videoFileInfoReader = videoFileInfoReader;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public LocalEpisode Augment(LocalEpisode localEpisode, bool otherFiles)
|
||||
{
|
||||
if (localEpisode.DownloadClientEpisodeInfo == null &&
|
||||
localEpisode.FolderEpisodeInfo == null &&
|
||||
localEpisode.FileEpisodeInfo == null)
|
||||
{
|
||||
if (MediaFileExtensions.Extensions.Contains(Path.GetExtension(localEpisode.Path)))
|
||||
{
|
||||
throw new AugmentingFailedException("Unable to parse episode info from path: {0}", localEpisode.Path);
|
||||
}
|
||||
}
|
||||
|
||||
localEpisode.Size = _diskProvider.GetFileSize(localEpisode.Path);
|
||||
localEpisode.MediaInfo = _videoFileInfoReader.GetMediaInfo(localEpisode.Path);
|
||||
|
||||
foreach (var augmenter in _augmenters)
|
||||
{
|
||||
try
|
||||
{
|
||||
augmenter.Aggregate(localEpisode, otherFiles);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Warn(ex, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
return localEpisode;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
using System.IO;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||
{
|
||||
public class AggregateEpisodes : IAggregateLocalEpisode
|
||||
{
|
||||
private readonly IParsingService _parsingService;
|
||||
|
||||
public AggregateEpisodes(IParsingService parsingService)
|
||||
{
|
||||
_parsingService = parsingService;
|
||||
}
|
||||
|
||||
public LocalEpisode Aggregate(LocalEpisode localEpisode, bool otherFiles)
|
||||
{
|
||||
var bestEpisodeInfoForEpisodes = GetBestEpisodeInfo(localEpisode, otherFiles);
|
||||
|
||||
localEpisode.Episodes = _parsingService.GetEpisodes(bestEpisodeInfoForEpisodes, localEpisode.Series, localEpisode.SceneSource);
|
||||
|
||||
return localEpisode;
|
||||
}
|
||||
|
||||
private ParsedEpisodeInfo GetBestEpisodeInfo(LocalEpisode localEpisode, bool otherFiles)
|
||||
{
|
||||
var parsedEpisodeInfo = localEpisode.FileEpisodeInfo;
|
||||
var downloadClientEpisodeInfo = localEpisode.DownloadClientEpisodeInfo;
|
||||
var folderEpisodeInfo = localEpisode.FolderEpisodeInfo;
|
||||
|
||||
if (!otherFiles && !SceneChecker.IsSceneTitle(Path.GetFileNameWithoutExtension(localEpisode.Path)))
|
||||
{
|
||||
if (downloadClientEpisodeInfo != null && !downloadClientEpisodeInfo.FullSeason)
|
||||
{
|
||||
parsedEpisodeInfo = localEpisode.DownloadClientEpisodeInfo;
|
||||
}
|
||||
else if (folderEpisodeInfo != null && !folderEpisodeInfo.FullSeason)
|
||||
{
|
||||
parsedEpisodeInfo = localEpisode.FolderEpisodeInfo;
|
||||
}
|
||||
}
|
||||
|
||||
if (parsedEpisodeInfo == null || parsedEpisodeInfo.IsPossibleSpecialEpisode)
|
||||
{
|
||||
var title = Path.GetFileNameWithoutExtension(localEpisode.Path);
|
||||
var specialEpisodeInfo = _parsingService.ParseSpecialEpisodeTitle(parsedEpisodeInfo, title, localEpisode.Series);
|
||||
|
||||
return specialEpisodeInfo;
|
||||
}
|
||||
|
||||
return parsedEpisodeInfo;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Qualities;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||
{
|
||||
public class AggregateQuality : IAggregateLocalEpisode
|
||||
{
|
||||
private readonly IEnumerable<IAugmentQuality> _augmentQualities;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public AggregateQuality(IEnumerable<IAugmentQuality> augmentQualities,
|
||||
Logger logger)
|
||||
{
|
||||
_augmentQualities = augmentQualities;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public LocalEpisode Aggregate(LocalEpisode localEpisode, bool otherFiles)
|
||||
{
|
||||
var augmentedQualities = _augmentQualities.Select(a => a.AugmentQuality(localEpisode))
|
||||
.Where(a => a != null)
|
||||
.OrderBy(a => a.SourceConfidence);
|
||||
|
||||
var source = QualitySource.Unknown;
|
||||
var sourceConfidence = Confidence.Default;
|
||||
var resolution = 0;
|
||||
var resolutionConfidence = Confidence.Default;
|
||||
var revison = new Revision();
|
||||
|
||||
foreach (var augmentedQuality in augmentedQualities)
|
||||
{
|
||||
if (augmentedQuality.Source > source ||
|
||||
augmentedQuality.SourceConfidence > sourceConfidence && augmentedQuality.Source != QualitySource.Unknown)
|
||||
{
|
||||
source = augmentedQuality.Source;
|
||||
sourceConfidence = augmentedQuality.SourceConfidence;
|
||||
}
|
||||
|
||||
if (augmentedQuality.Resolution > resolution ||
|
||||
augmentedQuality.ResolutionConfidence > resolutionConfidence && augmentedQuality.Resolution > 0)
|
||||
{
|
||||
resolution = augmentedQuality.Resolution;
|
||||
resolutionConfidence = augmentedQuality.ResolutionConfidence;
|
||||
}
|
||||
|
||||
if (augmentedQuality.Revision != null && augmentedQuality.Revision > revison)
|
||||
{
|
||||
revison = augmentedQuality.Revision;
|
||||
}
|
||||
}
|
||||
|
||||
var quality = new QualityModel(Quality.FindBySourceAndResolution(source, resolution), revison);
|
||||
|
||||
if (resolutionConfidence == Confidence.MediaInfo)
|
||||
{
|
||||
quality.QualityDetectionSource = QualityDetectionSource.MediaInfo;
|
||||
}
|
||||
else if (sourceConfidence == Confidence.Fallback || resolutionConfidence == Confidence.Fallback)
|
||||
{
|
||||
quality.QualityDetectionSource = QualityDetectionSource.Extension;
|
||||
}
|
||||
else
|
||||
{
|
||||
quality.QualityDetectionSource = QualityDetectionSource.Name;
|
||||
}
|
||||
|
||||
_logger.Debug("Using quality: {0}", quality);
|
||||
|
||||
localEpisode.Quality = quality;
|
||||
|
||||
return localEpisode;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||
{
|
||||
public class AggregateReleaseGroup : IAggregateLocalEpisode
|
||||
{
|
||||
public LocalEpisode Aggregate(LocalEpisode localEpisode, bool otherFiles)
|
||||
{
|
||||
var releaseGroup = localEpisode.DownloadClientEpisodeInfo?.ReleaseGroup;
|
||||
|
||||
if (releaseGroup.IsNullOrWhiteSpace())
|
||||
{
|
||||
releaseGroup = localEpisode.FolderEpisodeInfo?.ReleaseGroup;
|
||||
}
|
||||
|
||||
if (releaseGroup.IsNullOrWhiteSpace())
|
||||
{
|
||||
releaseGroup = localEpisode.FileEpisodeInfo?.ReleaseGroup;
|
||||
}
|
||||
|
||||
localEpisode.ReleaseGroup = releaseGroup;
|
||||
|
||||
return localEpisode;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality
|
||||
{
|
||||
public class AugmentQualityFromDownloadClientItem : IAugmentQuality
|
||||
{
|
||||
public AugmentQualityResult AugmentQuality(LocalEpisode localEpisode)
|
||||
{
|
||||
var quality = localEpisode.DownloadClientEpisodeInfo?.Quality;
|
||||
|
||||
if (quality == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new AugmentQualityResult(quality.Quality.Source,
|
||||
Confidence.Tag,
|
||||
quality.Quality.Resolution,
|
||||
Confidence.Tag,
|
||||
quality.Revision);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Qualities;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality
|
||||
{
|
||||
public class AugmentQualityFromFileName : IAugmentQuality
|
||||
{
|
||||
public AugmentQualityResult AugmentQuality(LocalEpisode localEpisode)
|
||||
{
|
||||
var quality = localEpisode.FileEpisodeInfo?.Quality;
|
||||
|
||||
if (quality == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var confidence = quality.QualityDetectionSource == QualityDetectionSource.Extension
|
||||
? Confidence.Fallback
|
||||
: Confidence.Tag;
|
||||
|
||||
return new AugmentQualityResult(quality.Quality.Source,
|
||||
confidence,
|
||||
quality.Quality.Resolution,
|
||||
confidence,
|
||||
quality.Revision);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality
|
||||
{
|
||||
public class AugmentQualityFromFolder : IAugmentQuality
|
||||
{
|
||||
public AugmentQualityResult AugmentQuality(LocalEpisode localEpisode)
|
||||
{
|
||||
var quality = localEpisode.FolderEpisodeInfo?.Quality;
|
||||
|
||||
if (quality == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new AugmentQualityResult(quality.Quality.Source,
|
||||
Confidence.Tag,
|
||||
quality.Quality.Resolution,
|
||||
Confidence.Tag,
|
||||
quality.Revision);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality
|
||||
{
|
||||
public class AugmentQualityFromMediaInfo : IAugmentQuality
|
||||
{
|
||||
public AugmentQualityResult AugmentQuality(LocalEpisode localEpisode)
|
||||
{
|
||||
if (localEpisode.MediaInfo == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var width = localEpisode.MediaInfo.Width;
|
||||
|
||||
if (width >= 3200)
|
||||
{
|
||||
return AugmentQualityResult.ResolutionOnly(2160, Confidence.MediaInfo);
|
||||
}
|
||||
|
||||
if (width >= 1800)
|
||||
{
|
||||
return AugmentQualityResult.ResolutionOnly(1080, Confidence.MediaInfo);
|
||||
}
|
||||
|
||||
if (width >= 1200)
|
||||
{
|
||||
return AugmentQualityResult.ResolutionOnly(720, Confidence.MediaInfo);
|
||||
}
|
||||
|
||||
if (width > 0)
|
||||
{
|
||||
return AugmentQualityResult.ResolutionOnly(480, Confidence.MediaInfo);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
using NzbDrone.Core.Qualities;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality
|
||||
{
|
||||
public class AugmentQualityResult
|
||||
{
|
||||
public QualitySource Source { get; set; }
|
||||
public Confidence SourceConfidence { get; set; }
|
||||
public int Resolution { get; set; }
|
||||
public Confidence ResolutionConfidence { get; set; }
|
||||
public Revision Revision { get; set; }
|
||||
|
||||
public AugmentQualityResult(QualitySource source,
|
||||
Confidence sourceConfidence,
|
||||
int resolution,
|
||||
Confidence resolutionConfidence,
|
||||
Revision revision)
|
||||
{
|
||||
Source = source;
|
||||
SourceConfidence = sourceConfidence;
|
||||
Resolution = resolution;
|
||||
ResolutionConfidence = resolutionConfidence;
|
||||
Revision = revision;
|
||||
}
|
||||
|
||||
public static AugmentQualityResult SourceOnly(QualitySource source, Confidence sourceConfidence)
|
||||
{
|
||||
return new AugmentQualityResult(source, sourceConfidence, 0, Confidence.Default, null);
|
||||
}
|
||||
|
||||
public static AugmentQualityResult ResolutionOnly(int resolution, Confidence resolutionConfidence)
|
||||
{
|
||||
return new AugmentQualityResult(QualitySource.Unknown, Confidence.Default, resolution, resolutionConfidence, null);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality
|
||||
{
|
||||
public enum Confidence
|
||||
{
|
||||
Fallback,
|
||||
Default,
|
||||
Tag,
|
||||
MediaInfo
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators.Augmenters.Quality
|
||||
{
|
||||
public interface IAugmentQuality
|
||||
{
|
||||
AugmentQualityResult AugmentQuality(LocalEpisode localEpisode);
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.MediaFiles.EpisodeImport.Aggregation.Aggregators
|
||||
{
|
||||
public interface IAggregateLocalEpisode
|
||||
{
|
||||
LocalEpisode Aggregate(LocalEpisode localEpisode, bool otherFiles);
|
||||
}
|
||||
}
|
Loading…
Reference in new issue