Fixed: Reject partial season packs

Fixes #2135
Mark McDowall 7 years ago
parent 58d158a5dc
commit 52ce2c0007
No known key found for this signature in database
GPG Key ID: D4CEFA9A718052E0

@ -49,27 +49,27 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
{
_remoteEpisode.ParsedEpisodeInfo.FullSeason = false;
_remoteEpisode.Episodes.Last().AirDateUtc = DateTime.UtcNow.AddDays(+2);
Mocker.Resolve<FullSeasonSpecification>().IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue();
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue();
}
[Test]
public void should_return_true_if_all_episodes_have_aired()
{
Mocker.Resolve<FullSeasonSpecification>().IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue();
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue();
}
[Test]
public void should_return_false_if_one_episode_has_not_aired()
{
_remoteEpisode.Episodes.Last().AirDateUtc = DateTime.UtcNow.AddDays(+2);
Mocker.Resolve<FullSeasonSpecification>().IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse();
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse();
}
[Test]
public void should_return_false_if_an_episode_does_not_have_an_air_date()
{
_remoteEpisode.Episodes.Last().AirDateUtc = null;
Mocker.Resolve<FullSeasonSpecification>().IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse();
Subject.IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse();
}
}
}

@ -1,4 +1,4 @@
using FluentAssertions;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Test.Framework;
@ -53,5 +53,18 @@ namespace NzbDrone.Core.Test.ParserTests
result.Should().BeNull();
}
[TestCase("The.Ranch.2016.S02.Part.1.1080p.NF.WEBRip.DD5.1.x264-NTb", "The Ranch 2016", 2, 1)]
public void should_parse_partial_season_release(string postTitle, string title, int season, int seasonPart)
{
var result = Parser.Parser.ParseTitle(postTitle);
result.SeasonNumber.Should().Be(season);
result.SeriesTitle.Should().Be(title);
result.EpisodeNumbers.Should().BeEmpty();
result.AbsoluteEpisodeNumbers.Should().BeEmpty();
result.FullSeason.Should().BeFalse();
result.IsPartialSeason.Should().BeTrue();
result.SeasonPart.Should().Be(seasonPart);
}
}
}

@ -93,9 +93,16 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
}
if (localEpisode.Episodes.Empty())
{
if (localEpisode.ParsedEpisodeInfo.IsPartialSeason)
{
decision = new ImportDecision(localEpisode, new Rejection("Partial season packs are not supported"));
}
else
{
decision = new ImportDecision(localEpisode, new Rejection("Invalid season or episode"));
}
}
else
{
decision = GetDecision(localEpisode, downloadClientItem);

@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Qualities;
@ -16,9 +16,11 @@ namespace NzbDrone.Core.Parser.Model
public string AirDate { get; set; }
public Language Language { get; set; }
public bool FullSeason { get; set; }
public bool IsPartialSeason { get; set; }
public bool Special { get; set; }
public string ReleaseGroup { get; set; }
public string ReleaseHash { get; set; }
public int SeasonPart { get; set; }
public ParsedEpisodeInfo()
{

@ -94,6 +94,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?(?!\\)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
// 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+)))+)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
//Mini-Series with year in title, treated as season 1, episodes are labelled as Part01, Part 01, Part.1
new Regex(@"^(?<title>.+?\d{4})(?:\W+(?:(?:Part\W?|e)(?<episode>\d{1,2}(?!\d+)))+)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
@ -602,9 +606,21 @@ namespace NzbDrone.Core.Parser
//Todo: Set a "Extras" flag in EpisodeParseResult if we want to download them ever
if (!matchCollection[0].Groups["extras"].Value.IsNullOrWhiteSpace()) return null;
// Partial season packs will have a seasonpart group so they can be differentiated
// from a full season/single episode release
var seasonPart = matchCollection[0].Groups["seasonpart"].Value;
if (seasonPart.IsNotNullOrWhiteSpace())
{
result.SeasonPart = Convert.ToInt32(seasonPart);
result.IsPartialSeason = true;
}
else
{
result.FullSeason = true;
}
}
}
if (result.AbsoluteEpisodeNumbers.Any() && !result.EpisodeNumbers.Any())
{

Loading…
Cancel
Save