diff --git a/NzbDrone.Api/NzbDrone.Api.csproj b/NzbDrone.Api/NzbDrone.Api.csproj
index c708953b9..c1453cd26 100644
--- a/NzbDrone.Api/NzbDrone.Api.csproj
+++ b/NzbDrone.Api/NzbDrone.Api.csproj
@@ -125,6 +125,7 @@
+
diff --git a/NzbDrone.Api/Seasons/SeasonModule.cs b/NzbDrone.Api/Seasons/SeasonModule.cs
new file mode 100644
index 000000000..62b69e2fa
--- /dev/null
+++ b/NzbDrone.Api/Seasons/SeasonModule.cs
@@ -0,0 +1,29 @@
+using System.Linq;
+using Nancy;
+using NzbDrone.Api.Extensions;
+using NzbDrone.Core.Tv;
+
+namespace NzbDrone.Api.Seasons
+{
+ public class SeasonModule : NzbDroneApiModule
+ {
+ private readonly ISeasonService _seasonService;
+
+ public SeasonModule(ISeasonService seasonService)
+ : base("/Season")
+ {
+ _seasonService = seasonService;
+
+ Get["/"] = x => GetSeasons();
+ }
+
+ private Response GetSeasons()
+ {
+ var seriesId = Request.Query.SeriesId;
+
+ return JsonExtensions.AsResponse(_seasonService.GetSeasonsBySeries(seriesId));
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/NzbDrone.Backbone/NzbDrone.Backbone.csproj b/NzbDrone.Backbone/NzbDrone.Backbone.csproj
index e836b6915..c46f1fb9e 100644
--- a/NzbDrone.Backbone/NzbDrone.Backbone.csproj
+++ b/NzbDrone.Backbone/NzbDrone.Backbone.csproj
@@ -122,10 +122,14 @@
+
+
+
-
-
+
+
+
diff --git a/NzbDrone.Backbone/Series/Details/SeasonCollection.js b/NzbDrone.Backbone/Series/Details/SeasonCollection.js
index 64f998157..848ccfa84 100644
--- a/NzbDrone.Backbone/Series/Details/SeasonCollection.js
+++ b/NzbDrone.Backbone/Series/Details/SeasonCollection.js
@@ -1,5 +1,6 @@
define(['app','Series/Details/SeasonModel'], function () {
NzbDrone.Series.Details.SeasonCollection = Backbone.Collection.extend({
- url: NzbDrone.Constants.ApiRoot + '/season'
+ url: NzbDrone.Constants.ApiRoot + '/season',
+ model: NzbDrone.Series.Details.SeasonModel
});
});
diff --git a/NzbDrone.Backbone/Series/Details/SeasonCompositeTemplate.html b/NzbDrone.Backbone/Series/Details/SeasonCompositeTemplate.html
index cc6edfb31..a42dcd314 100644
--- a/NzbDrone.Backbone/Series/Details/SeasonCompositeTemplate.html
+++ b/NzbDrone.Backbone/Series/Details/SeasonCompositeTemplate.html
@@ -1,4 +1,4 @@
-
Season {{seasonNumber}}
+{{seasonTitle}}
diff --git a/NzbDrone.Backbone/Series/Details/SeasonCompositeView.js b/NzbDrone.Backbone/Series/Details/SeasonCompositeView.js
index 89ca91e5d..074c26dba 100644
--- a/NzbDrone.Backbone/Series/Details/SeasonCompositeView.js
+++ b/NzbDrone.Backbone/Series/Details/SeasonCompositeView.js
@@ -6,9 +6,7 @@ define(['app', 'Series/Details/EpisodeItemView'], function () {
template: 'Series/Details/SeasonCompositeTemplate',
initialize: function() {
- var episodes = this.model.get('episodes');
- var test = 1;
- //this.collection
+
}
});
});
\ No newline at end of file
diff --git a/NzbDrone.Backbone/Series/Details/SeasonModel.js b/NzbDrone.Backbone/Series/Details/SeasonModel.js
index 579e20d9e..cde835c86 100644
--- a/NzbDrone.Backbone/Series/Details/SeasonModel.js
+++ b/NzbDrone.Backbone/Series/Details/SeasonModel.js
@@ -1,4 +1,21 @@
-define(['app', 'Series/Details/SeasonCollection'], function (app) {
+define(['app'], function () {
NzbDrone.Series.Details.SeasonModel = Backbone.Model.extend({
+
+ mutators: {
+ seasonTitle: function () {
+ var seasonNumber = this.get('seasonNumber');
+
+ if (seasonNumber === 0) {
+ return "Specials"
+ }
+
+ return "Season " + seasonNumber;
+ }
+ },
+
+ defaults: {
+ seasonNumber: 0
+ }
});
-});
\ No newline at end of file
+});
+
diff --git a/NzbDrone.Backbone/Series/Details/SeriesDetailsTemplate.html b/NzbDrone.Backbone/Series/Details/SeriesDetailsTemplate.html
index 0bd52c335..d073f2002 100644
--- a/NzbDrone.Backbone/Series/Details/SeriesDetailsTemplate.html
+++ b/NzbDrone.Backbone/Series/Details/SeriesDetailsTemplate.html
@@ -1,4 +1,6 @@
\ No newline at end of file
diff --git a/NzbDrone.Backbone/Series/Details/SeriesDetailsView.js b/NzbDrone.Backbone/Series/Details/SeriesDetailsView.js
index 63dc955c0..da43e8029 100644
--- a/NzbDrone.Backbone/Series/Details/SeriesDetailsView.js
+++ b/NzbDrone.Backbone/Series/Details/SeriesDetailsView.js
@@ -1,4 +1,4 @@
-define(['app', 'Quality/QualityProfileCollection', 'Series/Details/SeasonCompositeView'], function () {
+define(['app', 'Quality/QualityProfileCollection', 'Series/Details/SeasonCompositeView', 'Series/Details/SeasonCollection'], function () {
NzbDrone.Series.Details.SeriesDetailsView = Backbone.Marionette.CompositeView.extend({
itemView: NzbDrone.Series.Details.SeasonCompositeView,
@@ -6,6 +6,8 @@ define(['app', 'Quality/QualityProfileCollection', 'Series/Details/SeasonComposi
template: 'Series/Details/SeriesDetailsTemplate',
initialize: function () {
+ this.collection = new NzbDrone.Series.Details.SeasonCollection();
+ this.collection.fetch({data: { seriesId: this.model.get('id') }});
}
});
});
\ No newline at end of file
diff --git a/NzbDrone.Common.Test/EventingTests/EventAggregatorTests.cs b/NzbDrone.Common.Test/EventingTests/EventAggregatorTests.cs
index 2f2f19058..d064b635d 100644
--- a/NzbDrone.Common.Test/EventingTests/EventAggregatorTests.cs
+++ b/NzbDrone.Common.Test/EventingTests/EventAggregatorTests.cs
@@ -17,7 +17,7 @@ namespace NzbDrone.Common.Test.EventingTests
var intHandler = new Mock>();
- var aggregator = new EventAggregator(TestLogger, new List { intHandler.Object });
+ var aggregator = new EventAggregator(TestLogger, () => new List { intHandler.Object });
aggregator.Publish(eventA);
intHandler.Verify(c => c.Handle(eventA), Times.Once());
@@ -30,7 +30,7 @@ namespace NzbDrone.Common.Test.EventingTests
var intHandler1 = new Mock>();
var intHandler2 = new Mock>();
- var aggregator = new EventAggregator(TestLogger, new List { intHandler1.Object, intHandler2.Object });
+ var aggregator = new EventAggregator(TestLogger, () => new List { intHandler1.Object, intHandler2.Object });
aggregator.Publish(eventA);
intHandler1.Verify(c => c.Handle(eventA), Times.Once());
@@ -44,7 +44,7 @@ namespace NzbDrone.Common.Test.EventingTests
var aHandler = new Mock>();
var bHandler = new Mock>();
- var aggregator = new EventAggregator(TestLogger, new List { aHandler.Object, bHandler.Object });
+ var aggregator = new EventAggregator(TestLogger, () => new List { aHandler.Object, bHandler.Object });
aggregator.Publish(eventA);
diff --git a/NzbDrone.Common/Eventing/EventAggregator.cs b/NzbDrone.Common/Eventing/EventAggregator.cs
index 78fe8c0ad..86d6c901f 100644
--- a/NzbDrone.Common/Eventing/EventAggregator.cs
+++ b/NzbDrone.Common/Eventing/EventAggregator.cs
@@ -1,18 +1,17 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Linq;
using NLog;
-using NzbDrone.Common.EnsureThat;
namespace NzbDrone.Common.Eventing
{
public class EventAggregator : IEventAggregator
{
private readonly Logger _logger;
- private readonly IEnumerable _handlers;
+ private readonly Func> _handlers;
- public EventAggregator(Logger logger, IEnumerable handlers)
+ public EventAggregator(Logger logger, Func> handlers)
{
- Ensure.That(() => handlers).HasItems();
_logger = logger;
_handlers = handlers;
}
@@ -21,7 +20,7 @@ namespace NzbDrone.Common.Eventing
{
_logger.Trace("Publishing {0}", message.GetType().Name);
- foreach (var handler in _handlers.OfType>())
+ foreach (var handler in _handlers().OfType>())
{
_logger.Trace("{0} => {1}", message.GetType().Name, handler.GetType().Name);
handler.Handle(message);
diff --git a/NzbDrone.Common/Eventing/IEventAggregator.cs b/NzbDrone.Common/Eventing/IEventAggregator.cs
index a1369565a..05ca2eba1 100644
--- a/NzbDrone.Common/Eventing/IEventAggregator.cs
+++ b/NzbDrone.Common/Eventing/IEventAggregator.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Linq;
namespace NzbDrone.Common.Eventing
diff --git a/NzbDrone.Core/ContainerExtentions.cs b/NzbDrone.Core/ContainerExtentions.cs
index 467c93ae4..66b130e85 100644
--- a/NzbDrone.Core/ContainerExtentions.cs
+++ b/NzbDrone.Core/ContainerExtentions.cs
@@ -1,10 +1,12 @@
-using System.IO;
+using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Reflection;
using Autofac;
using Autofac.Core;
using NLog;
using NzbDrone.Common;
+using NzbDrone.Common.Eventing;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.ExternalNotification;
using NzbDrone.Core.Indexers;
@@ -25,6 +27,7 @@ namespace NzbDrone.Core
containerBuilder.InitDatabase();
+
containerBuilder.RegisterModule();
}
diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj
index 096d943c8..05c980c44 100644
--- a/NzbDrone.Core/NzbDrone.Core.csproj
+++ b/NzbDrone.Core/NzbDrone.Core.csproj
@@ -261,6 +261,8 @@
+
+
diff --git a/NzbDrone.Core/Tv/EpisodeService.cs b/NzbDrone.Core/Tv/EpisodeService.cs
index 00ee934e0..06167de0a 100644
--- a/NzbDrone.Core/Tv/EpisodeService.cs
+++ b/NzbDrone.Core/Tv/EpisodeService.cs
@@ -7,6 +7,7 @@ using NzbDrone.Core.Datastore;
using NzbDrone.Core.Download;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
+using NzbDrone.Core.Tv.Events;
namespace NzbDrone.Core.Tv
{
@@ -41,12 +42,14 @@ namespace NzbDrone.Core.Tv
private readonly TvDbProvider _tvDbProvider;
private readonly ISeasonRepository _seasonRepository;
private readonly IEpisodeRepository _episodeRepository;
+ private readonly IEventAggregator _eventAggregator;
- public EpisodeService(TvDbProvider tvDbProviderProvider, ISeasonRepository seasonRepository, IEpisodeRepository episodeRepository)
+ public EpisodeService(TvDbProvider tvDbProviderProvider, ISeasonRepository seasonRepository, IEpisodeRepository episodeRepository, IEventAggregator eventAggregator)
{
_tvDbProvider = tvDbProviderProvider;
_seasonRepository = seasonRepository;
_episodeRepository = episodeRepository;
+ _eventAggregator = eventAggregator;
}
public void AddEpisode(Episode episode)
@@ -240,7 +243,7 @@ namespace NzbDrone.Core.Tv
episodeToUpdate.Overview = episode.Overview;
episodeToUpdate.AirDate = episode.AirDate;
- if(!String.IsNullOrWhiteSpace(series.AirTime) && episodeToUpdate.AirDate.HasValue)
+ if (!String.IsNullOrWhiteSpace(series.AirTime) && episodeToUpdate.AirDate.HasValue)
{
episodeToUpdate.AirDate = episodeToUpdate.AirDate.Value.Add(Convert.ToDateTime(series.AirTime).TimeOfDay)
.AddHours(series.UtcOffset * -1);
@@ -258,6 +261,16 @@ namespace NzbDrone.Core.Tv
_episodeRepository.InsertMany(newList);
_episodeRepository.UpdateMany(updateList);
+ if (newList.Any())
+ {
+ _eventAggregator.Publish(new EpisodeInfoAddedEvent(newList));
+ }
+
+ if (updateList.Any())
+ {
+ _eventAggregator.Publish(new EpisodeInfoUpdatedEvent(updateList));
+ }
+
if (failCount != 0)
{
logger.Info("Finished episode refresh for series: {0}. Successful: {1} - Failed: {2} ",
diff --git a/NzbDrone.Core/Tv/Events/EpisodeInfoAddedEvent.cs b/NzbDrone.Core/Tv/Events/EpisodeInfoAddedEvent.cs
new file mode 100644
index 000000000..36b52ca8c
--- /dev/null
+++ b/NzbDrone.Core/Tv/Events/EpisodeInfoAddedEvent.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using NzbDrone.Common.Eventing;
+
+namespace NzbDrone.Core.Tv.Events
+{
+ public class EpisodeInfoAddedEvent : IEvent
+ {
+ public ReadOnlyCollection Episodes { get; private set; }
+
+ public EpisodeInfoAddedEvent(IList episodes)
+ {
+ Episodes = new ReadOnlyCollection(episodes);
+ }
+ }
+}
\ No newline at end of file
diff --git a/NzbDrone.Core/Tv/Events/EpisodeInfoUpdatedEvent.cs b/NzbDrone.Core/Tv/Events/EpisodeInfoUpdatedEvent.cs
new file mode 100644
index 000000000..fe2df05de
--- /dev/null
+++ b/NzbDrone.Core/Tv/Events/EpisodeInfoUpdatedEvent.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using NzbDrone.Common.Eventing;
+
+namespace NzbDrone.Core.Tv.Events
+{
+ public class EpisodeInfoUpdatedEvent : IEvent
+ {
+ public ReadOnlyCollection Episodes { get; private set; }
+
+ public EpisodeInfoUpdatedEvent(IList episodes)
+ {
+ Episodes = new ReadOnlyCollection(episodes);
+ }
+ }
+}
\ No newline at end of file
diff --git a/NzbDrone.Core/Tv/SeasonService.cs b/NzbDrone.Core/Tv/SeasonService.cs
index 7f85bfc15..d26c035a0 100644
Binary files a/NzbDrone.Core/Tv/SeasonService.cs and b/NzbDrone.Core/Tv/SeasonService.cs differ