mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-12-16 11:37:58 +02:00
Fixed: Specials with the season number will be handled properly
This commit is contained in:
parent
5e68ed7aac
commit
9a92815cbf
@ -14,7 +14,7 @@
|
||||
namespace NzbDrone.Core.Test.Download.DownloadApprovedReportsTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class DownloadApprovedReportsFixture : CoreTest<DownloadApprovedReports>
|
||||
public class GetQualifiedReportsFixture : CoreTest<DownloadApprovedReports>
|
||||
{
|
||||
private Episode GetEpisode(int id)
|
||||
{
|
||||
|
@ -21,7 +21,7 @@ public void should_not_treat_files_without_a_series_title_as_a_special()
|
||||
SeriesTitle = ""
|
||||
};
|
||||
|
||||
parsedEpisodeInfo.IsPossibleSpecialEpisode().Should().BeFalse();
|
||||
parsedEpisodeInfo.IsPossibleSpecialEpisode.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -33,7 +33,15 @@ public void should_return_true_when_episode_numbers_is_empty()
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ public class SeasonParserFixture : CoreTest
|
||||
[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);
|
||||
|
@ -2,6 +2,7 @@
|
||||
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 @@ private IEnumerable<DownloadDecision> GetDecisions(List<ReleaseInfo> reports, Se
|
||||
{
|
||||
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;
|
||||
|
@ -36,7 +36,7 @@ public bool IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchCriteriaBase 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;
|
||||
|
@ -46,7 +46,7 @@ public ValidationFailure ValidateDailyFilename(SampleResult sampleResult)
|
||||
return validationFailure;
|
||||
}
|
||||
|
||||
if (parsedEpisodeInfo.IsDaily())
|
||||
if (parsedEpisodeInfo.IsDaily)
|
||||
{
|
||||
if (!parsedEpisodeInfo.AirDate.Equals(sampleResult.Episodes.Single().AirDate))
|
||||
{
|
||||
|
@ -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 @@ public ParsedEpisodeInfo()
|
||||
AbsoluteEpisodeNumbers = new int[0];
|
||||
}
|
||||
|
||||
public bool IsDaily()
|
||||
public bool IsDaily
|
||||
{
|
||||
get
|
||||
{
|
||||
return !String.IsNullOrWhiteSpace(AirDate);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAbsoluteNumbering()
|
||||
public bool IsAbsoluteNumbering
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -190,7 +190,7 @@ public static ParsedEpisodeInfo ParseTitle(string title)
|
||||
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 @@ public static ParsedEpisodeInfo ParseTitle(string title)
|
||||
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 @@ private static ParsedEpisodeInfo ParseMatchCollection(MatchCollection matchColle
|
||||
}
|
||||
|
||||
//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 @@ private static ParsedEpisodeInfo ParseMatchCollection(MatchCollection matchColle
|
||||
{
|
||||
//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;
|
||||
|
@ -44,15 +44,13 @@ public LocalEpisode GetLocalEpisode(string filename, Series series, bool sceneSo
|
||||
{
|
||||
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 @@ public List<Episode> GetEpisodes(ParsedEpisodeInfo parsedEpisodeInfo, Series ser
|
||||
return _episodeService.GetEpisodesBySeason(series.Id, parsedEpisodeInfo.SeasonNumber);
|
||||
}
|
||||
|
||||
if (parsedEpisodeInfo.IsDaily())
|
||||
if (parsedEpisodeInfo.IsDaily)
|
||||
{
|
||||
if (series.SeriesType == SeriesTypes.Standard)
|
||||
{
|
||||
@ -149,7 +147,7 @@ public List<Episode> GetEpisodes(ParsedEpisodeInfo parsedEpisodeInfo, Series ser
|
||||
return result;
|
||||
}
|
||||
|
||||
if (parsedEpisodeInfo.IsAbsoluteNumbering())
|
||||
if (parsedEpisodeInfo.IsAbsoluteNumbering)
|
||||
{
|
||||
var sceneSeasonNumber = _sceneMappingService.GetSeasonNumber(parsedEpisodeInfo.SeriesTitle);
|
||||
|
||||
@ -299,6 +297,7 @@ public ParsedEpisodeInfo ParseSpecialEpisodeTitle(string title, Series series)
|
||||
{
|
||||
// find special episode in series season 0
|
||||
var episode = _episodeService.FindEpisodeByName(series.Id, 0, title);
|
||||
|
||||
if (episode != null)
|
||||
{
|
||||
// create parsed info from tv episode
|
||||
|
Loading…
Reference in New Issue
Block a user