diff --git a/NzbDrone.Core.Test/ParserTest.cs b/NzbDrone.Core.Test/ParserTest.cs index 12b2ab5c3..4fa825297 100644 --- a/NzbDrone.Core.Test/ParserTest.cs +++ b/NzbDrone.Core.Test/ParserTest.cs @@ -14,8 +14,9 @@ namespace NzbDrone.Core.Test { [Test] [Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", 3, 1)] - [Row("Two.and.a.Half.Me.103.720p.HDTV.X264-DIMENSION", 1, 3)] //This only worked because the 0 doesn't affect the results - //[Row("Two.and.a.Half.Me.113.720p.HDTV.X264-DIMENSION", 1, 13)] //This fails because the 1 matters in this case + [Row("Two.and.a.Half.Me.103.720p.HDTV.X264-DIMENSION", 1, 3)] + [Row("Two.and.a.Half.Me.113.720p.HDTV.X264-DIMENSION", 1, 13)] + [Row("Two.and.a.Half.Me.1013.720p.HDTV.X264-DIMENSION", 10, 13)] [Row("Chuck.4x05.HDTV.XviD-LOL", 4, 5)] [Row("The.Girls.Next.Door.S03E06.DVDRip.XviD-WiDE", 3, 6)] [Row("Degrassi.S10E27.WS.DSR.XviD-2HD", 10, 27)] diff --git a/NzbDrone.Core/Parser.cs b/NzbDrone.Core/Parser.cs index a200f25d6..c88550ab4 100644 --- a/NzbDrone.Core/Parser.cs +++ b/NzbDrone.Core/Parser.cs @@ -19,9 +19,14 @@ namespace NzbDrone.Core private static readonly Regex[] ReportTitleRegex = new[] { new Regex(@"(?.+?)?\W?(?<year>\d+?)?\WS?(?<season>\d+)(?:\-|\.|[a-z])(?<episode>\d+)\W(?!\\)", RegexOptions.IgnoreCase | RegexOptions.Compiled), - new Regex(@"(?<title>.+?)?\W?(?<year>\d+?)?\WS?(?<season>\d+)\w(?<episode>\d+)\W(?!\\)", RegexOptions.IgnoreCase | RegexOptions.Compiled) //Supports 103 naming + new Regex(@"(?<title>.+?)?\W?(?<year>\d+?)?\WS?(?<season>\d+)(?<episode>\d{2})\W(?!\\)", RegexOptions.IgnoreCase | RegexOptions.Compiled) //Supports 103/113 naming }; + private static readonly Regex[] SeasonReportTitleRegex = new[] + { + new Regex(@"(?<title>.+?)?\W?(?<year>\d{4}?)?\W(?:S|Season)?\W?(?<season>\d+)(?!\\)", RegexOptions.IgnoreCase | RegexOptions.Compiled), + }; + private static readonly Regex NormalizeRegex = new Regex(@"((\s|^)the(\s|$))|((\s|^)and(\s|$))|[^a-z]", RegexOptions.IgnoreCase | RegexOptions.Compiled); /// <summary> @@ -73,6 +78,49 @@ namespace NzbDrone.Core return result; } + /// <summary> + /// Parses a post title into season it contains + /// </summary> + /// <param name="title">Title of the report</param> + /// <returns>Season information contained in the post</returns> + internal static SeasonParseResult ParseSeasonInfo(string title) + { + Logger.Trace("Parsing string '{0}'", title); + + foreach (var regex in ReportTitleRegex) + { + var match = regex.Matches(title); + + if (match.Count != 0) + { + var seriesName = NormalizeTitle(match[0].Groups["title"].Value); + var year = 0; + Int32.TryParse(match[0].Groups["year"].Value, out year); + + if (year < 1900 || year > DateTime.Now.Year + 1) + { + year = 0; + } + + var seasonNumber = Convert.ToInt32(match[0].Groups["season"].Value); + + var result = new SeasonParseResult + { + SeriesTitle = seriesName, + SeasonNumber = seasonNumber, + Year = year + }; + + + + Logger.Trace("Season Parsed. {0}", result); + return result; + } + } + + return null; //Return null + } + /// <summary> /// Parses a post title to find the series that relates to it /// </summary>