Fixed: Correctly handle Repacks, restrict to same group

pull/2/head
Qstick 6 years ago
parent 7698ae00dd
commit 3bf5476922

@ -0,0 +1,174 @@
using System.Collections.Generic;
using System.Linq;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Movies;
namespace NzbDrone.Core.Test.DecisionEngineTests
{
[TestFixture]
public class RepackSpecificationFixture : CoreTest<RepackSpecification>
{
private ParsedMovieInfo _parsedMovieInfo;
private Movie _movie;
[SetUp]
public void Setup()
{
Mocker.Resolve<UpgradableSpecification>();
_parsedMovieInfo = Builder<ParsedMovieInfo>.CreateNew()
.With(p => p.Quality = new QualityModel(Quality.SDTV,
new Revision(2, 0, false)))
.With(p => p.ReleaseGroup = "Radarr")
.Build();
_movie = Builder<Movie>.CreateNew()
.With(e => e.MovieFileId = 0)
.Build();
}
[Test]
public void should_return_true_if_it_is_not_a_repack()
{
var remoteMovie = Builder<RemoteMovie>.CreateNew()
.With(e => e.ParsedMovieInfo = _parsedMovieInfo)
.With(e => e.Movie = _movie)
.Build();
Subject.IsSatisfiedBy(remoteMovie, null)
.Accepted
.Should()
.BeTrue();
}
[Test]
public void should_return_true_if_there_are_is_no_movie_file()
{
_parsedMovieInfo.Quality.Revision.IsRepack = true;
var remoteMovie = Builder<RemoteMovie>.CreateNew()
.With(e => e.ParsedMovieInfo = _parsedMovieInfo)
.With(e => e.Movie = _movie)
.Build();
Subject.IsSatisfiedBy(remoteMovie, null)
.Accepted
.Should()
.BeTrue();
}
[Test]
public void should_return_true_if_is_a_repack_for_a_different_quality()
{
_parsedMovieInfo.Quality.Revision.IsRepack = true;
_movie.MovieFileId = 1;
_movie.MovieFile = Builder<MovieFile>.CreateNew()
.With(e => e.Quality = new QualityModel(Quality.DVD))
.With(e => e.ReleaseGroup = "Radarr")
.Build();
var remoteMovie = Builder<RemoteMovie>.CreateNew()
.With(e => e.ParsedMovieInfo = _parsedMovieInfo)
.With(e => e.Movie = _movie)
.Build();
Subject.IsSatisfiedBy(remoteMovie, null)
.Accepted
.Should()
.BeTrue();
}
[Test]
public void should_return_true_if_is_a_repack_for_existing_file()
{
_parsedMovieInfo.Quality.Revision.IsRepack = true;
_movie.MovieFileId = 1;
_movie.MovieFile = Builder<MovieFile>.CreateNew()
.With(e => e.Quality = new QualityModel(Quality.SDTV))
.With(e => e.ReleaseGroup = "Radarr")
.Build();
var remoteMovie = Builder<RemoteMovie>.CreateNew()
.With(e => e.ParsedMovieInfo = _parsedMovieInfo)
.With(e => e.Movie = _movie)
.Build();
Subject.IsSatisfiedBy(remoteMovie, null)
.Accepted
.Should()
.BeTrue();
}
[Test]
public void should_return_false_if_is_a_repack_for_a_different_file()
{
_parsedMovieInfo.Quality.Revision.IsRepack = true;
_movie.MovieFileId = 1;
_movie.MovieFile = Builder<MovieFile>.CreateNew()
.With(e => e.Quality = new QualityModel(Quality.SDTV))
.With(e => e.ReleaseGroup = "NotRadarr")
.Build();
var remoteMovie = Builder<RemoteMovie>.CreateNew()
.With(e => e.ParsedMovieInfo = _parsedMovieInfo)
.With(e => e.Movie = _movie)
.Build();
Subject.IsSatisfiedBy(remoteMovie, null)
.Accepted
.Should()
.BeFalse();
}
[Test]
public void should_return_false_if_release_group_for_existing_file_is_unknown()
{
_parsedMovieInfo.Quality.Revision.IsRepack = true;
_movie.MovieFileId = 1;
_movie.MovieFile = Builder<MovieFile>.CreateNew()
.With(e => e.Quality = new QualityModel(Quality.SDTV))
.With(e => e.ReleaseGroup = "")
.Build();
var remoteMovie = Builder<RemoteMovie>.CreateNew()
.With(e => e.ParsedMovieInfo = _parsedMovieInfo)
.With(e => e.Movie = _movie)
.Build();
Subject.IsSatisfiedBy(remoteMovie, null)
.Accepted
.Should()
.BeFalse();
}
[Test]
public void should_return_false_if_release_group_for_release_is_unknown()
{
_parsedMovieInfo.Quality.Revision.IsRepack = true;
_parsedMovieInfo.ReleaseGroup = null;
_movie.MovieFileId = 1;
_movie.MovieFile = Builder<MovieFile>.CreateNew()
.With(e => e.Quality = new QualityModel(Quality.SDTV))
.With(e => e.ReleaseGroup = "Radarr")
.Build();
var remoteMovie = Builder<RemoteMovie>.CreateNew()
.With(e => e.ParsedMovieInfo = _parsedMovieInfo)
.With(e => e.Movie = _movie)
.Build();
Subject.IsSatisfiedBy(remoteMovie, null)
.Accepted
.Should()
.BeFalse();
}
}
}

@ -168,6 +168,7 @@
<Compile Include="DecisionEngineTests\QualityAllowedByProfileSpecificationFixture.cs" /> <Compile Include="DecisionEngineTests\QualityAllowedByProfileSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\QualityUpgradeSpecificationFixture.cs" /> <Compile Include="DecisionEngineTests\QualityUpgradeSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\MinimumAgeSpecificationFixture.cs" /> <Compile Include="DecisionEngineTests\MinimumAgeSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\RepackSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\RetentionSpecificationFixture.cs" /> <Compile Include="DecisionEngineTests\RetentionSpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\RssSync\DelaySpecificationFixture.cs" /> <Compile Include="DecisionEngineTests\RssSync\DelaySpecificationFixture.cs" />
<Compile Include="DecisionEngineTests\RssSync\ProperSpecificationFixture.cs" /> <Compile Include="DecisionEngineTests\RssSync\ProperSpecificationFixture.cs" />

@ -349,6 +349,17 @@ namespace NzbDrone.Core.Test.ParserTests
QualityParser.ParseQuality(postTitle).HardcodedSubs.Should().Be(sub); QualityParser.ParseQuality(postTitle).HardcodedSubs.Should().Be(sub);
} }
[TestCase("Movie Title 2018 REPACK 720p x264 aAF", true)]
[TestCase("Movie.Title.2018.REPACK.720p.x264-aAF", true)]
[TestCase("Movie.Title.2018.PROPER.720p.x264-aAF", false)]
[TestCase("Movie.Title.2018.RERIP.720p.BluRay.x264-DEMAND", true)]
public void should_be_able_to_parse_repack(string title, bool isRepack)
{
var result = QualityParser.ParseQuality(title);
result.Revision.Version.Should().Be(2);
result.Revision.IsRepack.Should().Be(isRepack);
}
private void ParseAndVerifyQuality(string title, Source source, bool proper, Resolution resolution, Modifier modifier = Modifier.NONE) private void ParseAndVerifyQuality(string title, Source source, bool proper, Resolution resolution, Modifier modifier = Modifier.NONE)
{ {
var result = QualityParser.ParseQuality(title); var result = QualityParser.ParseQuality(title);

@ -0,0 +1,65 @@
using System;
using System.Linq;
using NLog;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.DecisionEngine.Specifications
{
public class RepackSpecification : IDecisionEngineSpecification
{
private readonly UpgradableSpecification _upgradableSpecification;
private readonly Logger _logger;
public RepackSpecification(UpgradableSpecification upgradableSpecification, Logger logger)
{
_upgradableSpecification = upgradableSpecification;
_logger = logger;
}
public SpecificationPriority Priority => SpecificationPriority.Database;
public RejectionType Type => RejectionType.Permanent;
public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria)
{
if (!subject.ParsedMovieInfo.Quality.Revision.IsRepack)
{
return Decision.Accept();
}
if (subject.Movie.MovieFileId != 0)
{
var file = subject.Movie.MovieFile;
if (_upgradableSpecification.IsRevisionUpgrade(file.Quality, subject.ParsedMovieInfo.Quality))
{
var releaseGroup = subject.ParsedMovieInfo.ReleaseGroup;
var fileReleaseGroup = file.ReleaseGroup;
if (fileReleaseGroup.IsNullOrWhiteSpace())
{
return Decision.Reject("Unable to determine release group for the existing file");
}
if (releaseGroup.IsNullOrWhiteSpace())
{
return Decision.Reject("Unable to determine release group for this release");
}
if (!fileReleaseGroup.Equals(releaseGroup, StringComparison.InvariantCultureIgnoreCase))
{
_logger.Debug(
"Release is a repack for a different release group. Release Group: {0}. File release group: {0}",
releaseGroup, fileReleaseGroup);
return Decision.Reject(
"Release is a repack for a different release group. Release Group: {0}. File release group: {0}",
releaseGroup, fileReleaseGroup);
}
}
}
return Decision.Accept();
}
}
}

@ -1,4 +1,3 @@
using System.Linq;
using NLog; using NLog;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.Profiles; using NzbDrone.Core.Profiles;
@ -74,6 +73,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
if (currentQuality.Quality == newQuality.Quality && compare > 0) if (currentQuality.Quality == newQuality.Quality && compare > 0)
{ {
_logger.Debug("New quality is a better revision for existing quality");
return true; return true;
} }

@ -164,6 +164,7 @@
<Compile Include="DecisionEngine\Specifications\CustomFormatAllowedByProfileSpecification.cs" /> <Compile Include="DecisionEngine\Specifications\CustomFormatAllowedByProfileSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\IDecisionEngineSpecification.cs" /> <Compile Include="DecisionEngine\Specifications\IDecisionEngineSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\MaximumSizeSpecification.cs" /> <Compile Include="DecisionEngine\Specifications\MaximumSizeSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\RepackSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\RequiredIndexerFlagsSpecification.cs" /> <Compile Include="DecisionEngine\Specifications\RequiredIndexerFlagsSpecification.cs" />
<Compile Include="DecisionEngine\Specifications\UpgradeAllowedSpecification.cs" /> <Compile Include="DecisionEngine\Specifications\UpgradeAllowedSpecification.cs" />
<Compile Include="Download\Clients\DownloadClientUnavailableException.cs" /> <Compile Include="Download\Clients\DownloadClientUnavailableException.cs" />

@ -15,20 +15,6 @@ namespace NzbDrone.Core.Parser
{ {
private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(QualityParser)); private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(QualityParser));
//private static readonly Regex SourceRegex = new Regex(@"\b(?:
// (?<bluray>BluRay|Blu-Ray|HDDVD|BD)|
// (?<webdl>WEB[-_. ]DL|WEBDL|WebRip|iTunesHD|WebHD|[. ]WEB[. ](?:[xh]26[45]|DD5[. ]1)|\d+0p[. ]WEB[. ])|
// (?<hdtv>HDTV)|
// (?<bdrip>BDRip)|
// (?<brrip>BRRip)|
// (?<dvd>DVD|DVDRip|NTSC|PAL|xvidvd)|
// (?<dsr>WS[-_. ]DSR|DSR)|
// (?<pdtv>PDTV)|
// (?<sdtv>SDTV)|
// (?<tvrip>TVRip)
// )\b",
// RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
private static readonly Regex SourceRegex = new Regex(@"\b(?: private static readonly Regex SourceRegex = new Regex(@"\b(?:
(?<bluray>M?BluRay|Blu-Ray|HDDVD|BD|BDISO|BD25|BD50|BR.?DISK)| (?<bluray>M?BluRay|Blu-Ray|HDDVD|BD|BDISO|BD25|BD50|BR.?DISK)|
(?<webdl>WEB[-_. ]DL|HDRIP|WEBDL|WebRip|Web-Rip|iTunesHD|WebHD|[. ]WEB[. ](?:[xh]26[45]|DDP?5[. ]1)|\d+0p[-. ]WEB[-. ]|WEB-DLMux|\b\s\/\sWEB\s\/\s\b)| (?<webdl>WEB[-_. ]DL|HDRIP|WEBDL|WebRip|Web-Rip|iTunesHD|WebHD|[. ]WEB[. ](?:[xh]26[45]|DDP?5[. ]1)|\d+0p[-. ]WEB[-. ]|WEB-DLMux|\b\s\/\sWEB\s\/\s\b)|
@ -57,7 +43,10 @@ namespace NzbDrone.Core.Parser
private static readonly Regex BRDISKRegex = new Regex(@"\b(COMPLETE|ISO|BDISO|BD25|BD50|BR.?DISK)\b", private static readonly Regex BRDISKRegex = new Regex(@"\b(COMPLETE|ISO|BDISO|BD25|BD50|BR.?DISK)\b",
RegexOptions.Compiled | RegexOptions.IgnoreCase); RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex ProperRegex = new Regex(@"\b(?<proper>proper|repack|rerip)\b", private static readonly Regex ProperRegex = new Regex(@"\b(?<proper>proper)\b",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex RepackRegex = new Regex(@"\b(?<repack>repack|rerip)\b",
RegexOptions.Compiled | RegexOptions.IgnoreCase); RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex VersionRegex = new Regex(@"\dv(?<version>\d)\b|\[v(?<version>\d)\]", private static readonly Regex VersionRegex = new Regex(@"\dv(?<version>\d)\b|\[v(?<version>\d)\]",
@ -406,6 +395,12 @@ namespace NzbDrone.Core.Parser
result.Revision.Version = 2; result.Revision.Version = 2;
} }
if (RepackRegex.IsMatch(normalizedName))
{
result.Revision.Version = 2;
result.Revision.IsRepack = true;
}
var versionRegexResult = VersionRegex.Match(normalizedName); var versionRegexResult = VersionRegex.Match(normalizedName);
if (versionRegexResult.Success) if (versionRegexResult.Success)

@ -9,14 +9,16 @@ namespace NzbDrone.Core.Qualities
{ {
} }
public Revision(int version = 1, int real = 0) public Revision(int version = 1, int real = 0, bool isRepack = false)
{ {
Version = version; Version = version;
Real = real; Real = real;
IsRepack = isRepack;
} }
public int Version { get; set; } public int Version { get; set; }
public int Real { get; set; } public int Real { get; set; }
public bool IsRepack { get; set; }
public bool Equals(Revision other) public bool Equals(Revision other)
{ {

Loading…
Cancel
Save