New: Differentiate Proper and Repack when renaming files

Closes #7455
This commit is contained in:
Mark McDowall 2025-03-24 21:13:20 -07:00
parent b103005aa2
commit b9d46dd3ea
No known key found for this signature in database
6 changed files with 236 additions and 3 deletions

View file

@ -26,7 +26,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
_parsedEpisodeInfo = Builder<ParsedEpisodeInfo>.CreateNew()
.With(p => p.Quality = new QualityModel(Quality.SDTV,
new Revision(2, 0, false)))
new Revision(2, 0, 0, false)))
.With(p => p.ReleaseGroup = "Sonarr")
.Build();

View file

@ -0,0 +1,115 @@
using System.Collections.Generic;
using System.Linq;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.CustomFormats;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
{
[TestFixture]
public class QualityFullFixture : CoreTest<FileNameBuilder>
{
private Series _series;
private Episode _episode;
private EpisodeFile _episodeFile;
private NamingConfig _namingConfig;
[SetUp]
public void Setup()
{
_series = Builder<Series>
.CreateNew()
.Build();
_episode = Builder<Episode>.CreateNew()
.With(e => e.Title = "City Sushi")
.With(e => e.SeasonNumber = 15)
.With(e => e.EpisodeNumber = 6)
.With(e => e.AbsoluteEpisodeNumber = 100)
.Build();
_episodeFile = new EpisodeFile { Quality = new QualityModel(Quality.HDTV720p), ReleaseGroup = "SonarrTest" };
_namingConfig = NamingConfig.Default;
_namingConfig.RenameEpisodes = true;
Mocker.GetMock<INamingConfigService>()
.Setup(c => c.GetConfig()).Returns(_namingConfig);
Mocker.GetMock<IQualityDefinitionService>()
.Setup(v => v.Get(Moq.It.IsAny<Quality>()))
.Returns<Quality>(v => Quality.DefaultQualityDefinitions.First(c => c.Quality == v));
Mocker.GetMock<ICustomFormatService>()
.Setup(v => v.All())
.Returns(new List<CustomFormat>());
}
[Test]
public void should_get_quality()
{
_episodeFile.Quality.Revision = new Revision();
_namingConfig.StandardEpisodeFormat = "{Quality Full}";
Subject.BuildFileName(new List<Episode> { _episode }, _series, _episodeFile)
.Should().Be("HDTV-720p");
}
[Test]
public void should_get_quality_with_proper()
{
_episodeFile.Quality.Revision = new Revision(2);
_namingConfig.StandardEpisodeFormat = "{Quality Full}";
Subject.BuildFileName(new List<Episode> { _episode }, _series, _episodeFile)
.Should().Be("HDTV-720p Proper");
}
[Test]
public void should_get_quality_with_repack()
{
_episodeFile.Quality.Revision = new Revision(2, 0, 0, true);
_namingConfig.StandardEpisodeFormat = "{Quality Full}";
Subject.BuildFileName(new List<Episode> { _episode }, _series, _episodeFile)
.Should().Be("HDTV-720p Repack");
}
[Test]
public void should_get_quality_with_proper_and_repack()
{
_episodeFile.Quality.Revision = new Revision(3, 0, 1, true);
_namingConfig.StandardEpisodeFormat = "{Quality Full}";
Subject.BuildFileName(new List<Episode> { _episode }, _series, _episodeFile)
.Should().Be("HDTV-720p Proper Repack");
}
[Test]
public void should_get_quality_with_proper_repack_and_real()
{
_episodeFile.Quality.Revision = new Revision(3, 1, 1, true);
_namingConfig.StandardEpisodeFormat = "{Quality Full}";
Subject.BuildFileName(new List<Episode> { _episode }, _series, _episodeFile)
.Should().Be("HDTV-720p Proper Repack REAL");
}
[Test]
public void should_get_quality_with_proper_for_anime()
{
_series.SeriesType = SeriesTypes.Anime;
_episodeFile.Quality.Revision = new Revision(3, 0, 1, true);
_namingConfig.AnimeEpisodeFormat = "{Quality Full}";
Subject.BuildFileName(new List<Episode> { _episode }, _series, _episodeFile)
.Should().Be("HDTV-720p v3");
}
}
}

View file

@ -0,0 +1,105 @@
using System.Collections.Generic;
using System.Linq;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.CustomFormats;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
{
[TestFixture]
public class QualityProperFixture : CoreTest<FileNameBuilder>
{
private Series _series;
private Episode _episode;
private EpisodeFile _episodeFile;
private NamingConfig _namingConfig;
[SetUp]
public void Setup()
{
_series = Builder<Series>
.CreateNew()
.Build();
_episode = Builder<Episode>.CreateNew()
.With(e => e.Title = "City Sushi")
.With(e => e.SeasonNumber = 15)
.With(e => e.EpisodeNumber = 6)
.With(e => e.AbsoluteEpisodeNumber = 100)
.Build();
_episodeFile = new EpisodeFile { Quality = new QualityModel(Quality.HDTV720p), ReleaseGroup = "SonarrTest" };
_namingConfig = NamingConfig.Default;
_namingConfig.RenameEpisodes = true;
Mocker.GetMock<INamingConfigService>()
.Setup(c => c.GetConfig()).Returns(_namingConfig);
Mocker.GetMock<IQualityDefinitionService>()
.Setup(v => v.Get(Moq.It.IsAny<Quality>()))
.Returns<Quality>(v => Quality.DefaultQualityDefinitions.First(c => c.Quality == v));
Mocker.GetMock<ICustomFormatService>()
.Setup(v => v.All())
.Returns(new List<CustomFormat>());
}
[Test]
public void should_get_quality_proper_without_quality()
{
_episodeFile.Quality.Revision = new Revision();
_namingConfig.StandardEpisodeFormat = "{Quality Proper}";
Subject.BuildFileName(new List<Episode> { _episode }, _series, _episodeFile)
.Should().Be("");
}
[Test]
public void should_get_quality_proper()
{
_episodeFile.Quality.Revision = new Revision(2);
_namingConfig.StandardEpisodeFormat = "{Quality Proper}";
Subject.BuildFileName(new List<Episode> { _episode }, _series, _episodeFile)
.Should().Be("Proper");
}
[Test]
public void should_get_quality_repack()
{
_episodeFile.Quality.Revision = new Revision(2, 0, 0, true);
_namingConfig.StandardEpisodeFormat = "{Quality Proper}";
Subject.BuildFileName(new List<Episode> { _episode }, _series, _episodeFile)
.Should().Be("Repack");
}
[Test]
public void should_get_quality_proper_and_repack()
{
_episodeFile.Quality.Revision = new Revision(3, 0, 1, true);
_namingConfig.StandardEpisodeFormat = "{Quality Proper}";
Subject.BuildFileName(new List<Episode> { _episode }, _series, _episodeFile)
.Should().Be("Proper Repack");
}
[Test]
public void should_get_quality_proper_for_anime()
{
_series.SeriesType = SeriesTypes.Anime;
_episodeFile.Quality.Revision = new Revision(3, 0, 1, true);
_namingConfig.AnimeEpisodeFormat = "{Quality Proper}";
Subject.BuildFileName(new List<Episode> { _episode }, _series, _episodeFile)
.Should().Be("v3");
}
}
}

View file

@ -1097,7 +1097,17 @@ namespace NzbDrone.Core.Organizer
return "v" + quality.Revision.Version;
}
return "Proper";
if (!quality.Revision.IsRepack)
{
return "Proper";
}
if (quality.Revision.Repack > 0 && quality.Revision.Version - quality.Revision.Repack > 1)
{
return "Proper Repack";
}
return "Repack";
}
return string.Empty;

View file

@ -693,6 +693,7 @@ namespace NzbDrone.Core.Parser
if (RepackRegex.IsMatch(normalizedName))
{
result.Revision.Version = versionRegexResult.Success ? Convert.ToInt32(versionRegexResult.Groups["version"].Value) + 1 : 2;
result.Revision.Repack = RepackRegex.Count(normalizedName);
result.Revision.IsRepack = true;
result.RevisionDetectionSource = QualityDetectionSource.Name;
}

View file

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