Fixed: TheXEM mapping with one scene release to multiple tvdb episodes.
This commit is contained in:
parent
940f59468a
commit
e15530cee1
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.DataAugmentation.Scene;
|
||||
|
@ -117,6 +118,10 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
|||
{
|
||||
GivenAbsoluteNumberingSeries();
|
||||
|
||||
Mocker.GetMock<IEpisodeService>()
|
||||
.Setup(s => s.FindEpisodesBySceneNumbering(It.IsAny<int>(), It.IsAny<int>()))
|
||||
.Returns(new List<Episode>());
|
||||
|
||||
Subject.Map(_parsedEpisodeInfo, _series.TvdbId, _series.TvRageId, _singleEpisodeSearchCriteria);
|
||||
|
||||
Mocker.GetMock<IEpisodeService>()
|
||||
|
@ -253,7 +258,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
|||
[TestCase(0)]
|
||||
[TestCase(1)]
|
||||
[TestCase(2)]
|
||||
public void should_find_episode_by_season_and_absolute_episode_number_when_scene_absolute_episode_number_returns_multiple_results(int seasonNumber)
|
||||
public void should_return_episodes_when_scene_absolute_episode_number_returns_multiple_results(int seasonNumber)
|
||||
{
|
||||
GivenAbsoluteNumberingSeries();
|
||||
|
||||
|
@ -265,6 +270,32 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
|||
.Setup(s => s.FindEpisodesBySceneNumbering(It.IsAny<int>(), seasonNumber, It.IsAny<int>()))
|
||||
.Returns(Builder<Episode>.CreateListOfSize(5).Build().ToList());
|
||||
|
||||
var result = Subject.GetEpisodes(_parsedEpisodeInfo, _series, true, null);
|
||||
|
||||
result.Should().HaveCount(5);
|
||||
|
||||
Mocker.GetMock<IEpisodeService>()
|
||||
.Verify(v => v.FindEpisodesBySceneNumbering(It.IsAny<int>(), seasonNumber, It.IsAny<int>()), Times.Once());
|
||||
|
||||
Mocker.GetMock<IEpisodeService>()
|
||||
.Verify(v => v.FindEpisode(It.IsAny<int>(), seasonNumber, It.IsAny<int>()), Times.Never());
|
||||
}
|
||||
|
||||
[TestCase(0)]
|
||||
[TestCase(1)]
|
||||
[TestCase(2)]
|
||||
public void should_find_episode_by_season_and_absolute_episode_number_when_scene_absolute_episode_number_returns_no_results(int seasonNumber)
|
||||
{
|
||||
GivenAbsoluteNumberingSeries();
|
||||
|
||||
Mocker.GetMock<ISceneMappingService>()
|
||||
.Setup(s => s.GetSceneSeasonNumber(_parsedEpisodeInfo.SeriesTitle, It.IsAny<string>()))
|
||||
.Returns(seasonNumber);
|
||||
|
||||
Mocker.GetMock<IEpisodeService>()
|
||||
.Setup(s => s.FindEpisodesBySceneNumbering(It.IsAny<int>(), seasonNumber, It.IsAny<int>()))
|
||||
.Returns(Builder<Episode>.CreateListOfSize(0).Build().ToList());
|
||||
|
||||
Subject.GetEpisodes(_parsedEpisodeInfo, _series, true, null);
|
||||
|
||||
Mocker.GetMock<IEpisodeService>()
|
||||
|
|
|
@ -31,7 +31,25 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search
|
|||
if (!criteriaEpisodes.Intersect(remoteEpisodes).Any())
|
||||
{
|
||||
_logger.Debug("Release rejected since the episode wasn't requested: {0}", remoteEpisode.ParsedEpisodeInfo);
|
||||
return Decision.Reject("Episode wasn't requested");
|
||||
|
||||
if (remoteEpisodes.Any())
|
||||
{
|
||||
var episodes = remoteEpisode.Episodes.OrderBy(v => v.SeasonNumber).ThenBy(v => v.EpisodeNumber).ToList();
|
||||
|
||||
if (episodes.Count > 1)
|
||||
{
|
||||
return Decision.Reject($"Episode wasn't requested: {episodes.First().SeasonNumber}x{episodes.First().EpisodeNumber}-{episodes.Last().EpisodeNumber}");
|
||||
}
|
||||
else
|
||||
{
|
||||
return Decision.Reject($"Episode wasn't requested: {episodes.First().SeasonNumber}x{episodes.First().EpisodeNumber}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Decision.Reject("Episode wasn't requested");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Decision.Accept();
|
||||
|
|
|
@ -25,8 +25,16 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search
|
|||
}
|
||||
|
||||
var singleEpisodeSpec = searchCriteria as SingleEpisodeSearchCriteria;
|
||||
if (singleEpisodeSpec == null) return Decision.Accept();
|
||||
if (singleEpisodeSpec != null) return IsSatisfiedBy(remoteEpisode, singleEpisodeSpec);
|
||||
|
||||
var animeEpisodeSpec = searchCriteria as AnimeEpisodeSearchCriteria;
|
||||
if (animeEpisodeSpec != null) return IsSatisfiedBy(remoteEpisode, animeEpisodeSpec);
|
||||
|
||||
return Decision.Accept();
|
||||
}
|
||||
|
||||
private Decision IsSatisfiedBy(RemoteEpisode remoteEpisode, SingleEpisodeSearchCriteria singleEpisodeSpec)
|
||||
{
|
||||
if (singleEpisodeSpec.SeasonNumber != remoteEpisode.ParsedEpisodeInfo.SeasonNumber)
|
||||
{
|
||||
_logger.Debug("Season number does not match searched season number, skipping.");
|
||||
|
@ -47,5 +55,16 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search
|
|||
|
||||
return Decision.Accept();
|
||||
}
|
||||
|
||||
private Decision IsSatisfiedBy(RemoteEpisode remoteEpisode, AnimeEpisodeSearchCriteria singleEpisodeSpec)
|
||||
{
|
||||
if (remoteEpisode.ParsedEpisodeInfo.FullSeason)
|
||||
{
|
||||
_logger.Debug("Full season result during single episode search, skipping.");
|
||||
return Decision.Reject("Full season pack");
|
||||
}
|
||||
|
||||
return Decision.Accept();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -363,13 +363,13 @@ namespace NzbDrone.Core.Parser
|
|||
|
||||
foreach (var absoluteEpisodeNumber in parsedEpisodeInfo.AbsoluteEpisodeNumbers)
|
||||
{
|
||||
Episode episode = null;
|
||||
var episodes = new List<Episode>();
|
||||
|
||||
if (parsedEpisodeInfo.Special)
|
||||
{
|
||||
episode = _episodeService.FindEpisode(series.Id, 0, absoluteEpisodeNumber);
|
||||
var episode = _episodeService.FindEpisode(series.Id, 0, absoluteEpisodeNumber);
|
||||
episodes.AddIfNotNull(episode);
|
||||
}
|
||||
|
||||
else if (sceneSource)
|
||||
{
|
||||
// Is there a reason why we excluded season 1 from this handling before?
|
||||
|
@ -377,31 +377,33 @@ namespace NzbDrone.Core.Parser
|
|||
// If this needs to be reverted tests will need to be added
|
||||
if (sceneSeasonNumber.HasValue)
|
||||
{
|
||||
var episodes = _episodeService.FindEpisodesBySceneNumbering(series.Id, sceneSeasonNumber.Value, absoluteEpisodeNumber);
|
||||
episodes = _episodeService.FindEpisodesBySceneNumbering(series.Id, sceneSeasonNumber.Value, absoluteEpisodeNumber);
|
||||
|
||||
if (episodes.Count == 1)
|
||||
if (episodes.Empty())
|
||||
{
|
||||
episode = episodes.First();
|
||||
}
|
||||
|
||||
if (episode == null)
|
||||
{
|
||||
episode = _episodeService.FindEpisode(series.Id, sceneSeasonNumber.Value, absoluteEpisodeNumber);
|
||||
var episode = _episodeService.FindEpisode(series.Id, sceneSeasonNumber.Value, absoluteEpisodeNumber);
|
||||
episodes.AddIfNotNull(episode);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
episode = _episodeService.FindEpisodeBySceneNumbering(series.Id, absoluteEpisodeNumber);
|
||||
episodes = _episodeService.FindEpisodesBySceneNumbering(series.Id, absoluteEpisodeNumber);
|
||||
|
||||
// Don't allow multiple results without a scene name mapping.
|
||||
if (episodes.Count > 1)
|
||||
{
|
||||
episodes.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (episode == null)
|
||||
if (episodes.Empty())
|
||||
{
|
||||
episode = _episodeService.FindEpisode(series.Id, absoluteEpisodeNumber);
|
||||
var episode = _episodeService.FindEpisode(series.Id, absoluteEpisodeNumber);
|
||||
episodes.AddIfNotNull(episode);
|
||||
}
|
||||
|
||||
if (episode != null)
|
||||
foreach (var episode in episodes)
|
||||
{
|
||||
_logger.Debug("Using absolute episode number {0} for: {1} - TVDB: {2}x{3:00}",
|
||||
absoluteEpisodeNumber,
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace NzbDrone.Core.Tv
|
|||
PagingSpec<Episode> EpisodesWithoutFiles(PagingSpec<Episode> pagingSpec, bool includeSpecials);
|
||||
PagingSpec<Episode> EpisodesWhereCutoffUnmet(PagingSpec<Episode> pagingSpec, List<QualitiesBelowCutoff> qualitiesBelowCutoff, bool includeSpecials);
|
||||
List<Episode> FindEpisodesBySceneNumbering(int seriesId, int seasonNumber, int episodeNumber);
|
||||
Episode FindEpisodeBySceneNumbering(int seriesId, int sceneAbsoluteEpisodeNumber);
|
||||
List<Episode> FindEpisodesBySceneNumbering(int seriesId, int sceneAbsoluteEpisodeNumber);
|
||||
List<Episode> EpisodesBetweenDates(DateTime startDate, DateTime endDate, bool includeUnmonitored);
|
||||
void SetMonitoredFlat(Episode episode, bool monitored);
|
||||
void SetMonitoredBySeason(int seriesId, int seasonNumber, bool monitored);
|
||||
|
@ -134,21 +134,15 @@ namespace NzbDrone.Core.Tv
|
|||
{
|
||||
return Query.Where(s => s.SeriesId == seriesId)
|
||||
.AndWhere(s => s.SceneSeasonNumber == seasonNumber)
|
||||
.AndWhere(s => s.SceneEpisodeNumber == episodeNumber);
|
||||
.AndWhere(s => s.SceneEpisodeNumber == episodeNumber)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public Episode FindEpisodeBySceneNumbering(int seriesId, int sceneAbsoluteEpisodeNumber)
|
||||
public List<Episode> FindEpisodesBySceneNumbering(int seriesId, int sceneAbsoluteEpisodeNumber)
|
||||
{
|
||||
var episodes = Query.Where(s => s.SeriesId == seriesId)
|
||||
return Query.Where(s => s.SeriesId == seriesId)
|
||||
.AndWhere(s => s.SceneAbsoluteEpisodeNumber == sceneAbsoluteEpisodeNumber)
|
||||
.ToList();
|
||||
|
||||
if (episodes.Empty() || episodes.Count > 1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return episodes.Single();
|
||||
}
|
||||
|
||||
public List<Episode> EpisodesBetweenDates(DateTime startDate, DateTime endDate, bool includeUnmonitored)
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace NzbDrone.Core.Tv
|
|||
Episode FindEpisode(int seriesId, int absoluteEpisodeNumber);
|
||||
Episode FindEpisodeByTitle(int seriesId, int seasonNumber, string releaseTitle);
|
||||
List<Episode> FindEpisodesBySceneNumbering(int seriesId, int seasonNumber, int episodeNumber);
|
||||
Episode FindEpisodeBySceneNumbering(int seriesId, int sceneAbsoluteEpisodeNumber);
|
||||
List<Episode> FindEpisodesBySceneNumbering(int seriesId, int sceneAbsoluteEpisodeNumber);
|
||||
Episode GetEpisode(int seriesId, string date);
|
||||
Episode FindEpisode(int seriesId, string date);
|
||||
List<Episode> GetEpisodeBySeries(int seriesId);
|
||||
|
@ -78,9 +78,9 @@ namespace NzbDrone.Core.Tv
|
|||
return _episodeRepository.FindEpisodesBySceneNumbering(seriesId, seasonNumber, episodeNumber);
|
||||
}
|
||||
|
||||
public Episode FindEpisodeBySceneNumbering(int seriesId, int sceneAbsoluteEpisodeNumber)
|
||||
public List<Episode> FindEpisodesBySceneNumbering(int seriesId, int sceneAbsoluteEpisodeNumber)
|
||||
{
|
||||
return _episodeRepository.FindEpisodeBySceneNumbering(seriesId, sceneAbsoluteEpisodeNumber);
|
||||
return _episodeRepository.FindEpisodesBySceneNumbering(seriesId, sceneAbsoluteEpisodeNumber);
|
||||
}
|
||||
|
||||
public Episode GetEpisode(int seriesId, string date)
|
||||
|
|
Loading…
Reference in New Issue