mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-12-12 11:15:43 +02:00
Parser refactoring. Now tries to parse full path if file name didn't work.
This commit is contained in:
parent
5c1f4bbf1a
commit
d0d9c44124
@ -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 @@ public class ParserTest : CoreTest
|
||||
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 @@ public void ParseTitle_single(string postTitle, string title, int seasonNumber,
|
||||
[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 @@ public void parse_season_extras(string postTitle)
|
||||
var result = Parser.ParseTitle(postTitle);
|
||||
|
||||
result.Should().BeNull();
|
||||
ExceptionVerification.ExcpectedWarns(1);
|
||||
}
|
||||
|
||||
[TestCase("Lie.to.Me.S03.SUBPACK.DVDRip.XviD-REWARD")]
|
||||
@ -355,6 +361,8 @@ public void parse_season_subpack(string postTitle)
|
||||
var result = Parser.ParseTitle(postTitle);
|
||||
|
||||
result.Should().BeNull();
|
||||
|
||||
ExceptionVerification.ExcpectedWarns(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,22 +62,22 @@ public static class Parser
|
||||
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 @@ internal static EpisodeParseResult ParseTitle(string title)
|
||||
|
||||
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 @@ internal static Quality ParseQuality(string name)
|
||||
return result;
|
||||
}
|
||||
|
||||
public static LanguageType ParseLanguage(string title)
|
||||
internal static LanguageType ParseLanguage(string title)
|
||||
{
|
||||
var lowerTitle = title.ToLower();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user