mirror of https://github.com/Sonarr/Sonarr
Fixed: Daily series with multiple episodes on the same day
This commit is contained in:
parent
a336726dd5
commit
9edb261c16
|
@ -213,6 +213,7 @@
|
||||||
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedEpisodesFixture.cs" />
|
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedEpisodesFixture.cs" />
|
||||||
<Compile Include="ThingiProviderTests\NullConfigFixture.cs" />
|
<Compile Include="ThingiProviderTests\NullConfigFixture.cs" />
|
||||||
<Compile Include="ThingiProvider\ProviderBaseFixture.cs" />
|
<Compile Include="ThingiProvider\ProviderBaseFixture.cs" />
|
||||||
|
<Compile Include="TvTests\EpisodeRepositoryTests\ByAirDateFixture.cs" />
|
||||||
<Compile Include="TvTests\EpisodeRepositoryTests\EpisodesWithFilesFixture.cs" />
|
<Compile Include="TvTests\EpisodeRepositoryTests\EpisodesWithFilesFixture.cs" />
|
||||||
<Compile Include="TvTests\EpisodeRepositoryTests\EpisodesWhereCutoffUnmetFixture.cs" />
|
<Compile Include="TvTests\EpisodeRepositoryTests\EpisodesWhereCutoffUnmetFixture.cs" />
|
||||||
<Compile Include="TvTests\RefreshEpisodeServiceFixture.cs" />
|
<Compile Include="TvTests\RefreshEpisodeServiceFixture.cs" />
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
using System;
|
||||||
|
using FizzWare.NBuilder;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using NzbDrone.Core.Tv;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class ByAirDateFixture : DbTest<EpisodeRepository, Episode>
|
||||||
|
{
|
||||||
|
private const int SERIES_ID = 1;
|
||||||
|
private const string AIR_DATE = "2014-04-02";
|
||||||
|
|
||||||
|
private void GivenEpisode(int seasonNumber)
|
||||||
|
{
|
||||||
|
var episode = Builder<Episode>.CreateNew()
|
||||||
|
.With(e => e.SeriesId = 1)
|
||||||
|
.With(e => e.SeasonNumber = seasonNumber)
|
||||||
|
.With(e => e.AirDate = AIR_DATE)
|
||||||
|
.BuildNew();
|
||||||
|
|
||||||
|
Db.Insert(episode);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_throw_when_multiple_regular_episodes_are_found()
|
||||||
|
{
|
||||||
|
GivenEpisode(1);
|
||||||
|
GivenEpisode(2);
|
||||||
|
|
||||||
|
Assert.Throws<InvalidOperationException>(() => Subject.Get(SERIES_ID, AIR_DATE));
|
||||||
|
Assert.Throws<InvalidOperationException>(() => Subject.Find(SERIES_ID, AIR_DATE));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_throw_when_get_finds_no_episode()
|
||||||
|
{
|
||||||
|
Assert.Throws<InvalidOperationException>(() => Subject.Get(SERIES_ID, AIR_DATE));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_get_episode_when_single_episode_exists_for_air_date()
|
||||||
|
{
|
||||||
|
GivenEpisode(1);
|
||||||
|
|
||||||
|
Subject.Get(SERIES_ID, AIR_DATE).Should().NotBeNull();
|
||||||
|
Subject.Find(SERIES_ID, AIR_DATE).Should().NotBeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_get_episode_when_regular_episode_and_special_share_the_same_air_date()
|
||||||
|
{
|
||||||
|
GivenEpisode(1);
|
||||||
|
GivenEpisode(0);
|
||||||
|
|
||||||
|
Subject.Get(SERIES_ID, AIR_DATE).Should().NotBeNull();
|
||||||
|
Subject.Find(SERIES_ID, AIR_DATE).Should().NotBeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_get_special_when_its_the_only_episode_for_the_date_provided()
|
||||||
|
{
|
||||||
|
GivenEpisode(0);
|
||||||
|
|
||||||
|
Subject.Get(SERIES_ID, AIR_DATE).Should().NotBeNull();
|
||||||
|
Subject.Find(SERIES_ID, AIR_DATE).Should().NotBeNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Marr.Data.QGen;
|
using Marr.Data.QGen;
|
||||||
|
using NLog;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
using NzbDrone.Core.Datastore.Extentions;
|
using NzbDrone.Core.Datastore.Extentions;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
|
@ -14,8 +16,8 @@ namespace NzbDrone.Core.Tv
|
||||||
{
|
{
|
||||||
Episode Find(int seriesId, int season, int episodeNumber);
|
Episode Find(int seriesId, int season, int episodeNumber);
|
||||||
Episode Find(int seriesId, int absoluteEpisodeNumber);
|
Episode Find(int seriesId, int absoluteEpisodeNumber);
|
||||||
Episode Get(int seriesId, String date);
|
Episode Get(int seriesId, string date);
|
||||||
Episode Find(int seriesId, String date);
|
Episode Find(int seriesId, string date);
|
||||||
List<Episode> GetEpisodes(int seriesId);
|
List<Episode> GetEpisodes(int seriesId);
|
||||||
List<Episode> GetEpisodes(int seriesId, int seasonNumber);
|
List<Episode> GetEpisodes(int seriesId, int seasonNumber);
|
||||||
List<Episode> GetEpisodeByFileId(int fileId);
|
List<Episode> GetEpisodeByFileId(int fileId);
|
||||||
|
@ -32,11 +34,13 @@ namespace NzbDrone.Core.Tv
|
||||||
public class EpisodeRepository : BasicRepository<Episode>, IEpisodeRepository
|
public class EpisodeRepository : BasicRepository<Episode>, IEpisodeRepository
|
||||||
{
|
{
|
||||||
private readonly IDatabase _database;
|
private readonly IDatabase _database;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public EpisodeRepository(IDatabase database, IEventAggregator eventAggregator)
|
public EpisodeRepository(IDatabase database, IEventAggregator eventAggregator, Logger logger)
|
||||||
: base(database, eventAggregator)
|
: base(database, eventAggregator)
|
||||||
{
|
{
|
||||||
_database = database;
|
_database = database;
|
||||||
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Episode Find(int seriesId, int season, int episodeNumber)
|
public Episode Find(int seriesId, int season, int episodeNumber)
|
||||||
|
@ -54,18 +58,21 @@ namespace NzbDrone.Core.Tv
|
||||||
.SingleOrDefault();
|
.SingleOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Episode Get(int seriesId, String date)
|
public Episode Get(int seriesId, string date)
|
||||||
{
|
{
|
||||||
return Query.Where(s => s.SeriesId == seriesId)
|
var episode = FindOneByAirDate(seriesId, date);
|
||||||
.AndWhere(s => s.AirDate == date)
|
|
||||||
.Single();
|
if (episode == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Expected at one episode");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Episode Find(int seriesId, String date)
|
return episode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Episode Find(int seriesId, string date)
|
||||||
{
|
{
|
||||||
return Query.Where(s => s.SeriesId == seriesId)
|
return FindOneByAirDate(seriesId, date);
|
||||||
.AndWhere(s => s.AirDate == date)
|
|
||||||
.SingleOrDefault();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Episode> GetEpisodes(int seriesId)
|
public List<Episode> GetEpisodes(int seriesId)
|
||||||
|
@ -207,5 +214,28 @@ namespace NzbDrone.Core.Tv
|
||||||
|
|
||||||
return String.Format("({0})", String.Join(" OR ", clauses));
|
return String.Format("({0})", String.Join(" OR ", clauses));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Episode FindOneByAirDate(int seriesId, string date)
|
||||||
|
{
|
||||||
|
var episodes = Query.Where(s => s.SeriesId == seriesId)
|
||||||
|
.AndWhere(s => s.AirDate == date)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (!episodes.Any()) return null;
|
||||||
|
|
||||||
|
if (episodes.Count == 1) return episodes.First();
|
||||||
|
|
||||||
|
_logger.Debug("Multiple episodes with the same air date were found, will exclude specials");
|
||||||
|
|
||||||
|
var regularEpisodes = episodes.Where(e => e.SeasonNumber > 0).ToList();
|
||||||
|
|
||||||
|
if (regularEpisodes.Count == 1)
|
||||||
|
{
|
||||||
|
_logger.Debug("Left with one episode after excluding specials");
|
||||||
|
return regularEpisodes.First();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InvalidOperationException("Multiple episodes with the same air date found");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue