mirror of https://github.com/lidarr/Lidarr
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);
|
||||
|
||||
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]
|
||||
|
@ -141,7 +141,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
|||
Subject.Map(_parsedEpisodeInfo, _series.TvRageId, _singleEpisodeSearchCriteria);
|
||||
|
||||
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]
|
||||
|
@ -153,7 +153,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
|||
Subject.Map(_parsedEpisodeInfo, _series.TvRageId, _singleEpisodeSearchCriteria);
|
||||
|
||||
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]
|
||||
|
@ -162,7 +162,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
|||
Subject.Map(_parsedEpisodeInfo, _series.TvRageId);
|
||||
|
||||
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]
|
||||
|
@ -171,7 +171,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
|||
Subject.Map(_parsedEpisodeInfo, _series.TvRageId, _singleEpisodeSearchCriteria);
|
||||
|
||||
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]
|
||||
|
@ -182,7 +182,7 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
|||
Subject.Map(_parsedEpisodeInfo, _series.TvRageId, _singleEpisodeSearchCriteria);
|
||||
|
||||
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 NUnit.Framework;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
@ -9,46 +10,55 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests
|
|||
[TestFixture]
|
||||
public class FindEpisodeFixture : DbTest<EpisodeRepository, Episode>
|
||||
{
|
||||
private Episode _episode;
|
||||
private Episode _episode1;
|
||||
private Episode _episode2;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_episode = Builder<Episode>.CreateNew()
|
||||
.With(e => e.Id = 0)
|
||||
.With(e => e.SeriesId = 1)
|
||||
.With(e => e.SeasonNumber = 1)
|
||||
.With(e => e.SceneSeasonNumber = 2)
|
||||
.With(e => e.EpisodeNumber = 3)
|
||||
.With(e => e.AbsoluteEpisodeNumber = 3)
|
||||
.With(e => e.SceneEpisodeNumber = 4)
|
||||
.Build();
|
||||
_episode1 = Builder<Episode>.CreateNew()
|
||||
.With(e => e.SeriesId = 1)
|
||||
.With(e => e.SeasonNumber = 1)
|
||||
.With(e => e.SceneSeasonNumber = 2)
|
||||
.With(e => e.EpisodeNumber = 3)
|
||||
.With(e => e.AbsoluteEpisodeNumber = 3)
|
||||
.With(e => e.SceneEpisodeNumber = 4)
|
||||
.BuildNew();
|
||||
|
||||
_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]
|
||||
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
|
||||
.Should()
|
||||
.Be(_episode.Id);
|
||||
.Be(_episode1.Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
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
|
||||
.Should()
|
||||
.Be(_episode.Id);
|
||||
.Be(_episode1.Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
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()
|
||||
.BeNull();
|
||||
}
|
||||
|
@ -56,10 +66,20 @@ namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests
|
|||
[Test]
|
||||
public void should_find_episode_by_absolute_numbering()
|
||||
{
|
||||
Subject.Find(_episode.SeriesId, _episode.AbsoluteEpisodeNumber.Value)
|
||||
Subject.Find(_episode1.SeriesId, _episode1.AbsoluteEpisodeNumber.Value)
|
||||
.Id
|
||||
.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)
|
||||
{
|
||||
Episode episodeInfo = null;
|
||||
|
||||
if (series.UseSceneNumbering && sceneSource)
|
||||
{
|
||||
List<Episode> episodes = new List<Episode>();
|
||||
|
||||
if (searchCriteria != null)
|
||||
{
|
||||
episodeInfo = searchCriteria.Episodes.SingleOrDefault(e => e.SceneSeasonNumber == parsedEpisodeInfo.SeasonNumber &&
|
||||
e.SceneEpisodeNumber == episodeNumber);
|
||||
episodes = searchCriteria.Episodes.Where(e => e.SceneSeasonNumber == parsedEpisodeInfo.SeasonNumber &&
|
||||
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,
|
||||
episodeInfo.SceneSeasonNumber,
|
||||
episodeInfo.SceneEpisodeNumber,
|
||||
episodeInfo.SeasonNumber,
|
||||
episodeInfo.EpisodeNumber);
|
||||
episodes.First().SceneSeasonNumber,
|
||||
episodes.First().SceneEpisodeNumber,
|
||||
String.Join(", ", episodes.Select(e => String.Format("{0}x{1:00}", e.SeasonNumber, e.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 &&
|
||||
e.EpisodeNumber == episodeNumber);
|
||||
|
|
|
@ -53,7 +53,7 @@ namespace NzbDrone.Core.Queue
|
|||
foreach (var episode in queueItem.RemoteEpisode.Episodes)
|
||||
{
|
||||
var queue = new Queue();
|
||||
queue.Id = queueItem.Id.GetHashCode();
|
||||
queue.Id = queueItem.Id.GetHashCode() + episode.Id;
|
||||
queue.Series = queueItem.RemoteEpisode.Series;
|
||||
queue.Episode = episode;
|
||||
queue.Quality = queueItem.RemoteEpisode.ParsedEpisodeInfo.Quality;
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace NzbDrone.Core.Tv
|
|||
List<Episode> GetEpisodeByFileId(int fileId);
|
||||
PagingSpec<Episode> EpisodesWithoutFiles(PagingSpec<Episode> pagingSpec, 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);
|
||||
void SetMonitoredFlat(Episode episode, bool monitored);
|
||||
void SetMonitoredBySeason(int seriesId, int seasonNumber, bool monitored);
|
||||
|
@ -116,12 +116,11 @@ namespace NzbDrone.Core.Tv
|
|||
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)
|
||||
.AndWhere(s => s.SceneSeasonNumber == seasonNumber)
|
||||
.AndWhere(s => s.SceneEpisodeNumber == episodeNumber)
|
||||
.SingleOrDefault();
|
||||
.AndWhere(s => s.SceneEpisodeNumber == episodeNumber);
|
||||
}
|
||||
|
||||
public List<Episode> EpisodesBetweenDates(DateTime startDate, DateTime endDate)
|
||||
|
|
|
@ -14,9 +14,10 @@ namespace NzbDrone.Core.Tv
|
|||
public interface IEpisodeService
|
||||
{
|
||||
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 FindEpisodeByName(int seriesId, int seasonNumber, string episodeTitle);
|
||||
List<Episode> FindEpisodesBySceneNumbering(int seriesId, int seasonNumber, int episodeNumber);
|
||||
Episode GetEpisode(int seriesId, String date);
|
||||
Episode FindEpisode(int seriesId, String date);
|
||||
List<Episode> GetEpisodeBySeries(int seriesId);
|
||||
|
@ -39,16 +40,13 @@ namespace NzbDrone.Core.Tv
|
|||
IHandle<EpisodeFileAddedEvent>,
|
||||
IHandleAsync<SeriesDeletedEvent>
|
||||
{
|
||||
|
||||
private readonly IEpisodeRepository _episodeRepository;
|
||||
private readonly IQualityProfileRepository _qualityProfileRepository;
|
||||
private readonly IConfigService _configService;
|
||||
private readonly Logger _logger;
|
||||
|
||||
public EpisodeService(IEpisodeRepository episodeRepository, IQualityProfileRepository qualityProfileRepository, IConfigService configService, Logger logger)
|
||||
public EpisodeService(IEpisodeRepository episodeRepository, IConfigService configService, Logger logger)
|
||||
{
|
||||
_episodeRepository = episodeRepository;
|
||||
_qualityProfileRepository = qualityProfileRepository;
|
||||
_configService = configService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
@ -58,12 +56,8 @@ namespace NzbDrone.Core.Tv
|
|||
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);
|
||||
}
|
||||
|
||||
|
@ -72,6 +66,11 @@ namespace NzbDrone.Core.Tv
|
|||
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)
|
||||
{
|
||||
return _episodeRepository.Get(seriesId, date);
|
||||
|
|
Loading…
Reference in New Issue