|
|
@ -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
|
|
|
|