mirror of https://github.com/Sonarr/Sonarr
parent
a9a3e50179
commit
7991ed0154
|
@ -0,0 +1,61 @@
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.DecisionEngine.Specifications;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using System.Linq;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
using Moq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class MultiSeasonSpecificationFixture : CoreTest<MultiSeasonSpecification>
|
||||||
|
{
|
||||||
|
private RemoteEpisode _remoteEpisode;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
var series = Builder<Series>.CreateNew().With(s => s.Id = 1234).Build();
|
||||||
|
_remoteEpisode = new RemoteEpisode
|
||||||
|
{
|
||||||
|
ParsedEpisodeInfo = new ParsedEpisodeInfo
|
||||||
|
{
|
||||||
|
FullSeason = true,
|
||||||
|
IsMultiSeason = true
|
||||||
|
},
|
||||||
|
Episodes = Builder<Episode>.CreateListOfSize(3)
|
||||||
|
.All()
|
||||||
|
.With(s => s.SeriesId = series.Id)
|
||||||
|
.BuildList(),
|
||||||
|
Series = series,
|
||||||
|
Release = new ReleaseInfo
|
||||||
|
{
|
||||||
|
Title = "Series.Title.S01-05.720p.BluRay.X264-RlsGrp"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Mocker.GetMock<IEpisodeService>().Setup(s => s.EpisodesBetweenDates(It.IsAny<DateTime>(), It.IsAny<DateTime>(), false))
|
||||||
|
.Returns(new List<Episode>());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_true_if_is_not_a_multi_season_release()
|
||||||
|
{
|
||||||
|
_remoteEpisode.ParsedEpisodeInfo.IsMultiSeason = false;
|
||||||
|
_remoteEpisode.Episodes.Last().AirDateUtc = DateTime.UtcNow.AddDays(+2);
|
||||||
|
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_false_if_is_a_multi_season_release()
|
||||||
|
{
|
||||||
|
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -159,6 +159,7 @@
|
||||||
<Compile Include="Datastore\SqliteSchemaDumperTests\SqliteSchemaDumperFixture.cs" />
|
<Compile Include="Datastore\SqliteSchemaDumperTests\SqliteSchemaDumperFixture.cs" />
|
||||||
<Compile Include="DecisionEngineTests\AcceptableSizeSpecificationFixture.cs" />
|
<Compile Include="DecisionEngineTests\AcceptableSizeSpecificationFixture.cs" />
|
||||||
<Compile Include="DecisionEngineTests\AnimeVersionUpgradeSpecificationFixture.cs" />
|
<Compile Include="DecisionEngineTests\AnimeVersionUpgradeSpecificationFixture.cs" />
|
||||||
|
<Compile Include="DecisionEngineTests\MultiSeasonSpecificationFixture.cs" />
|
||||||
<Compile Include="DecisionEngineTests\UpgradeAllowedSpecificationFixture .cs" />
|
<Compile Include="DecisionEngineTests\UpgradeAllowedSpecificationFixture .cs" />
|
||||||
<Compile Include="DecisionEngineTests\FullSeasonSpecificationFixture.cs" />
|
<Compile Include="DecisionEngineTests\FullSeasonSpecificationFixture.cs" />
|
||||||
<Compile Include="DecisionEngineTests\MaximumSizeSpecificationFixture.cs" />
|
<Compile Include="DecisionEngineTests\MaximumSizeSpecificationFixture.cs" />
|
||||||
|
|
|
@ -76,5 +76,18 @@ namespace NzbDrone.Core.Test.ParserTests
|
||||||
result.IsPartialSeason.Should().BeTrue();
|
result.IsPartialSeason.Should().BeTrue();
|
||||||
result.SeasonPart.Should().Be(seasonPart);
|
result.SeasonPart.Should().Be(seasonPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestCase("The Wire S01-05 WS BDRip X264-REWARD-No Rars", "The Wire", 1)]
|
||||||
|
public void should_parse_multi_season_release(string postTitle, string title, int firstSeason)
|
||||||
|
{
|
||||||
|
var result = Parser.Parser.ParseTitle(postTitle);
|
||||||
|
result.SeasonNumber.Should().Be(firstSeason);
|
||||||
|
result.SeriesTitle.Should().Be(title);
|
||||||
|
result.EpisodeNumbers.Should().BeEmpty();
|
||||||
|
result.AbsoluteEpisodeNumbers.Should().BeEmpty();
|
||||||
|
result.FullSeason.Should().BeTrue();
|
||||||
|
result.IsPartialSeason.Should().BeFalse();
|
||||||
|
result.IsMultiSeason.Should().BeTrue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
using NzbDrone.Core.Parser.Model;
|
using NzbDrone.Core.Parser.Model;
|
||||||
using NzbDrone.Common.Extensions;
|
using NzbDrone.Common.Extensions;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NzbDrone.Core.Tv;
|
|
||||||
|
|
||||||
namespace NzbDrone.Core.DecisionEngine.Specifications
|
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.DecisionEngine.Specifications
|
||||||
|
{
|
||||||
|
public class MultiSeasonSpecification : IDecisionEngineSpecification
|
||||||
|
{
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public MultiSeasonSpecification(Logger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpecificationPriority Priority => SpecificationPriority.Default;
|
||||||
|
public RejectionType Type => RejectionType.Permanent;
|
||||||
|
|
||||||
|
public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria)
|
||||||
|
{
|
||||||
|
if (subject.ParsedEpisodeInfo.IsMultiSeason)
|
||||||
|
{
|
||||||
|
_logger.Debug("Multi-season release {0} rejected. Not supported", subject.Release.Title);
|
||||||
|
return Decision.Reject("Multi-season releases are not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Decision.Accept();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -145,6 +145,7 @@
|
||||||
<Compile Include="CustomFilters\CustomFilterService.cs" />
|
<Compile Include="CustomFilters\CustomFilterService.cs" />
|
||||||
<Compile Include="Datastore\Migration\127_rename_release_profiles.cs" />
|
<Compile Include="Datastore\Migration\127_rename_release_profiles.cs" />
|
||||||
<Compile Include="Datastore\Migration\126_add_custom_filters.cs" />
|
<Compile Include="Datastore\Migration\126_add_custom_filters.cs" />
|
||||||
|
<Compile Include="DecisionEngine\Specifications\MultiSeasonSpecification.cs" />
|
||||||
<Compile Include="DecisionEngine\Specifications\UpgradeAllowedSpecification.cs" />
|
<Compile Include="DecisionEngine\Specifications\UpgradeAllowedSpecification.cs" />
|
||||||
<Compile Include="Exceptions\SearchFailedException.cs" />
|
<Compile Include="Exceptions\SearchFailedException.cs" />
|
||||||
<Compile Include="Extras\Metadata\MetadataSectionType.cs" />
|
<Compile Include="Extras\Metadata\MetadataSectionType.cs" />
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace NzbDrone.Core.Parser.Model
|
||||||
public Language Language { get; set; }
|
public Language Language { get; set; }
|
||||||
public bool FullSeason { get; set; }
|
public bool FullSeason { get; set; }
|
||||||
public bool IsPartialSeason { get; set; }
|
public bool IsPartialSeason { get; set; }
|
||||||
|
public bool IsMultiSeason { get; set; }
|
||||||
public bool IsSeasonExtra { get; set; }
|
public bool IsSeasonExtra { get; set; }
|
||||||
public bool Special { get; set; }
|
public bool Special { get; set; }
|
||||||
public string ReleaseGroup { get; set; }
|
public string ReleaseGroup { get; set; }
|
||||||
|
|
|
@ -128,6 +128,10 @@ namespace NzbDrone.Core.Parser
|
||||||
new Regex(@"^(?<title>.+?)(?:(?:[-_\W](?<![()\[!]))+(?<season>(?<!\d+)(?:\d{4})(?!\d+))(?:x|\Wx){1,2}(?<episode>\d{2,3}(?!\d+))(?:(?:\-|x|\Wx|_){1,2}(?<episode>\d{2,3}(?!\d+)))*)\W?(?!\\)",
|
new Regex(@"^(?<title>.+?)(?:(?:[-_\W](?<![()\[!]))+(?<season>(?<!\d+)(?:\d{4})(?!\d+))(?:x|\Wx){1,2}(?<episode>\d{2,3}(?!\d+))(?:(?:\-|x|\Wx|_){1,2}(?<episode>\d{2,3}(?!\d+)))*)\W?(?!\\)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
|
// Multi-season pack
|
||||||
|
new Regex(@"^(?<title>.+?)[-_. ]+S(?<season>(?<!\d+)(?:\d{1,2})(?!\d+))-(?<season>(?<!\d+)(?:\d{1,2})(?!\d+))",
|
||||||
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
|
||||||
// Partial season pack
|
// Partial season pack
|
||||||
new Regex(@"^(?<title>.+?)(?:\W+S(?<season>(?<!\d+)(?:\d{1,2})(?!\d+))\W+(?:(?:Part\W?|(?<!\d+\W+)e)(?<seasonpart>\d{1,2}(?!\d+)))+)",
|
new Regex(@"^(?<title>.+?)(?:\W+S(?<season>(?<!\d+)(?:\d{1,2})(?!\d+))\W+(?:(?:Part\W?|(?<!\d+\W+)e)(?<seasonpart>\d{1,2}(?!\d+)))+)",
|
||||||
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
RegexOptions.IgnoreCase | RegexOptions.Compiled),
|
||||||
|
@ -684,9 +688,6 @@ namespace NzbDrone.Core.Parser
|
||||||
//If no season was found it should be treated as a mini series and season 1
|
//If no season was found it should be treated as a mini series and season 1
|
||||||
if (seasons.Count == 0) seasons.Add(1);
|
if (seasons.Count == 0) seasons.Add(1);
|
||||||
|
|
||||||
//If more than 1 season was parsed go to the next REGEX (A multi-season release is unlikely)
|
|
||||||
if (seasons.Distinct().Count() > 1) return null;
|
|
||||||
|
|
||||||
result = new ParsedEpisodeInfo
|
result = new ParsedEpisodeInfo
|
||||||
{
|
{
|
||||||
ReleaseTitle = releaseTitle,
|
ReleaseTitle = releaseTitle,
|
||||||
|
@ -695,6 +696,13 @@ namespace NzbDrone.Core.Parser
|
||||||
AbsoluteEpisodeNumbers = new int[0]
|
AbsoluteEpisodeNumbers = new int[0]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//If more than 1 season was parsed set IsMultiSeason to true so it can be rejected later
|
||||||
|
if (seasons.Distinct().Count() > 1)
|
||||||
|
{
|
||||||
|
result.IsMultiSeason = true;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (Match matchGroup in matchCollection)
|
foreach (Match matchGroup in matchCollection)
|
||||||
{
|
{
|
||||||
var episodeCaptures = matchGroup.Groups["episode"].Captures.Cast<Capture>().ToList();
|
var episodeCaptures = matchGroup.Groups["episode"].Captures.Cast<Capture>().ToList();
|
||||||
|
|
Loading…
Reference in New Issue