parent
ada9b944dc
commit
bfc467dd96
@ -0,0 +1,73 @@
|
|||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Languages;
|
||||||
|
using NzbDrone.Core.MediaFiles.MovieImport.Aggregation.Aggregators;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.MediaFiles.MovieImport.Aggregation.Aggregators
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class AggregateLanguageFixture : CoreTest<AggregateLanguage>
|
||||||
|
{
|
||||||
|
private LocalMovie _localMovie;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_localMovie = Builder<LocalMovie>.CreateNew()
|
||||||
|
.With(l => l.DownloadClientMovieInfo = null)
|
||||||
|
.With(l => l.FolderMovieInfo = null)
|
||||||
|
.With(l => l.FileMovieInfo = null)
|
||||||
|
.Build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ParsedMovieInfo GetParsedMovieInfo(Language language)
|
||||||
|
{
|
||||||
|
return new ParsedMovieInfo
|
||||||
|
{
|
||||||
|
Languages = new List<Language> { language }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_file_language_when_only_file_info_is_known()
|
||||||
|
{
|
||||||
|
_localMovie.FileMovieInfo = GetParsedMovieInfo(Language.English);
|
||||||
|
|
||||||
|
Subject.Aggregate(_localMovie, false).Languages.Should().Contain(_localMovie.FileMovieInfo.Languages);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_folder_language_when_folder_info_is_known()
|
||||||
|
{
|
||||||
|
_localMovie.FolderMovieInfo = GetParsedMovieInfo(Language.English);
|
||||||
|
_localMovie.FileMovieInfo = GetParsedMovieInfo(Language.English);
|
||||||
|
|
||||||
|
Subject.Aggregate(_localMovie, false).Languages.Should().Contain(_localMovie.FolderMovieInfo.Languages);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_download_client_item_language_when_download_client_item_info_is_known()
|
||||||
|
{
|
||||||
|
_localMovie.DownloadClientMovieInfo = GetParsedMovieInfo(Language.English);
|
||||||
|
_localMovie.FolderMovieInfo = GetParsedMovieInfo(Language.English);
|
||||||
|
_localMovie.FileMovieInfo = GetParsedMovieInfo(Language.English);
|
||||||
|
|
||||||
|
Subject.Aggregate(_localMovie, false).Languages.Should().Contain(_localMovie.DownloadClientMovieInfo.Languages);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_file_language_when_file_language_is_higher_than_others()
|
||||||
|
{
|
||||||
|
_localMovie.DownloadClientMovieInfo = GetParsedMovieInfo(Language.English);
|
||||||
|
_localMovie.FolderMovieInfo = GetParsedMovieInfo(Language.English);
|
||||||
|
_localMovie.FileMovieInfo = GetParsedMovieInfo(Language.French);
|
||||||
|
|
||||||
|
Subject.Aggregate(_localMovie, false).Languages.Should().Contain(_localMovie.FileMovieInfo.Languages);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.CustomFormats;
|
||||||
|
using NzbDrone.Core.MediaFiles.MovieImport.Aggregation.Aggregators;
|
||||||
|
using NzbDrone.Core.MediaFiles.MovieImport.Aggregation.Aggregators.Augmenters.Quality;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.MediaFiles.MovieImport.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<LocalMovie>()))
|
||||||
|
.Returns(AugmentQualityResult.ResolutionOnly(Resolution.R1080P, Confidence.MediaInfo));
|
||||||
|
|
||||||
|
_fileExtensionAugmenter.Setup(s => s.AugmentQuality(It.IsAny<LocalMovie>()))
|
||||||
|
.Returns(new AugmentQualityResult(Source.TV, Confidence.Fallback, Resolution.R720P, Confidence.Fallback, new Revision()));
|
||||||
|
|
||||||
|
_nameAugmenter.Setup(s => s.AugmentQuality(It.IsAny<LocalMovie>()))
|
||||||
|
.Returns(new AugmentQualityResult(Source.TV, Confidence.Default, Resolution.R480P, 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<LocalMovie>()))
|
||||||
|
.Returns<LocalMovie>(l => null);
|
||||||
|
|
||||||
|
GivenAugmenters(_fileExtensionAugmenter, nullMock);
|
||||||
|
|
||||||
|
var result = Subject.Aggregate(new LocalMovie(), 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 LocalMovie(), 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 LocalMovie(), 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 LocalMovie(), false);
|
||||||
|
|
||||||
|
result.Quality.QualityDetectionSource.Should().Be(QualityDetectionSource.MediaInfo);
|
||||||
|
result.Quality.Quality.Should().Be(Quality.HDTV1080p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.MediaFiles.MovieImport.Aggregation.Aggregators.Augmenters.Quality;
|
||||||
|
using NzbDrone.Core.MediaFiles.MediaInfo;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.CustomFormats;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.MediaFiles.MovieImport.Aggregation.Aggregators.Augmenters.Quality
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class AugmentQualityFromMediaInfoFixture : CoreTest<AugmentQualityFromMediaInfo>
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void should_return_null_if_media_info_is_null()
|
||||||
|
{
|
||||||
|
var localMovie = Builder<LocalMovie>.CreateNew()
|
||||||
|
.With(l => l.MediaInfo = null)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
Subject.AugmentQuality(localMovie).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 localMovie = Builder<LocalMovie>.CreateNew()
|
||||||
|
.With(l => l.MediaInfo = mediaInfo)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
Subject.AugmentQuality(localMovie).Should().Be(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(4096, Resolution.R2160P)] // True 4K
|
||||||
|
[TestCase(4000, Resolution.R2160P)]
|
||||||
|
[TestCase(3840, Resolution.R2160P)] // 4K UHD
|
||||||
|
[TestCase(3200, Resolution.R2160P)]
|
||||||
|
[TestCase(2000, Resolution.R1080P)]
|
||||||
|
[TestCase(1920, Resolution.R1080P)] // Full HD
|
||||||
|
[TestCase(1800, Resolution.R1080P)]
|
||||||
|
[TestCase(1490, Resolution.R720P)]
|
||||||
|
[TestCase(1280, Resolution.R720P)] // HD
|
||||||
|
[TestCase(1200, Resolution.R720P)]
|
||||||
|
[TestCase(800, Resolution.R480P)]
|
||||||
|
[TestCase(720, Resolution.R480P)] // SDTV
|
||||||
|
[TestCase(600, Resolution.R480P)]
|
||||||
|
[TestCase(100, Resolution.R480P)]
|
||||||
|
public void should_return_closest_resolution(int mediaInfoWidth, Resolution expectedResolution)
|
||||||
|
{
|
||||||
|
var mediaInfo = Builder<MediaInfoModel>.CreateNew()
|
||||||
|
.With(m => m.Width = mediaInfoWidth)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var localMovie = Builder<LocalMovie>.CreateNew()
|
||||||
|
.With(l => l.MediaInfo = mediaInfo)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
var result = Subject.AugmentQuality(localMovie);
|
||||||
|
|
||||||
|
result.Should().NotBe(null);
|
||||||
|
result.Resolution.Should().Be(expectedResolution);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using NzbDrone.Common.Exceptions;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MediaFiles.MovieImport.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,75 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.Disk;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.MediaFiles.MovieImport.Aggregation.Aggregators;
|
||||||
|
using NzbDrone.Core.MediaFiles.MediaInfo;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MediaFiles.MovieImport.Aggregation
|
||||||
|
{
|
||||||
|
public interface IAggregationService
|
||||||
|
{
|
||||||
|
LocalMovie Augment(LocalMovie localMovie, bool otherFiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AggregationService : IAggregationService
|
||||||
|
{
|
||||||
|
private readonly IEnumerable<IAggregateLocalMovie> _augmenters;
|
||||||
|
private readonly IDiskProvider _diskProvider;
|
||||||
|
private readonly IVideoFileInfoReader _videoFileInfoReader;
|
||||||
|
private readonly IConfigService _configService;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public AggregationService(IEnumerable<IAggregateLocalMovie> augmenters,
|
||||||
|
IDiskProvider diskProvider,
|
||||||
|
IVideoFileInfoReader videoFileInfoReader,
|
||||||
|
IConfigService configService,
|
||||||
|
Logger logger)
|
||||||
|
{
|
||||||
|
_augmenters = augmenters;
|
||||||
|
_diskProvider = diskProvider;
|
||||||
|
_videoFileInfoReader = videoFileInfoReader;
|
||||||
|
_configService = configService;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalMovie Augment(LocalMovie localMovie, bool otherFiles)
|
||||||
|
{
|
||||||
|
var isMediaFile = MediaFileExtensions.Extensions.Contains(Path.GetExtension(localMovie.Path));
|
||||||
|
|
||||||
|
if (localMovie.DownloadClientMovieInfo == null &&
|
||||||
|
localMovie.FolderMovieInfo == null &&
|
||||||
|
localMovie.FileMovieInfo == null)
|
||||||
|
{
|
||||||
|
if (isMediaFile)
|
||||||
|
{
|
||||||
|
throw new AugmentingFailedException("Unable to parse movie info from path: {0}", localMovie.Path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
localMovie.Size = _diskProvider.GetFileSize(localMovie.Path);
|
||||||
|
|
||||||
|
if (isMediaFile && (!localMovie.ExistingFile || _configService.EnableMediaInfo))
|
||||||
|
{
|
||||||
|
localMovie.MediaInfo = _videoFileInfoReader.GetMediaInfo(localMovie.Path);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var augmenter in _augmenters)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
augmenter.Aggregate(localMovie, otherFiles);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.Warn(ex, ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return localMovie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Core.Languages;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MediaFiles.MovieImport.Aggregation.Aggregators
|
||||||
|
{
|
||||||
|
public class AggregateLanguage : IAggregateLocalMovie
|
||||||
|
{
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public AggregateLanguage(Logger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalMovie Aggregate(LocalMovie localMovie, bool otherFiles)
|
||||||
|
{
|
||||||
|
// 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
|
||||||
|
// between parsed languages the more preferred item will be used.
|
||||||
|
|
||||||
|
var languages = new List<Language>();
|
||||||
|
|
||||||
|
languages.AddRange(GetLanguage(localMovie.DownloadClientMovieInfo));
|
||||||
|
languages.AddRange(GetLanguage(localMovie.FolderMovieInfo));
|
||||||
|
languages.AddRange(GetLanguage(localMovie.FileMovieInfo));
|
||||||
|
|
||||||
|
var language = new List<Language> { languages.FirstOrDefault(l => l != Language.English) ?? Language.English };
|
||||||
|
|
||||||
|
_logger.Debug("Using language: {0}", language.First());
|
||||||
|
|
||||||
|
localMovie.Languages = language;
|
||||||
|
|
||||||
|
return localMovie;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Language> GetLanguage(ParsedMovieInfo parsedMovieInfo)
|
||||||
|
{
|
||||||
|
if (parsedMovieInfo == null)
|
||||||
|
{
|
||||||
|
// English is the default language when otherwise unknown
|
||||||
|
|
||||||
|
return new List<Language> { Language.English };
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsedMovieInfo.Languages;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Core.CustomFormats;
|
||||||
|
using NzbDrone.Core.MediaFiles.MovieImport.Aggregation.Aggregators.Augmenters.Quality;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MediaFiles.MovieImport.Aggregation.Aggregators
|
||||||
|
{
|
||||||
|
public class AggregateQuality : IAggregateLocalMovie
|
||||||
|
{
|
||||||
|
private readonly IEnumerable<IAugmentQuality> _augmentQualities;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public AggregateQuality(IEnumerable<IAugmentQuality> augmentQualities,
|
||||||
|
Logger logger)
|
||||||
|
{
|
||||||
|
_augmentQualities = augmentQualities;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalMovie Aggregate(LocalMovie localMovie, bool otherFiles)
|
||||||
|
{
|
||||||
|
var augmentedQualities = _augmentQualities.Select(a => a.AugmentQuality(localMovie))
|
||||||
|
.Where(a => a != null)
|
||||||
|
.OrderBy(a => a.SourceConfidence);
|
||||||
|
|
||||||
|
var source = Source.UNKNOWN;
|
||||||
|
var sourceConfidence = Confidence.Default;
|
||||||
|
var resolution = Resolution.Unknown;
|
||||||
|
var resolutionConfidence = Confidence.Default;
|
||||||
|
var revison = new Revision();
|
||||||
|
|
||||||
|
foreach (var augmentedQuality in augmentedQualities)
|
||||||
|
{
|
||||||
|
if (augmentedQuality.Source > source ||
|
||||||
|
augmentedQuality.SourceConfidence > sourceConfidence && augmentedQuality.Source != Source.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Trace("Finding quality. Source: {0}. Resolution: {1}", source, resolution);
|
||||||
|
|
||||||
|
var quality = new QualityModel(QualityFinder.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);
|
||||||
|
|
||||||
|
localMovie.Quality = quality;
|
||||||
|
|
||||||
|
return localMovie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
using NzbDrone.Common.Extensions;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MediaFiles.MovieImport.Aggregation.Aggregators
|
||||||
|
{
|
||||||
|
public class AggregateReleaseGroup : IAggregateLocalMovie
|
||||||
|
{
|
||||||
|
public LocalMovie Aggregate(LocalMovie localMovie, bool otherFiles)
|
||||||
|
{
|
||||||
|
var releaseGroup = localMovie.DownloadClientMovieInfo?.ReleaseGroup;
|
||||||
|
|
||||||
|
if (releaseGroup.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
releaseGroup = localMovie.FolderMovieInfo?.ReleaseGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (releaseGroup.IsNullOrWhiteSpace())
|
||||||
|
{
|
||||||
|
releaseGroup = localMovie.FileMovieInfo?.ReleaseGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
localMovie.ReleaseGroup = releaseGroup;
|
||||||
|
|
||||||
|
return localMovie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MediaFiles.MovieImport.Aggregation.Aggregators.Augmenters.Quality
|
||||||
|
{
|
||||||
|
public class AugmentQualityFromDownloadClientItem : IAugmentQuality
|
||||||
|
{
|
||||||
|
public AugmentQualityResult AugmentQuality(LocalMovie localMovie)
|
||||||
|
{
|
||||||
|
var quality = localMovie.DownloadClientMovieInfo?.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.MovieImport.Aggregation.Aggregators.Augmenters.Quality
|
||||||
|
{
|
||||||
|
public class AugmentQualityFromFileName : IAugmentQuality
|
||||||
|
{
|
||||||
|
public AugmentQualityResult AugmentQuality(LocalMovie localMovie)
|
||||||
|
{
|
||||||
|
var quality = localMovie.FileMovieInfo?.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.MovieImport.Aggregation.Aggregators.Augmenters.Quality
|
||||||
|
{
|
||||||
|
public class AugmentQualityFromFolder : IAugmentQuality
|
||||||
|
{
|
||||||
|
public AugmentQualityResult AugmentQuality(LocalMovie localMovie)
|
||||||
|
{
|
||||||
|
var quality = localMovie.FolderMovieInfo?.Quality;
|
||||||
|
|
||||||
|
if (quality == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new AugmentQualityResult(quality.Quality.Source,
|
||||||
|
Confidence.Tag,
|
||||||
|
quality.Quality.Resolution,
|
||||||
|
Confidence.Tag,
|
||||||
|
quality.Revision);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
using NzbDrone.Core.CustomFormats;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MediaFiles.MovieImport.Aggregation.Aggregators.Augmenters.Quality
|
||||||
|
{
|
||||||
|
public class AugmentQualityFromMediaInfo : IAugmentQuality
|
||||||
|
{
|
||||||
|
public AugmentQualityResult AugmentQuality(LocalMovie localMovie)
|
||||||
|
{
|
||||||
|
if (localMovie.MediaInfo == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var width = localMovie.MediaInfo.Width;
|
||||||
|
|
||||||
|
if (width >= 3200)
|
||||||
|
{
|
||||||
|
return AugmentQualityResult.ResolutionOnly(Resolution.R2160P, Confidence.MediaInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width >= 1800)
|
||||||
|
{
|
||||||
|
return AugmentQualityResult.ResolutionOnly(Resolution.R1080P, Confidence.MediaInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width >= 1200)
|
||||||
|
{
|
||||||
|
return AugmentQualityResult.ResolutionOnly(Resolution.R720P, Confidence.MediaInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width > 0)
|
||||||
|
{
|
||||||
|
return AugmentQualityResult.ResolutionOnly(Resolution.R480P, Confidence.MediaInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
using NzbDrone.Core.CustomFormats;
|
||||||
|
using NzbDrone.Core.Qualities;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MediaFiles.MovieImport.Aggregation.Aggregators.Augmenters.Quality
|
||||||
|
{
|
||||||
|
public class AugmentQualityResult
|
||||||
|
{
|
||||||
|
public Source Source { get; set; }
|
||||||
|
public Confidence SourceConfidence { get; set; }
|
||||||
|
public Resolution Resolution { get; set; }
|
||||||
|
public Confidence ResolutionConfidence { get; set; }
|
||||||
|
public Revision Revision { get; set; }
|
||||||
|
|
||||||
|
public AugmentQualityResult(Source source,
|
||||||
|
Confidence sourceConfidence,
|
||||||
|
Resolution resolution,
|
||||||
|
Confidence resolutionConfidence,
|
||||||
|
Revision revision)
|
||||||
|
{
|
||||||
|
Source = source;
|
||||||
|
SourceConfidence = sourceConfidence;
|
||||||
|
Resolution = resolution;
|
||||||
|
ResolutionConfidence = resolutionConfidence;
|
||||||
|
Revision = revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AugmentQualityResult SourceOnly(Source source, Confidence sourceConfidence)
|
||||||
|
{
|
||||||
|
return new AugmentQualityResult(source, sourceConfidence, 0, Confidence.Default, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AugmentQualityResult ResolutionOnly(Resolution resolution, Confidence resolutionConfidence)
|
||||||
|
{
|
||||||
|
return new AugmentQualityResult(Source.UNKNOWN, Confidence.Default, resolution, resolutionConfidence, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
namespace NzbDrone.Core.MediaFiles.MovieImport.Aggregation.Aggregators.Augmenters.Quality
|
||||||
|
{
|
||||||
|
public enum Confidence
|
||||||
|
{
|
||||||
|
Fallback,
|
||||||
|
Default,
|
||||||
|
Tag,
|
||||||
|
MediaInfo
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MediaFiles.MovieImport.Aggregation.Aggregators.Augmenters.Quality
|
||||||
|
{
|
||||||
|
public interface IAugmentQuality
|
||||||
|
{
|
||||||
|
AugmentQualityResult AugmentQuality(LocalMovie localMovie);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.MediaFiles.MovieImport.Aggregation.Aggregators
|
||||||
|
{
|
||||||
|
public interface IAggregateLocalMovie
|
||||||
|
{
|
||||||
|
LocalMovie Aggregate(LocalMovie localMovie, bool otherFiles);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.Instrumentation;
|
||||||
|
using NzbDrone.Core.CustomFormats;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Qualities
|
||||||
|
{
|
||||||
|
public static class QualityFinder
|
||||||
|
{
|
||||||
|
private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(QualityFinder));
|
||||||
|
|
||||||
|
public static Quality FindBySourceAndResolution(Source source, Resolution resolution)
|
||||||
|
{
|
||||||
|
var matchingQuality = Quality.All.SingleOrDefault(q => q.Source == source && q.Resolution == resolution);
|
||||||
|
|
||||||
|
if (matchingQuality != null)
|
||||||
|
{
|
||||||
|
return matchingQuality;
|
||||||
|
}
|
||||||
|
|
||||||
|
var matchingResolution = Quality.All.Where(q => q.Resolution == resolution)
|
||||||
|
.OrderBy(q => q.Source)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
var nearestQuality = Quality.Unknown;
|
||||||
|
|
||||||
|
foreach (var quality in matchingResolution)
|
||||||
|
{
|
||||||
|
if (quality.Source >= source)
|
||||||
|
{
|
||||||
|
nearestQuality = quality;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Warn("Unable to find exact quality for {0} and {1}. Using {2} as fallback", source, resolution, nearestQuality);
|
||||||
|
|
||||||
|
return nearestQuality;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue