Properly handling multi episode in one scene numbered release
Fixed: Multiple episodes under one scene episode for some shows
This commit is contained in:
parent
434ad5f340
commit
669f351d08
|
@ -130,7 +130,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
||||||
Subject.Map(_parsedEpisodeInfo, _series.TvRageId);
|
Subject.Map(_parsedEpisodeInfo, _series.TvRageId);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>()
|
Mocker.GetMock<IEpisodeService>()
|
||||||
.Verify(v => v.FindEpisode(It.IsAny<Int32>(), It.IsAny<Int32>(), It.IsAny<Int32>(), true), Times.Once());
|
.Verify(v => v.FindEpisodesBySceneNumbering(It.IsAny<Int32>(), It.IsAny<Int32>(), It.IsAny<Int32>()), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -141,7 +141,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
||||||
Subject.Map(_parsedEpisodeInfo, _series.TvRageId, _singleEpisodeSearchCriteria);
|
Subject.Map(_parsedEpisodeInfo, _series.TvRageId, _singleEpisodeSearchCriteria);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>()
|
Mocker.GetMock<IEpisodeService>()
|
||||||
.Verify(v => v.FindEpisode(It.IsAny<Int32>(), It.IsAny<Int32>(), It.IsAny<Int32>(), true), Times.Never());
|
.Verify(v => v.FindEpisodesBySceneNumbering(It.IsAny<Int32>(), It.IsAny<Int32>(), It.IsAny<Int32>()), Times.Never());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -153,7 +153,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
||||||
Subject.Map(_parsedEpisodeInfo, _series.TvRageId, _singleEpisodeSearchCriteria);
|
Subject.Map(_parsedEpisodeInfo, _series.TvRageId, _singleEpisodeSearchCriteria);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>()
|
Mocker.GetMock<IEpisodeService>()
|
||||||
.Verify(v => v.FindEpisode(It.IsAny<Int32>(), It.IsAny<Int32>(), It.IsAny<Int32>(), true), Times.Once());
|
.Verify(v => v.FindEpisodesBySceneNumbering(It.IsAny<Int32>(), It.IsAny<Int32>(), It.IsAny<Int32>()), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -162,7 +162,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
||||||
Subject.Map(_parsedEpisodeInfo, _series.TvRageId);
|
Subject.Map(_parsedEpisodeInfo, _series.TvRageId);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>()
|
Mocker.GetMock<IEpisodeService>()
|
||||||
.Verify(v => v.FindEpisode(It.IsAny<Int32>(), It.IsAny<Int32>(), It.IsAny<Int32>(), false), Times.Once());
|
.Verify(v => v.FindEpisode(It.IsAny<Int32>(), It.IsAny<Int32>(), It.IsAny<Int32>()), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -171,7 +171,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
||||||
Subject.Map(_parsedEpisodeInfo, _series.TvRageId, _singleEpisodeSearchCriteria);
|
Subject.Map(_parsedEpisodeInfo, _series.TvRageId, _singleEpisodeSearchCriteria);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>()
|
Mocker.GetMock<IEpisodeService>()
|
||||||
.Verify(v => v.FindEpisode(It.IsAny<Int32>(), It.IsAny<Int32>(), It.IsAny<Int32>(), false), Times.Never());
|
.Verify(v => v.FindEpisode(It.IsAny<Int32>(), It.IsAny<Int32>(), It.IsAny<Int32>()), Times.Never());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -182,7 +182,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
||||||
Subject.Map(_parsedEpisodeInfo, _series.TvRageId, _singleEpisodeSearchCriteria);
|
Subject.Map(_parsedEpisodeInfo, _series.TvRageId, _singleEpisodeSearchCriteria);
|
||||||
|
|
||||||
Mocker.GetMock<IEpisodeService>()
|
Mocker.GetMock<IEpisodeService>()
|
||||||
.Verify(v => v.FindEpisode(It.IsAny<Int32>(), It.IsAny<Int32>(), It.IsAny<Int32>(), false), Times.Once());
|
.Verify(v => v.FindEpisode(It.IsAny<Int32>(), It.IsAny<Int32>(), It.IsAny<Int32>()), Times.Once());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using FizzWare.NBuilder;
|
using System.Linq;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
@ -9,46 +10,55 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class FindEpisodeFixture : DbTest<EpisodeRepository, Episode>
|
public class FindEpisodeFixture : DbTest<EpisodeRepository, Episode>
|
||||||
{
|
{
|
||||||
private Episode _episode;
|
private Episode _episode1;
|
||||||
|
private Episode _episode2;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
_episode = Builder<Episode>.CreateNew()
|
_episode1 = Builder<Episode>.CreateNew()
|
||||||
.With(e => e.Id = 0)
|
.With(e => e.SeriesId = 1)
|
||||||
.With(e => e.SeriesId = 1)
|
.With(e => e.SeasonNumber = 1)
|
||||||
.With(e => e.SeasonNumber = 1)
|
.With(e => e.SceneSeasonNumber = 2)
|
||||||
.With(e => e.SceneSeasonNumber = 2)
|
.With(e => e.EpisodeNumber = 3)
|
||||||
.With(e => e.EpisodeNumber = 3)
|
.With(e => e.AbsoluteEpisodeNumber = 3)
|
||||||
.With(e => e.AbsoluteEpisodeNumber = 3)
|
.With(e => e.SceneEpisodeNumber = 4)
|
||||||
.With(e => e.SceneEpisodeNumber = 4)
|
.BuildNew();
|
||||||
.Build();
|
|
||||||
|
|
||||||
_episode = Db.Insert(_episode);
|
_episode2 = Builder<Episode>.CreateNew()
|
||||||
|
.With(e => e.SeriesId = 1)
|
||||||
|
.With(e => e.SeasonNumber = 1)
|
||||||
|
.With(e => e.SceneSeasonNumber = 2)
|
||||||
|
.With(e => e.EpisodeNumber = 4)
|
||||||
|
.With(e => e.SceneEpisodeNumber = 4)
|
||||||
|
.BuildNew();
|
||||||
|
|
||||||
|
_episode1 = Db.Insert(_episode1);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_find_episode_by_scene_numbering()
|
public void should_find_episode_by_scene_numbering()
|
||||||
{
|
{
|
||||||
Subject.FindEpisodeBySceneNumbering(_episode.SeriesId, _episode.SceneSeasonNumber, _episode.SceneEpisodeNumber)
|
Subject.FindEpisodesBySceneNumbering(_episode1.SeriesId, _episode1.SceneSeasonNumber, _episode1.SceneEpisodeNumber)
|
||||||
|
.First()
|
||||||
.Id
|
.Id
|
||||||
.Should()
|
.Should()
|
||||||
.Be(_episode.Id);
|
.Be(_episode1.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_find_episode_by_standard_numbering()
|
public void should_find_episode_by_standard_numbering()
|
||||||
{
|
{
|
||||||
Subject.Find(_episode.SeriesId, _episode.SeasonNumber, _episode.EpisodeNumber)
|
Subject.Find(_episode1.SeriesId, _episode1.SeasonNumber, _episode1.EpisodeNumber)
|
||||||
.Id
|
.Id
|
||||||
.Should()
|
.Should()
|
||||||
.Be(_episode.Id);
|
.Be(_episode1.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_not_find_episode_that_does_not_exist()
|
public void should_not_find_episode_that_does_not_exist()
|
||||||
{
|
{
|
||||||
Subject.Find(_episode.SeriesId, _episode.SeasonNumber + 1, _episode.EpisodeNumber)
|
Subject.Find(_episode1.SeriesId, _episode1.SeasonNumber + 1, _episode1.EpisodeNumber)
|
||||||
.Should()
|
.Should()
|
||||||
.BeNull();
|
.BeNull();
|
||||||
}
|
}
|
||||||
|
@ -56,10 +66,20 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests
|
||||||
[Test]
|
[Test]
|
||||||
public void should_find_episode_by_absolute_numbering()
|
public void should_find_episode_by_absolute_numbering()
|
||||||
{
|
{
|
||||||
Subject.Find(_episode.SeriesId, _episode.AbsoluteEpisodeNumber.Value)
|
Subject.Find(_episode1.SeriesId, _episode1.AbsoluteEpisodeNumber.Value)
|
||||||
.Id
|
.Id
|
||||||
.Should()
|
.Should()
|
||||||
.Be(_episode.Id);
|
.Be(_episode1.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_multiple_episode_if_multiple_match_by_scene_numbering()
|
||||||
|
{
|
||||||
|
_episode2 = Db.Insert(_episode2);
|
||||||
|
|
||||||
|
Subject.FindEpisodesBySceneNumbering(_episode1.SeriesId, _episode1.SceneSeasonNumber, _episode1.SceneEpisodeNumber)
|
||||||
|
.Should()
|
||||||
|
.HaveCount(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,33 +174,37 @@ namespace NzbDrone.Core.Parser
|
||||||
|
|
||||||
foreach (var episodeNumber in parsedEpisodeInfo.EpisodeNumbers)
|
foreach (var episodeNumber in parsedEpisodeInfo.EpisodeNumbers)
|
||||||
{
|
{
|
||||||
Episode episodeInfo = null;
|
|
||||||
|
|
||||||
if (series.UseSceneNumbering && sceneSource)
|
if (series.UseSceneNumbering && sceneSource)
|
||||||
{
|
{
|
||||||
|
List<Episode> episodes = new List<Episode>();
|
||||||
|
|
||||||
if (searchCriteria != null)
|
if (searchCriteria != null)
|
||||||
{
|
{
|
||||||
episodeInfo = searchCriteria.Episodes.SingleOrDefault(e => e.SceneSeasonNumber == parsedEpisodeInfo.SeasonNumber &&
|
episodes = searchCriteria.Episodes.Where(e => e.SceneSeasonNumber == parsedEpisodeInfo.SeasonNumber &&
|
||||||
e.SceneEpisodeNumber == episodeNumber);
|
e.SceneEpisodeNumber == episodeNumber).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (episodeInfo == null)
|
if (!episodes.Any())
|
||||||
{
|
{
|
||||||
episodeInfo = _episodeService.FindEpisode(series.Id, parsedEpisodeInfo.SeasonNumber, episodeNumber, true);
|
episodes = _episodeService.FindEpisodesBySceneNumbering(series.Id, parsedEpisodeInfo.SeasonNumber, episodeNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (episodeInfo != null)
|
if (episodes != null && episodes.Any())
|
||||||
{
|
{
|
||||||
_logger.Info("Using Scene to TVDB Mapping for: {0} - Scene: {1}x{2:00} - TVDB: {3}x{4:00}",
|
_logger.Info("Using Scene to TVDB Mapping for: {0} - Scene: {1}x{2:00} - TVDB: {3}",
|
||||||
series.Title,
|
series.Title,
|
||||||
episodeInfo.SceneSeasonNumber,
|
episodes.First().SceneSeasonNumber,
|
||||||
episodeInfo.SceneEpisodeNumber,
|
episodes.First().SceneEpisodeNumber,
|
||||||
episodeInfo.SeasonNumber,
|
String.Join(", ", episodes.Select(e => String.Format("{0}x{1:00}", e.SeasonNumber, e.EpisodeNumber))));
|
||||||
episodeInfo.EpisodeNumber);
|
|
||||||
|
result.AddRange(episodes);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (episodeInfo == null && searchCriteria != null)
|
Episode episodeInfo = null;
|
||||||
|
|
||||||
|
if (searchCriteria != null)
|
||||||
{
|
{
|
||||||
episodeInfo = searchCriteria.Episodes.SingleOrDefault(e => e.SeasonNumber == parsedEpisodeInfo.SeasonNumber &&
|
episodeInfo = searchCriteria.Episodes.SingleOrDefault(e => e.SeasonNumber == parsedEpisodeInfo.SeasonNumber &&
|
||||||
e.EpisodeNumber == episodeNumber);
|
e.EpisodeNumber == episodeNumber);
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace NzbDrone.Core.Queue
|
||||||
foreach (var episode in queueItem.RemoteEpisode.Episodes)
|
foreach (var episode in queueItem.RemoteEpisode.Episodes)
|
||||||
{
|
{
|
||||||
var queue = new Queue();
|
var queue = new Queue();
|
||||||
queue.Id = queueItem.Id.GetHashCode();
|
queue.Id = queueItem.Id.GetHashCode() + episode.Id;
|
||||||
queue.Series = queueItem.RemoteEpisode.Series;
|
queue.Series = queueItem.RemoteEpisode.Series;
|
||||||
queue.Episode = episode;
|
queue.Episode = episode;
|
||||||
queue.Quality = queueItem.RemoteEpisode.ParsedEpisodeInfo.Quality;
|
queue.Quality = queueItem.RemoteEpisode.ParsedEpisodeInfo.Quality;
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace NzbDrone.Core.Tv
|
||||||
List<Episode> GetEpisodeByFileId(int fileId);
|
List<Episode> GetEpisodeByFileId(int fileId);
|
||||||
PagingSpec<Episode> EpisodesWithoutFiles(PagingSpec<Episode> pagingSpec, bool includeSpecials);
|
PagingSpec<Episode> EpisodesWithoutFiles(PagingSpec<Episode> pagingSpec, bool includeSpecials);
|
||||||
PagingSpec<Episode> EpisodesWhereCutoffUnmet(PagingSpec<Episode> pagingSpec, List<QualitiesBelowCutoff> qualitiesBelowCutoff, bool includeSpecials);
|
PagingSpec<Episode> EpisodesWhereCutoffUnmet(PagingSpec<Episode> pagingSpec, List<QualitiesBelowCutoff> qualitiesBelowCutoff, bool includeSpecials);
|
||||||
Episode FindEpisodeBySceneNumbering(int seriesId, int seasonNumber, int episodeNumber);
|
List<Episode> FindEpisodesBySceneNumbering(int seriesId, int seasonNumber, int episodeNumber);
|
||||||
List<Episode> EpisodesBetweenDates(DateTime startDate, DateTime endDate);
|
List<Episode> EpisodesBetweenDates(DateTime startDate, DateTime endDate);
|
||||||
void SetMonitoredFlat(Episode episode, bool monitored);
|
void SetMonitoredFlat(Episode episode, bool monitored);
|
||||||
void SetMonitoredBySeason(int seriesId, int seasonNumber, bool monitored);
|
void SetMonitoredBySeason(int seriesId, int seasonNumber, bool monitored);
|
||||||
|
@ -116,12 +116,11 @@ namespace NzbDrone.Core.Tv
|
||||||
return pagingSpec;
|
return pagingSpec;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Episode FindEpisodeBySceneNumbering(int seriesId, int seasonNumber, int episodeNumber)
|
public List<Episode> FindEpisodesBySceneNumbering(int seriesId, int seasonNumber, int episodeNumber)
|
||||||
{
|
{
|
||||||
return Query.Where(s => s.SeriesId == seriesId)
|
return Query.Where(s => s.SeriesId == seriesId)
|
||||||
.AndWhere(s => s.SceneSeasonNumber == seasonNumber)
|
.AndWhere(s => s.SceneSeasonNumber == seasonNumber)
|
||||||
.AndWhere(s => s.SceneEpisodeNumber == episodeNumber)
|
.AndWhere(s => s.SceneEpisodeNumber == episodeNumber);
|
||||||
.SingleOrDefault();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Episode> EpisodesBetweenDates(DateTime startDate, DateTime endDate)
|
public List<Episode> EpisodesBetweenDates(DateTime startDate, DateTime endDate)
|
||||||
|
|
|
@ -14,9 +14,10 @@ namespace NzbDrone.Core.Tv
|
||||||
public interface IEpisodeService
|
public interface IEpisodeService
|
||||||
{
|
{
|
||||||
Episode GetEpisode(int id);
|
Episode GetEpisode(int id);
|
||||||
Episode FindEpisode(int seriesId, int seasonNumber, int episodeNumber, bool useScene = false);
|
Episode FindEpisode(int seriesId, int seasonNumber, int episodeNumber);
|
||||||
Episode FindEpisode(int seriesId, int absoluteEpisodeNumber);
|
Episode FindEpisode(int seriesId, int absoluteEpisodeNumber);
|
||||||
Episode FindEpisodeByName(int seriesId, int seasonNumber, string episodeTitle);
|
Episode FindEpisodeByName(int seriesId, int seasonNumber, string episodeTitle);
|
||||||
|
List<Episode> FindEpisodesBySceneNumbering(int seriesId, int seasonNumber, int episodeNumber);
|
||||||
Episode GetEpisode(int seriesId, String date);
|
Episode GetEpisode(int seriesId, String date);
|
||||||
Episode FindEpisode(int seriesId, String date);
|
Episode FindEpisode(int seriesId, String date);
|
||||||
List<Episode> GetEpisodeBySeries(int seriesId);
|
List<Episode> GetEpisodeBySeries(int seriesId);
|
||||||
|
@ -39,16 +40,13 @@ namespace NzbDrone.Core.Tv
|
||||||
IHandle<EpisodeFileAddedEvent>,
|
IHandle<EpisodeFileAddedEvent>,
|
||||||
IHandleAsync<SeriesDeletedEvent>
|
IHandleAsync<SeriesDeletedEvent>
|
||||||
{
|
{
|
||||||
|
|
||||||
private readonly IEpisodeRepository _episodeRepository;
|
private readonly IEpisodeRepository _episodeRepository;
|
||||||
private readonly IQualityProfileRepository _qualityProfileRepository;
|
|
||||||
private readonly IConfigService _configService;
|
private readonly IConfigService _configService;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public EpisodeService(IEpisodeRepository episodeRepository, IQualityProfileRepository qualityProfileRepository, IConfigService configService, Logger logger)
|
public EpisodeService(IEpisodeRepository episodeRepository, IConfigService configService, Logger logger)
|
||||||
{
|
{
|
||||||
_episodeRepository = episodeRepository;
|
_episodeRepository = episodeRepository;
|
||||||
_qualityProfileRepository = qualityProfileRepository;
|
|
||||||
_configService = configService;
|
_configService = configService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
@ -58,12 +56,8 @@ namespace NzbDrone.Core.Tv
|
||||||
return _episodeRepository.Get(id);
|
return _episodeRepository.Get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Episode FindEpisode(int seriesId, int seasonNumber, int episodeNumber, bool useSceneNumbering = false)
|
public Episode FindEpisode(int seriesId, int seasonNumber, int episodeNumber)
|
||||||
{
|
{
|
||||||
if (useSceneNumbering)
|
|
||||||
{
|
|
||||||
return _episodeRepository.FindEpisodeBySceneNumbering(seriesId, seasonNumber, episodeNumber);
|
|
||||||
}
|
|
||||||
return _episodeRepository.Find(seriesId, seasonNumber, episodeNumber);
|
return _episodeRepository.Find(seriesId, seasonNumber, episodeNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +66,11 @@ namespace NzbDrone.Core.Tv
|
||||||
return _episodeRepository.Find(seriesId, absoluteEpisodeNumber);
|
return _episodeRepository.Find(seriesId, absoluteEpisodeNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Episode> FindEpisodesBySceneNumbering(int seriesId, int seasonNumber, int episodeNumber)
|
||||||
|
{
|
||||||
|
return _episodeRepository.FindEpisodesBySceneNumbering(seriesId, seasonNumber, episodeNumber);
|
||||||
|
}
|
||||||
|
|
||||||
public Episode GetEpisode(int seriesId, String date)
|
public Episode GetEpisode(int seriesId, String date)
|
||||||
{
|
{
|
||||||
return _episodeRepository.Get(seriesId, date);
|
return _episodeRepository.Get(seriesId, date);
|
||||||
|
|
Loading…
Reference in New Issue