diff --git a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj
index b3e34350c..0d3bd3634 100644
--- a/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj
+++ b/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj
@@ -186,6 +186,7 @@
+
diff --git a/NzbDrone.Core.Test/TvTests/SeasonServiceTests/HandleEpisodeInfoDeletedEventFixture.cs b/NzbDrone.Core.Test/TvTests/SeasonServiceTests/HandleEpisodeInfoDeletedEventFixture.cs
new file mode 100644
index 000000000..d31c2b679
--- /dev/null
+++ b/NzbDrone.Core.Test/TvTests/SeasonServiceTests/HandleEpisodeInfoDeletedEventFixture.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using FizzWare.NBuilder;
+using Moq;
+using NUnit.Framework;
+using NzbDrone.Core.Test.Framework;
+using NzbDrone.Core.Tv;
+using NzbDrone.Core.Tv.Events;
+
+namespace NzbDrone.Core.Test.TvTests.SeasonServiceTests
+{
+ [TestFixture]
+ public class HandleEpisodeInfoDeletedEventFixture : CoreTest
+ {
+ private List _seasons;
+ private List _episodes;
+
+ [SetUp]
+ public void Setup()
+ {
+ _seasons = Builder
+ .CreateListOfSize(1)
+ .All()
+ .With(s => s.SeriesId = 1)
+ .Build()
+ .ToList();
+
+ _episodes = Builder
+ .CreateListOfSize(1)
+ .All()
+ .With(e => e.SeasonNumber = _seasons.First().SeasonNumber)
+ .With(s => s.SeriesId = _seasons.First().SeasonNumber)
+ .Build()
+ .ToList();
+
+ Mocker.GetMock()
+ .Setup(s => s.GetSeasonBySeries(It.IsAny()))
+ .Returns(_seasons);
+
+ Mocker.GetMock()
+ .Setup(s => s.GetEpisodesBySeason(It.IsAny(), _seasons.First().SeasonNumber))
+ .Returns(_episodes);
+ }
+
+ private void GivenAbandonedSeason()
+ {
+ Mocker.GetMock()
+ .Setup(s => s.GetEpisodesBySeason(It.IsAny(), _seasons.First().SeasonNumber))
+ .Returns(new List());
+ }
+
+ [Test]
+ public void should_not_delete_when_season_is_still_valid()
+ {
+ Subject.Handle(new EpisodeInfoDeletedEvent(_episodes));
+
+ Mocker.GetMock()
+ .Verify(v => v.Delete(It.IsAny()), Times.Never());
+ }
+
+ [Test]
+ public void should_delete_season_if_no_episodes_exist_in_that_season()
+ {
+ GivenAbandonedSeason();
+
+ Subject.Handle(new EpisodeInfoDeletedEvent(_episodes));
+
+ Mocker.GetMock()
+ .Verify(v => v.Delete(It.IsAny()), Times.Once());
+ }
+
+ [Test]
+ public void should_only_delete_a_season_once()
+ {
+ _episodes = Builder
+ .CreateListOfSize(5)
+ .All()
+ .With(e => e.SeasonNumber = _seasons.First().SeasonNumber)
+ .With(s => s.SeriesId = _seasons.First().SeasonNumber)
+ .Build()
+ .ToList();
+
+ GivenAbandonedSeason();
+
+ Subject.Handle(new EpisodeInfoDeletedEvent(_episodes));
+
+ Mocker.GetMock()
+ .Verify(v => v.Delete(It.IsAny()), Times.Once());
+ }
+ }
+}
diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj
index a774cc3fd..9ed55a6ff 100644
--- a/NzbDrone.Core/NzbDrone.Core.csproj
+++ b/NzbDrone.Core/NzbDrone.Core.csproj
@@ -350,6 +350,7 @@
+
diff --git a/NzbDrone.Core/Tv/Events/EpisodeInfoDeletedEvent.cs b/NzbDrone.Core/Tv/Events/EpisodeInfoDeletedEvent.cs
new file mode 100644
index 000000000..864445e58
--- /dev/null
+++ b/NzbDrone.Core/Tv/Events/EpisodeInfoDeletedEvent.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using NzbDrone.Common.Messaging;
+
+namespace NzbDrone.Core.Tv.Events
+{
+ public class EpisodeInfoDeletedEvent : IEvent
+ {
+ public ReadOnlyCollection Episodes { get; private set; }
+
+ public EpisodeInfoDeletedEvent(IList episodes)
+ {
+ Episodes = new ReadOnlyCollection(episodes);
+ }
+ }
+}
\ No newline at end of file
diff --git a/NzbDrone.Core/Tv/RefreshEpisodeService.cs b/NzbDrone.Core/Tv/RefreshEpisodeService.cs
index 14140ba84..c62d8a5d2 100644
--- a/NzbDrone.Core/Tv/RefreshEpisodeService.cs
+++ b/NzbDrone.Core/Tv/RefreshEpisodeService.cs
@@ -34,7 +34,7 @@ namespace NzbDrone.Core.Tv
var successCount = 0;
var failCount = 0;
- var existinEpisodes = _episodeService.GetEpisodeBySeries(series.Id);
+ var existingEpisodes = _episodeService.GetEpisodeBySeries(series.Id);
var seasons = _seasonService.GetSeasonsBySeries(series.Id);
var updateList = new List();
@@ -44,11 +44,11 @@ namespace NzbDrone.Core.Tv
{
try
{
- var episodeToUpdate = existinEpisodes.SingleOrDefault(e => e.SeasonNumber == episode.SeasonNumber && e.EpisodeNumber == episode.EpisodeNumber);
+ var episodeToUpdate = existingEpisodes.SingleOrDefault(e => e.SeasonNumber == episode.SeasonNumber && e.EpisodeNumber == episode.EpisodeNumber);
if (episodeToUpdate != null)
{
- existinEpisodes.Remove(episodeToUpdate);
+ existingEpisodes.Remove(episodeToUpdate);
updateList.Add(episodeToUpdate);
}
else
@@ -82,11 +82,10 @@ namespace NzbDrone.Core.Tv
AdjustMultiEpisodeAirTime(series, allEpisodes);
- _episodeService.DeleteMany(existinEpisodes);
+ _episodeService.DeleteMany(existingEpisodes);
_episodeService.UpdateMany(updateList);
_episodeService.InsertMany(newList);
-
if (newList.Any())
{
_messageAggregator.PublishEvent(new EpisodeInfoAddedEvent(newList, series));
@@ -97,6 +96,11 @@ namespace NzbDrone.Core.Tv
_messageAggregator.PublishEvent(new EpisodeInfoUpdatedEvent(updateList));
}
+ if (existingEpisodes.Any())
+ {
+ _messageAggregator.PublishEvent(new EpisodeInfoDeletedEvent(updateList));
+ }
+
if (failCount != 0)
{
_logger.Info("Finished episode refresh for series: {0}. Successful: {1} - Failed: {2} ",
diff --git a/NzbDrone.Core/Tv/SeasonService.cs b/NzbDrone.Core/Tv/SeasonService.cs
index 8cb3d0c75..6355796a4 100644
Binary files a/NzbDrone.Core/Tv/SeasonService.cs and b/NzbDrone.Core/Tv/SeasonService.cs differ