Fixed: Specials with the season number will be handled properly

This commit is contained in:
Mark McDowall 2014-07-09 00:13:01 -07:00
parent 5e68ed7aac
commit 9a92815cbf
9 changed files with 69 additions and 44 deletions

View File

@ -14,7 +14,7 @@ using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
{
[TestFixture]
public class DownloadApprovedReportsFixture : CoreTest<DownloadApprovedReports>
public class GetQualifiedReportsFixture : CoreTest<DownloadApprovedReports>
{
private Episode GetEpisode(int id)
{

View File

@ -21,7 +21,7 @@ namespace NzbDrone.Core.Test.ParserTests
SeriesTitle = ""
};
parsedEpisodeInfo.IsPossibleSpecialEpisode().Should().BeFalse();
parsedEpisodeInfo.IsPossibleSpecialEpisode.Should().BeFalse();
}
[Test]
@ -33,7 +33,15 @@ namespace NzbDrone.Core.Test.ParserTests
SeriesTitle = ""
};
parsedEpisodeInfo.IsPossibleSpecialEpisode().Should().BeTrue();
parsedEpisodeInfo.IsPossibleSpecialEpisode.Should().BeTrue();
}
[TestCase("Under.the.Dome.S02.Special-Inside.Chesters.Mill.HDTV.x264-BAJSKORV")]
[TestCase("Under.the.Dome.S02.Special-Inside.Chesters.Mill.720p.HDTV.x264-BAJSKORV")]
[TestCase("Rookie.Blue.Behind.the.Badge.S05.Special.HDTV.x264-2HD")]
public void IsPossibleSpecialEpisode_should_be_true(string title)
{
Parser.Parser.ParseTitle(title).IsPossibleSpecialEpisode.Should().BeTrue();
}
}
}

View File

@ -25,7 +25,7 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Eureka S 01 720p WEB DL DD 5 1 h264 TjHD", "Eureka", 1)]
[TestCase("Doctor Who Confidential Season 3", "Doctor Who Confidential", 3)]
[TestCase("Fleming.S01.720p.WEBDL.DD5.1.H.264-NTb", "Fleming", 1)]
public void should_parsefull_season_release(string postTitle, string title, int season)
public void should_parse_full_season_release(string postTitle, string title, int season)
{
var result = Parser.Parser.ParseTitle(postTitle);
result.SeasonNumber.Should().Be(season);

View File

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Common;
using NzbDrone.Core.DecisionEngine.Specifications;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Instrumentation.Extensions;
@ -63,16 +64,17 @@ namespace NzbDrone.Core.DecisionEngine
{
var parsedEpisodeInfo = Parser.Parser.ParseTitle(report.Title);
if (parsedEpisodeInfo == null || parsedEpisodeInfo.IsPossibleSpecialEpisode())
if (parsedEpisodeInfo == null || parsedEpisodeInfo.IsPossibleSpecialEpisode)
{
var specialEpisodeInfo = _parsingService.ParseSpecialEpisodeTitle(report.Title, report.TvRageId, searchCriteria);
if (specialEpisodeInfo != null)
{
parsedEpisodeInfo = specialEpisodeInfo;
}
}
if (parsedEpisodeInfo != null && !string.IsNullOrWhiteSpace(parsedEpisodeInfo.SeriesTitle))
if (parsedEpisodeInfo != null && !parsedEpisodeInfo.SeriesTitle.IsNullOrWhiteSpace())
{
var remoteEpisode = _parsingService.Map(parsedEpisodeInfo, report.TvRageId, searchCriteria);
remoteEpisode.Release = report;

View File

@ -36,7 +36,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search
var episode = _episodeService.GetEpisode(dailySearchSpec.Series.Id, dailySearchSpec.AirDate.ToString(Episode.AIR_DATE_FORMAT));
if (!remoteEpisode.ParsedEpisodeInfo.IsDaily() || remoteEpisode.ParsedEpisodeInfo.AirDate != episode.AirDate)
if (!remoteEpisode.ParsedEpisodeInfo.IsDaily || remoteEpisode.ParsedEpisodeInfo.AirDate != episode.AirDate)
{
_logger.Debug("Episode AirDate does not match searched episode number, skipping.");
return false;

View File

@ -46,7 +46,7 @@ namespace NzbDrone.Core.Organizer
return validationFailure;
}
if (parsedEpisodeInfo.IsDaily())
if (parsedEpisodeInfo.IsDaily)
{
if (!parsedEpisodeInfo.AirDate.Equals(sampleResult.Episodes.Single().AirDate))
{

View File

@ -1,23 +1,24 @@
using System;
using System.Linq;
using NzbDrone.Common;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Parser.Model
{
public class ParsedEpisodeInfo
{
public string SeriesTitle { get; set; }
public String SeriesTitle { get; set; }
public SeriesTitleInfo SeriesTitleInfo { get; set; }
public QualityModel Quality { get; set; }
public int SeasonNumber { get; set; }
public int[] EpisodeNumbers { get; set; }
public int[] AbsoluteEpisodeNumbers { get; set; }
public Int32 SeasonNumber { get; set; }
public Int32[] EpisodeNumbers { get; set; }
public Int32[] AbsoluteEpisodeNumbers { get; set; }
public String AirDate { get; set; }
public Language Language { get; set; }
public bool FullSeason { get; set; }
public string ReleaseGroup { get; set; }
public string ReleaseHash { get; set; }
public Boolean FullSeason { get; set; }
public Boolean Special { get; set; }
public String ReleaseGroup { get; set; }
public String ReleaseHash { get; set; }
public ParsedEpisodeInfo()
{
@ -25,46 +26,56 @@ namespace NzbDrone.Core.Parser.Model
AbsoluteEpisodeNumbers = new int[0];
}
public bool IsDaily()
public bool IsDaily
{
return !String.IsNullOrWhiteSpace(AirDate);
get
{
return !String.IsNullOrWhiteSpace(AirDate);
}
}
public bool IsAbsoluteNumbering()
public bool IsAbsoluteNumbering
{
return AbsoluteEpisodeNumbers.Any();
get
{
return AbsoluteEpisodeNumbers.Any();
}
}
public bool IsPossibleSpecialEpisode()
public bool IsPossibleSpecialEpisode
{
// if we dont have eny episode numbers we are likely a special episode and need to do a search by episode title
return String.IsNullOrWhiteSpace(AirDate) &&
(EpisodeNumbers.Length == 0 || SeasonNumber == 0) &&
String.IsNullOrWhiteSpace(SeriesTitle);
get
{
// if we don't have eny episode numbers we are likely a special episode and need to do a search by episode title
return (AirDate.IsNullOrWhiteSpace() &&
SeriesTitle.IsNullOrWhiteSpace() &&
(EpisodeNumbers.Length == 0 || SeasonNumber == 0) ||
!SeriesTitle.IsNullOrWhiteSpace() && Special);
}
}
public override string ToString()
{
string episodeString = "[Unknown Episode]";
if (IsDaily() && EpisodeNumbers == null)
if (IsDaily && EpisodeNumbers == null)
{
episodeString = string.Format("{0}", AirDate);
episodeString = String.Format("{0}", AirDate);
}
else if (FullSeason)
{
episodeString = string.Format("Season {0:00}", SeasonNumber);
episodeString = String.Format("Season {0:00}", SeasonNumber);
}
else if (EpisodeNumbers != null && EpisodeNumbers.Any())
{
episodeString = string.Format("S{0:00}E{1}", SeasonNumber, String.Join("-", EpisodeNumbers.Select(c => c.ToString("00"))));
episodeString = String.Format("S{0:00}E{1}", SeasonNumber, String.Join("-", EpisodeNumbers.Select(c => c.ToString("00"))));
}
else if (AbsoluteEpisodeNumbers != null && AbsoluteEpisodeNumbers.Any())
{
episodeString = string.Format("{0}", String.Join("-", AbsoluteEpisodeNumbers.Select(c => c.ToString("000"))));
episodeString = String.Format("{0}", String.Join("-", AbsoluteEpisodeNumbers.Select(c => c.ToString("000"))));
}
return string.Format("{0} - {1} {2}", SeriesTitle, episodeString, Quality);
return String.Format("{0} - {1} {2}", SeriesTitle, episodeString, Quality);
}
}
}

View File

@ -190,7 +190,7 @@ namespace NzbDrone.Core.Parser
var titleWithoutExtension = RemoveFileExtension(title).ToCharArray();
Array.Reverse(titleWithoutExtension);
title = new string(titleWithoutExtension) + title.Substring(titleWithoutExtension.Length);
title = new String(titleWithoutExtension) + title.Substring(titleWithoutExtension.Length);
Logger.Debug("Reversed name detected. Converted to '{0}'", title);
}
@ -213,8 +213,15 @@ namespace NzbDrone.Core.Parser
try
{
var result = ParseMatchCollection(match);
if (result != null)
{
if (result.FullSeason && title.ContainsIgnoreCase("Special"))
{
result.FullSeason = false;
result.Special = true;
}
result.Language = ParseLanguage(title);
Logger.Debug("Language parsed: {0}", result.Language);
@ -379,12 +386,10 @@ namespace NzbDrone.Core.Parser
}
//If no season was found it should be treated as a mini series and season 1
if (seasons.Count == 0)
seasons.Add(1);
if (seasons.Count == 0) seasons.Add(1);
//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;
if (seasons.Distinct().Count() > 1) return null;
result = new ParsedEpisodeInfo
{
@ -431,12 +436,12 @@ namespace NzbDrone.Core.Parser
{
//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;
if (!matchCollection[0].Groups["extras"].Value.IsNullOrWhiteSpace()) return null;
result.FullSeason = true;
}
}
if (result.AbsoluteEpisodeNumbers.Any() && !result.EpisodeNumbers.Any())
{
result.SeasonNumber = 0;

View File

@ -44,15 +44,13 @@ namespace NzbDrone.Core.Parser
{
var parsedEpisodeInfo = Parser.ParsePath(filename);
// do we have a possible special episode?
if (parsedEpisodeInfo == null || parsedEpisodeInfo.IsPossibleSpecialEpisode())
if (parsedEpisodeInfo == null || parsedEpisodeInfo.IsPossibleSpecialEpisode)
{
// try to parse as a special episode
var title = Path.GetFileNameWithoutExtension(filename);
var specialEpisodeInfo = ParseSpecialEpisodeTitle(title, series);
if (specialEpisodeInfo != null)
{
// use special episode
parsedEpisodeInfo = specialEpisodeInfo;
}
}
@ -131,7 +129,7 @@ namespace NzbDrone.Core.Parser
return _episodeService.GetEpisodesBySeason(series.Id, parsedEpisodeInfo.SeasonNumber);
}
if (parsedEpisodeInfo.IsDaily())
if (parsedEpisodeInfo.IsDaily)
{
if (series.SeriesType == SeriesTypes.Standard)
{
@ -149,7 +147,7 @@ namespace NzbDrone.Core.Parser
return result;
}
if (parsedEpisodeInfo.IsAbsoluteNumbering())
if (parsedEpisodeInfo.IsAbsoluteNumbering)
{
var sceneSeasonNumber = _sceneMappingService.GetSeasonNumber(parsedEpisodeInfo.SeriesTitle);
@ -299,6 +297,7 @@ namespace NzbDrone.Core.Parser
{
// find special episode in series season 0
var episode = _episodeService.FindEpisodeByName(series.Id, 0, title);
if (episode != null)
{
// create parsed info from tv episode