Parser refactoring. Now tries to parse full path if file name didn't work.

This commit is contained in:
kay.one 2011-11-23 23:35:37 -08:00
parent 5c1f4bbf1a
commit d0d9c44124
2 changed files with 100 additions and 91 deletions

View File

@ -1,10 +1,12 @@
// ReSharper disable RedundantUsingDirective
using System;
using System.Linq;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Model;
using NzbDrone.Core.Repository.Quality;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common;
namespace NzbDrone.Core.Test
{
@ -52,10 +54,10 @@ namespace NzbDrone.Core.Test
public void ParseTitle_single(string postTitle, string title, int seasonNumber, int episodeNumber)
{
var result = Parser.ParseTitle(postTitle);
result.EpisodeNumbers.Should().HaveCount(1);
result.SeasonNumber.Should().Be(seasonNumber);
result.EpisodeNumbers[0].Should().Be(episodeNumber);
result.EpisodeNumbers.First().Should().Be(episodeNumber);
result.CleanTitle.Should().Be(Parser.NormalizeTitle(title));
result.EpisodeNumbers.Count.Should().Be(1);
}
[Test]
@ -68,12 +70,15 @@ namespace NzbDrone.Core.Test
[TestCase(@"P:\TV Shows\House\Season 6\S06E13 - 5 to 9 - 720p BluRay.mkv", 6, 13)]
[TestCase(@"S:\TV Drop\House - 10x11 - Title [SDTV]\1011 - Title.avi", 10, 11)]
[TestCase(@"S:\TV Drop\King of the Hill - 10x12 - 24 Hour Propane People [SDTV]\1012 - 24 Hour Propane People.avi", 10, 12)]
[TestCase(@"S:\TV Drop\King of the Hill - 10x12 - 24 Hour Propane People [SDTV]\Hour Propane People.avi", 10, 12)]
public void PathParse_tests(string path, int season, int episode)
{
var result = Parser.ParsePath(path);
result.EpisodeNumbers.Should().HaveCount(1);
result.SeasonNumber.Should().Be(season);
result.EpisodeNumbers[0].Should().Be(episode);
ExceptionVerification.IgnoreWarns();
}
[TestCase("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", QualityTypes.DVD)]
@ -345,6 +350,7 @@ namespace NzbDrone.Core.Test
var result = Parser.ParseTitle(postTitle);
result.Should().BeNull();
ExceptionVerification.ExcpectedWarns(1);
}
[TestCase("Lie.to.Me.S03.SUBPACK.DVDRip.XviD-REWARD")]
@ -355,6 +361,8 @@ namespace NzbDrone.Core.Test
var result = Parser.ParseTitle(postTitle);
result.Should().BeNull();
ExceptionVerification.ExcpectedWarns(1);
}
}
}

View File

@ -62,22 +62,22 @@ namespace NzbDrone.Core
RegexOptions.IgnoreCase | RegexOptions.Compiled);
/// <summary>
/// Parses a file path into list of episodes it contains
/// </summary>
/// <param name = "path">Path of the file to parse</param>
/// <returns>List of episodes contained in the file</returns>
internal static EpisodeParseResult ParsePath(string path)
{
var fileInfo = new FileInfo(path);
return ParseTitle(fileInfo.Name);
var result = ParseTitle(fileInfo.Name);
if (result == null)
{
Logger.Trace("Attempting to parse episode info using full path. {0}", fileInfo.FullName);
result = ParseTitle(fileInfo.FullName);
}
return result;
}
/// <summary>
/// Parses a post title into list of episodes it contains
/// </summary>
/// <param name = "title">Title of the report</param>
/// <returns>List of episodes contained in the post</returns>
internal static EpisodeParseResult ParseTitle(string title)
{
Logger.Trace("Parsing string '{0}'", title);
@ -85,95 +85,96 @@ namespace NzbDrone.Core
foreach (var regex in ReportTitleRegex)
{
//Use only the filename, not the entire path
var match = regex.Matches(simpleTitle);
if (match.Count != 0)
{
var seriesName = NormalizeTitle(match[0].Groups["title"].Value);
int airyear;
Int32.TryParse(match[0].Groups["airyear"].Value, out airyear);
EpisodeParseResult parsedEpisode;
if (airyear < 1)
var result = ParseMatchCollection(match);
if (result != null)
{
var seasons = new List<int>();
foreach (Capture seasonCapture in match[0].Groups["season"].Captures)
{
int s;
if (Int32.TryParse(seasonCapture.Value, out s))
seasons.Add(s);
}
//If more than 1 season was parsed go to the next REGEX (A multi-season release is unlikely)
if (seasons.Distinct().Count() != 1)
continue;
var season = seasons[0];
parsedEpisode = new EpisodeParseResult
{
CleanTitle = seriesName,
SeasonNumber = season,
EpisodeNumbers = new List<int>()
};
foreach (Match matchGroup in match)
{
var count = matchGroup.Groups["episode"].Captures.Count;
//Allows use to return a list of 0 episodes (We can handle that as a full season release)
if (count > 0)
{
var first = Convert.ToInt32(matchGroup.Groups["episode"].Captures[0].Value);
var last = Convert.ToInt32(matchGroup.Groups["episode"].Captures[count - 1].Value);
for (int i = first; i <= last; i++)
{
parsedEpisode.EpisodeNumbers.Add(i);
}
}
else
{
//Check to see if this is an "Extras" or "SUBPACK" release, if it is, return NULL
//Todo: Set a "Extras" flag in EpisodeParseResult if we want to download them ever
if (!String.IsNullOrEmpty(match[0].Groups["extras"].Value))
return null;
parsedEpisode.FullSeason = true;
}
}
result.Language = ParseLanguage(title);
result.Quality = ParseQuality(title);
return result;
}
else
{
//Try to Parse as a daily show
var airmonth = Convert.ToInt32(match[0].Groups["airmonth"].Value);
var airday = Convert.ToInt32(match[0].Groups["airday"].Value);
parsedEpisode = new EpisodeParseResult
{
CleanTitle = seriesName,
AirDate = new DateTime(airyear, airmonth, airday),
Language = ParseLanguage(simpleTitle)
};
}
parsedEpisode.Quality = ParseQuality(title);
Logger.Trace("Episode Parsed. {0}", parsedEpisode);
return parsedEpisode;
}
}
Logger.Warn("Unable to parse episode info. {0}", title);
return null;
}
private static EpisodeParseResult ParseMatchCollection(MatchCollection matchCollection)
{
var seriesName = NormalizeTitle(matchCollection[0].Groups["title"].Value);
int airyear;
Int32.TryParse(matchCollection[0].Groups["airyear"].Value, out airyear);
EpisodeParseResult parsedEpisode;
if (airyear < 1900)
{
var seasons = new List<int>();
foreach (Capture seasonCapture in matchCollection[0].Groups["season"].Captures)
{
int parsedSeason;
if (Int32.TryParse(seasonCapture.Value, out parsedSeason))
seasons.Add(parsedSeason);
}
//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;
parsedEpisode = new EpisodeParseResult
{
SeasonNumber = seasons.First(),
EpisodeNumbers = new List<int>()
};
foreach (Match matchGroup in matchCollection)
{
var episodeCaptures = matchGroup.Groups["episode"].Captures.Cast<Capture>().ToList();
//Allows use to return a list of 0 episodes (We can handle that as a full season release)
if (episodeCaptures.Any())
{
var first = Convert.ToInt32(episodeCaptures.First().Value);
var last = Convert.ToInt32(episodeCaptures.Last().Value);
parsedEpisode.EpisodeNumbers = Enumerable.Range(first, last - first + 1).ToList();
}
else
{
//Check to see if this is an "Extras" or "SUBPACK" release, if it is, return NULL
//Todo: Set a "Extras" flag in EpisodeParseResult if we want to download them ever
if (!String.IsNullOrWhiteSpace(matchCollection[0].Groups["extras"].Value))
return null;
parsedEpisode.FullSeason = true;
}
}
}
else
{
//Try to Parse as a daily show
var airmonth = Convert.ToInt32(matchCollection[0].Groups["airmonth"].Value);
var airday = Convert.ToInt32(matchCollection[0].Groups["airday"].Value);
parsedEpisode = new EpisodeParseResult
{
AirDate = new DateTime(airyear, airmonth, airday),
};
}
parsedEpisode.CleanTitle = seriesName;
Logger.Trace("Episode Parsed. {0}", parsedEpisode);
return parsedEpisode;
}
/// <summary>
/// Parses a post title to find the series that relates to it
/// </summary>
@ -294,7 +295,7 @@ namespace NzbDrone.Core
return result;
}
public static LanguageType ParseLanguage(string title)
internal static LanguageType ParseLanguage(string title)
{
var lowerTitle = title.ToLower();