Parser can parse absolute episode numbers

pull/38/merge
Cyberlane 11 years ago committed by Mark McDowall
parent af5376f052
commit d13b41313f

@ -177,6 +177,38 @@ namespace NzbDrone.Core.Test.ParserTests
result.EpisodeNumbers.Should().BeNull(); result.EpisodeNumbers.Should().BeNull();
} }
[TestCase("[SubDESU]_High_School_DxD_07_(1280x720_x264-AAC)_[6B7FD717]", "High School DxD", 7, 0, 0)]
[TestCase("[Chihiro]_Working!!_-_06_[848x480_H.264_AAC][859EEAFA]", "Working!!", 6, 0, 0)]
[TestCase("[Commie]_Senki_Zesshou_Symphogear_-_11_[65F220B4]", "Senki_Zesshou_Symphogear", 11, 0, 0)]
[TestCase("[Underwater]_Rinne_no_Lagrange_-_12_(720p)_[5C7BC4F9]", "Rinne_no_Lagrange", 12, 0, 0)]
[TestCase("[Commie]_Rinne_no_Lagrange_-_15_[E76552EA]", "Rinne_no_Lagrange", 15, 0, 0)]
[TestCase("[HorribleSubs]_Hunter_X_Hunter_-_33_[720p]", "Hunter_X_Hunter", 33, 0, 0)]
[TestCase("[HorribleSubs]_Fairy_Tail_-_145_[720p]", "Fairy_Tail", 145, 0, 0)]
[TestCase("[HorribleSubs] Tonari no Kaibutsu-kun - 13 [1080p].mkv", "Tonari no Kaibutsu-kun", 13, 0, 0)]
[TestCase("[Doremi].Yes.Pretty.Cure.5.Go.Go!.31.[1280x720].[C65D4B1F].mkv", "Yes.Pretty.Cure.5.Go.Go!", 31, 0, 0)]
[TestCase("[K-F] One Piece 214", "One Piece", 214, 0, 0)]
[TestCase("[K-F] One Piece S10E14 214", "One Piece", 214, 10, 14)]
[TestCase("[K-F] One Piece 10x14 214", "One Piece", 214, 10, 14)]
[TestCase("[K-F] One Piece 214 10x14", "One Piece", 214, 10, 14)]
[TestCase("One Piece S10E14 214", "One Piece", 214, 10, 14)]
[TestCase("One Piece 10x14 214", "One Piece", 214, 10, 14)]
[TestCase("One Piece 214 10x14", "One Piece", 214, 10, 14)]
[TestCase("214 One Piece 10x14", "One Piece", 214, 10, 14)]
[TestCase("Bleach - 031 - The Resolution to Kill [Lunar].avi", "Bleach", 31, 0, 0)]
[TestCase("Bleach - 031 - The Resolution to Kill [Lunar]", "Bleach", 31, 0, 0)]
[TestCase("[ACX]Hack Sign 01 Role Play [Kosaka] [9C57891E].mkv", "Hack Sign", 1, 0, 0)]
[TestCase("[SFW-sage] Bakuman S3 - 12 [720p][D07C91FC]", "Bakuman S3", 12, 0, 0)]
[TestCase("ducktales_e66_time_is_money_part_one_marking_time", "DuckTales", 66, 0, 0)]
public void parse_absolute_numbers(string postTitle, string title, int absoluteEpisodeNumber, int seasonNumber, int episodeNumber)
{
var result = Parser.Parser.ParseTitle(postTitle);
result.Should().NotBeNull();
result.AbsoluteEpisodeNumbers.First().Should().Be(absoluteEpisodeNumber);
result.SeasonNumber.Should().Be(seasonNumber);
result.EpisodeNumbers.FirstOrDefault().Should().Be(episodeNumber);
result.SeriesTitle.Should().Be(title.CleanSeriesTitle());
}
[TestCase("Conan {year} {month} {day} Emma Roberts HDTV XviD BFF")] [TestCase("Conan {year} {month} {day} Emma Roberts HDTV XviD BFF")]
[TestCase("The Tonight Show With Jay Leno {year} {month} {day} 1080i HDTV DD5 1 MPEG2 TrollHD")] [TestCase("The Tonight Show With Jay Leno {year} {month} {day} 1080i HDTV DD5 1 MPEG2 TrollHD")]

@ -11,6 +11,7 @@ namespace NzbDrone.Core.Parser.Model
public QualityModel Quality { get; set; } public QualityModel Quality { get; set; }
public int SeasonNumber { get; set; } public int SeasonNumber { get; set; }
public int[] EpisodeNumbers { get; set; } public int[] EpisodeNumbers { get; set; }
public int[] AbsoluteEpisodeNumbers { get; set; }
public String AirDate { get; set; } public String AirDate { get; set; }
public Language Language { get; set; } public Language Language { get; set; }

@ -16,6 +16,26 @@ namespace NzbDrone.Core.Parser
private static readonly Regex[] ReportTitleRegex = new[] private static readonly Regex[] ReportTitleRegex = new[]
{ {
//Anime - Absolute Episode Number + Title + Season+Episode
new Regex(@"^(?:(?<absoluteepisode>\d{2,3})(?:_|-|\s|\.)+)+(?<title>.+?)(?:_|-|\s|\.)+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
//Anime - [SubGroup] Title Absolute Episode Number + Season+Episode
new Regex(@"^(?:\[(?<subgroup>.+?)\](?:_|-|\s|\.))?(?<title>.+?)(?:(?:_|-|\s|\.)+(?<absoluteepisode>\d{2,3}))+(?:_|-|\s|\.)+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
//Anime - [SubGroup] Title Season+Episode + Absolute Episode Number
new Regex(@"^(?:\[(?<subgroup>.+?)\](?:_|-|\s|\.))?(?<title>.+?)(?:_|-|\s|\.)+(?:S?(?<season>(?<!\d+)\d{1,2}(?!\d+))(?:(?:\-|[ex]|\W[ex]){1,2}(?<episode>\d{2}(?!\d+)))+)(?:_|\s|\.)(?:(?<absoluteepisode>\d{2,3})(?:_|-|\s|\.|$)+)+",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
//Anime - [SubGroup] Title Absolute Episode Number
new Regex(@"^\[(?<subgroup>.+?)\](?:_|-|\s|\.)?(?<title>.+?)(?:(?:_|-|\s|\.)+(?<absoluteepisode>\d{2,}))+",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
//Anime - Title Absolute Episode Number [SubGroup]
new Regex(@"^(?<title>.+?)(?:(?:_|-|\s|\.)+(?<absoluteepisode>\d{2,3}))+(?:.+?)\[(?<subgroup>.+?)\](?:\.|$)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
//Episodes with airdate //Episodes with airdate
new Regex(@"^(?<title>.+?)?\W*(?<airyear>\d{4})\W+(?<airmonth>[0-1][0-9])\W+(?<airday>[0-3][0-9])(\W+|_|$)(?!\\)", new Regex(@"^(?<title>.+?)?\W*(?<airyear>\d{4})\W+(?<airmonth>[0-1][0-9])\W+(?<airday>[0-3][0-9])(\W+|_|$)(?!\\)",
RegexOptions.IgnoreCase | RegexOptions.Compiled), RegexOptions.IgnoreCase | RegexOptions.Compiled),
@ -226,14 +246,20 @@ namespace NzbDrone.Core.Parser
{ {
SeasonNumber = seasons.First(), SeasonNumber = seasons.First(),
EpisodeNumbers = new int[0], EpisodeNumbers = new int[0],
AbsoluteEpisodeNumbers = new int[0]
}; };
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();
var absoluteEpisodeCaptures = matchGroup.Groups["absoluteepisode"].Captures.Cast<Capture>().ToList();
//Allows use to return a list of 0 episodes (We can handle that as a full season release) //Allows use to return a list of 0 episodes (We can handle that as a full season release)
if (episodeCaptures.Any()) var eps = episodeCaptures.Any();
var epsAbs = absoluteEpisodeCaptures.Any();
if (eps || epsAbs)
{
if (eps)
{ {
var first = Convert.ToInt32(episodeCaptures.First().Value); var first = Convert.ToInt32(episodeCaptures.First().Value);
var last = Convert.ToInt32(episodeCaptures.Last().Value); var last = Convert.ToInt32(episodeCaptures.Last().Value);
@ -246,6 +272,20 @@ namespace NzbDrone.Core.Parser
var count = last - first + 1; var count = last - first + 1;
result.EpisodeNumbers = Enumerable.Range(first, count).ToArray(); result.EpisodeNumbers = Enumerable.Range(first, count).ToArray();
} }
if (epsAbs)
{
var first = Convert.ToInt32(absoluteEpisodeCaptures.First().Value);
var last = Convert.ToInt32(absoluteEpisodeCaptures.Last().Value);
if (first > last)
{
return null;
}
var count = last - first + 1;
result.AbsoluteEpisodeNumbers = Enumerable.Range(first, count).ToArray();
}
}
else else
{ {
//Check to see if this is an "Extras" or "SUBPACK" release, if it is, return NULL //Check to see if this is an "Extras" or "SUBPACK" release, if it is, return NULL
@ -256,6 +296,10 @@ namespace NzbDrone.Core.Parser
result.FullSeason = true; result.FullSeason = true;
} }
} }
if (result.AbsoluteEpisodeNumbers.Any() && !result.EpisodeNumbers.Any())
{
result.SeasonNumber = 0;
}
} }
else else

Loading…
Cancel
Save