this should cover it!

This commit is contained in:
Keivan Beigi 2013-09-11 17:42:15 -07:00
parent 7f5136120d
commit c090b3efa1
15 changed files with 166 additions and 331 deletions

View File

@ -5,6 +5,14 @@ namespace NzbDrone.Core.Notifications.Email
{
public class TestEmailCommand : Command
{
public override bool SendUpdatesToClient
{
get
{
return true;
}
}
public string Server { get; set; }
public int Port { get; set; }
public bool Ssl { get; set; }

View File

@ -7,6 +7,13 @@ namespace NzbDrone.Core.Notifications.Growl
{
public class TestGrowlCommand : Command
{
public override bool SendUpdatesToClient
{
get
{
return true;
}
}
public string Host { get; set; }
public int Port { get; set; }
public string Password { get; set; }

View File

@ -7,6 +7,13 @@ namespace NzbDrone.Core.Notifications.Plex
{
public class TestPlexClientCommand : Command
{
public override bool SendUpdatesToClient
{
get
{
return true;
}
}
public string Host { get; set; }
public int Port { get; set; }
public string Username { get; set; }

View File

@ -7,6 +7,14 @@ namespace NzbDrone.Core.Notifications.Plex
{
public class TestPlexServerCommand : Command
{
public override bool SendUpdatesToClient
{
get
{
return true;
}
}
public string Host { get; set; }
public int Port { get; set; }
}

View File

@ -7,6 +7,13 @@ namespace NzbDrone.Core.Notifications.Prowl
{
public class TestProwlCommand : Command
{
public override bool SendUpdatesToClient
{
get
{
return true;
}
}
public string ApiKey { get; set; }
public int Priority { get; set; }
}

View File

@ -7,6 +7,14 @@ namespace NzbDrone.Core.Notifications.Pushover
{
public class TestPushoverCommand : Command
{
public override bool SendUpdatesToClient
{
get
{
return true;
}
}
public string UserKey { get; set; }
public int Priority { get; set; }
}

View File

@ -7,6 +7,14 @@ namespace NzbDrone.Core.Notifications.Xbmc
{
public class TestXbmcCommand : Command
{
public override bool SendUpdatesToClient
{
get
{
return true;
}
}
public string Host { get; set; }
public int Port { get; set; }
public string Username { get; set; }

View File

@ -3,10 +3,12 @@ define(
[
'Commands/CommandModel',
'Commands/CommandCollection',
'underscore'
'underscore',
'jQuery/jquery.spin'
], function (CommandModel, CommandCollection, _) {
return{
Execute: function (name, properties) {
var attr = _.extend({name: name.toLocaleLowerCase()}, properties);
@ -16,6 +18,39 @@ define(
return commandModel.save().success(function () {
CommandCollection.add(commandModel);
});
},
bindToCommand: function (options) {
var self = this;
var existingCommand = CommandCollection.findCommand(options.command);
if (existingCommand) {
this._bindToCommandModel.call(this, existingCommand, options);
}
CommandCollection.bind('add sync', function (model) {
if (model.isSameCommand(options.command)) {
self._bindToCommandModel.call(self, model, options);
}
});
},
_bindToCommandModel: function bindToCommand(model, options) {
if (!model.isActive()) {
options.element.stopSpin();
return;
}
model.bind('change:state', function (model) {
if (!model.isActive()) {
options.element.stopSpin();
}
});
options.element.startSpin();
}
}
});

View File

@ -7,11 +7,10 @@ require(
'Series/SeriesCollection',
'ProgressMessaging/ProgressMessageCollection',
'Commands/CommandMessengerCollectionView',
'Shared/Actioneer',
'Navbar/NavbarView',
'jQuery/RouteBinder',
'jquery'
], function (App, Marionette, Controller, SeriesCollection, ProgressMessageCollection, CommandMessengerCollectionView, Actioneer, NavbarView, RouterBinder, $) {
], function (App, Marionette, Controller, SeriesCollection, ProgressMessageCollection, CommandMessengerCollectionView, NavbarView, RouterBinder, $) {
var Router = Marionette.AppRouter.extend({

View File

@ -2,9 +2,9 @@
define(
[
'marionette',
'Series/SeasonCollection',
'Cells/ToggleCell'
], function (Marionette, Backgrid, SeasonCollection, ToggleCell) {
'backgrid',
'Series/SeasonCollection'
], function (Marionette, Backgrid, SeasonCollection) {
return Marionette.Layout.extend({
template: 'SeasonPass/SeriesLayoutTemplate',
@ -111,11 +111,9 @@ define(
this.model.setSeasonMonitored(seasonNumber);
Actioneer.SaveModel({
element: element,
context: this,
always : this._afterToggleSeasonMonitored
});
var savePromise =this.model.save()
.always(this.render.bind(this));
element.spinForPromise(savePromise);
},
_afterToggleSeasonMonitored: function () {

View File

@ -8,9 +8,9 @@ define(
'Cells/EpisodeTitleCell',
'Cells/RelativeDateCell',
'Cells/EpisodeStatusCell',
'Shared/Actioneer',
'Commands/CommandController',
'moment'
], function (App, Marionette, Backgrid, ToggleCell, EpisodeTitleCell, RelativeDateCell, EpisodeStatusCell, Actioneer, Moment) {
], function (App, Marionette, Backgrid, ToggleCell, EpisodeTitleCell, RelativeDateCell, EpisodeStatusCell, CommandController, Moment) {
return Marionette.Layout.extend({
template: 'Series/Details/SeasonLayoutTemplate',
@ -21,11 +21,11 @@ define(
},
events: {
'click .x-season-search' : '_seasonSearch',
'click .x-season-monitored' : '_seasonMonitored',
'click .x-season-rename' : '_seasonRename',
'click .x-show-hide-episodes' : '_showHideEpisodes',
'dblclick .series-season h2' : '_showHideEpisodes'
'click .x-season-monitored' : '_seasonMonitored',
'click .x-season-search' : '_seasonSearch',
'click .x-season-rename' : '_seasonRename',
'click .x-show-hide-episodes': '_showHideEpisodes',
'dblclick .series-season h2' : '_showHideEpisodes'
},
regions: {
@ -51,11 +51,11 @@ define(
})
},
{
name : 'this',
label : 'Title',
hideSeriesLink : true,
cell : EpisodeTitleCell,
sortable: false
name : 'this',
label : 'Title',
hideSeriesLink: true,
cell : EpisodeTitleCell,
sortable : false
},
{
name : 'airDateUtc',
@ -75,42 +75,60 @@ define(
if (!options.episodeCollection) {
throw 'episodeCollection is needed';
}
this.templateHelpers = {};
this.templateHelpers = this.templateHelpers || {};
this.episodeCollection = options.episodeCollection.bySeason(this.model.get('seasonNumber'));
this.series = options.series;
this.showingEpisodes = this._shouldShowEpisodes();
this._generateTemplateHelpers();
this.listenTo(this.model, 'sync', function () {
this._afterSeasonMonitored();
}, this);
this.listenTo(this.episodeCollection, 'sync', function () {
this.render();
}, this);
this.listenTo(this.model, 'sync', this._afterSeasonMonitored);
this.listenTo(this.episodeCollection, 'sync', this.render);
},
onRender: function () {
this._generateTemplateHelpers();
if (this.showingEpisodes) {
this._showEpisodes();
}
this._setSeasonMonitoredState();
CommandController.bindToCommand({
element: this.ui.seasonSearch,
command: {
name: 'seasonSearch',
seriesId : this.series.id,
seasonNumber: this.model.get('seasonNumber')
}
});
CommandController.bindToCommand({
element: this.ui.seasonRename,
command: {
name: 'renameSeason',
seriesId : this.series.id,
seasonNumber: this.model.get('seasonNumber')
}
});
},
_seasonSearch: function () {
Actioneer.ExecuteCommand({
command : 'seasonSearch',
properties : {
seriesId : this.model.get('seriesId'),
seasonNumber: this.model.get('seasonNumber')
},
element : this.ui.seasonSearch,
errorMessage : 'Search for season {0} failed'.format(this.model.get('seasonNumber')),
startMessage : 'Search for season {0} started'.format(this.model.get('seasonNumber')),
successMessage: 'Search for season {0} completed'.format(this.model.get('seasonNumber'))
CommandController.Execute('seasonSearch', {
name: 'seasonSearch',
seriesId : this.series.id,
seasonNumber: this.model.get('seasonNumber')
});
},
_seasonRename: function () {
CommandController.Execute('renameSeason', {
name: 'renameSeason',
seriesId : this.series.id,
seasonNumber: this.model.get('seasonNumber')
});
},
@ -119,12 +137,10 @@ define(
this.model.set(name, !this.model.get(name));
this.series.setSeasonMonitored(this.model.get('seasonNumber'));
Actioneer.SaveModel({
model : this.series,
context: this,
element: this.ui.seasonMonitored,
always : this._afterSeasonMonitored
});
var savePromise = this.series.save()
.always(this._afterSeasonMonitored.bind(this));
this.ui.seasonMonitored.spinForPromise(savePromise);
},
_afterSeasonMonitored: function () {
@ -150,19 +166,7 @@ define(
}
},
_seasonRename: function () {
Actioneer.ExecuteCommand({
command : 'renameSeason',
properties : {
seriesId : this.model.get('seriesId'),
seasonNumber: this.model.get('seasonNumber')
},
element : this.ui.seasonRename,
errorMessage: 'Season rename failed',
context : this,
onSuccess : this._afterRename
});
},
_afterRename: function () {
App.vent.trigger(App.Events.SeasonRenamed, { series: this.series, seasonNumber: this.model.get('seasonNumber') });
@ -180,12 +184,11 @@ define(
var startDate = Moment().add('month', -1);
var endDate = Moment().add('year', 1);
var result = this.episodeCollection.some(function(episode) {
var result = this.episodeCollection.some(function (episode) {
var airDate = episode.get('airDateUtc');
if (airDate)
{
if (airDate) {
var airDateMoment = Moment(airDate);
if (airDateMoment.isAfter(startDate) && airDateMoment.isBefore(endDate)) {
@ -203,7 +206,7 @@ define(
this.templateHelpers.showingEpisodes = this.showingEpisodes;
var episodeCount = this.episodeCollection.filter(function (episode) {
return (episode.get('monitored') && Moment(episode.get('airDateUtc')).isBefore(Moment())) || episode.get('hasFile');
return (episode.get('monitored') && Moment(episode.get('airDateUtc')).isBefore(Moment())) || episode.get('hasFile');
}).length;
var episodeFileCount = this.episodeCollection.where({ hasFile: true }).length;
@ -221,14 +224,11 @@ define(
_showHideEpisodes: function () {
if (this.showingEpisodes) {
this.showingEpisodes = false;
this.episodeGrid.$el.slideUp();
this.episodeGrid.close();
}
else {
this.showingEpisodes = true;
this._showEpisodes();
this.episodeGrid.$el.slideDown();
}
this.templateHelpers.showingEpisodes = this.showingEpisodes;

View File

@ -10,10 +10,9 @@ define(
'Series/Details/InfoView',
'Commands/CommandController',
'Shared/LoadingView',
'Shared/Actioneer',
'backstrech',
'Mixins/backbone.signalr.mixin'
], function (App, Marionette, EpisodeCollection, EpisodeFileCollection, SeasonCollection, SeasonCollectionView, InfoView, CommandController, LoadingView, Actioneer) {
], function (App, Marionette, EpisodeCollection, EpisodeFileCollection, SeasonCollection, SeasonCollectionView, InfoView, CommandController, LoadingView) {
return Marionette.Layout.extend({
itemViewContainer: '.x-series-seasons',
@ -67,21 +66,21 @@ define(
},
onRender: function () {
Actioneer.bindToCommand({
CommandController.bindToCommand({
element: this.ui.refresh,
command: {
name: 'refreshSeries'
}
});
Actioneer.bindToCommand({
CommandController.bindToCommand({
element: this.ui.search,
command: {
name: 'seriesSearch'
}
});
Actioneer.bindToCommand({
CommandController.bindToCommand({
element: this.ui.rename,
command: {
name: 'renameSeries'
@ -195,13 +194,9 @@ define(
this.info.show(new InfoView({ model: this.model }));
},
_refetchEpisodeFiles: function () {
this.episodeFileCollection.fetch();
},
_onSeasonRenamed: function (event) {
if (this.model.get('id') === event.series.get('id')) {
this._refetchEpisodeFiles();
this.episodeFileCollection.fetch();
}
}
});

View File

@ -6,11 +6,11 @@ define([
'Settings/Notifications/Model',
'Settings/Notifications/DeleteView',
'Shared/Messenger',
'Shared/Actioneer',
'Commands/CommandController',
'Mixins/AsModelBoundView',
'Form/FormBuilder'
], function (App, Marionette, NotificationModel, DeleteView, Messenger, Actioneer, AsModelBoundView) {
], function (App, Marionette, NotificationModel, DeleteView, Messenger, CommandController, AsModelBoundView) {
var model = Marionette.ItemView.extend({
template: 'Settings/Notifications/EditTemplate',
@ -76,16 +76,8 @@ define([
properties[field.name] = field.value;
});
Actioneer.ExecuteCommand({
command : testCommand,
properties : properties,
button : this.ui.testButton,
element : this.ui.testIcon,
errorMessage : 'Failed to test notification settings',
successMessage: 'Notification settings tested successfully',
always : this._testOnAlways,
context : this
});
CommandController.Execute(testCommand, properties);
}
},

View File

@ -1,236 +0,0 @@
'use strict';
define(
[
'Commands/CommandController',
'Commands/CommandCollection',
'Shared/Messenger',
'jQuery/jquery.spin'
], function (CommandController, CommandCollection, Messenger) {
var actioneer = Marionette.AppRouter.extend({
initialize: function () {
this.trackedCommands =
[
];
CommandCollection.fetch();
this.listenTo(CommandCollection, 'sync', this._handleCommands);
},
bindToCommand: function (options) {
var self = this;
options.idleIcon = this._getIconClass(options.element);
var existingCommand = CommandCollection.findCommand(options.command);
if (existingCommand) {
this._bindToCommandModel.call(this, existingCommand, options);
}
this.listenTo(CommandCollection, 'add sync', function (model) {
if (model.isSameCommand(options.command)) {
self._bindToCommandModel.call(self, model, options);
}
});
},
_bindToCommandModel: function bindToCommand(model, options) {
if (!model.isActive()) {
options.element.stopSpin();
return;
}
this.listenTo(model, 'change:state', function (model) {
if (!model.isActive()) {
options.element.stopSpin();
}
});
options.element.startSpin();
},
ExecuteCommand: function (options) {
options.iconClass = this._getIconClass(options.element);
if (options.button) {
options.button.addClass('disable');
}
this._setSpinnerOnElement(options);
var promise = CommandController.Execute(options.command, options.properties);
this._showStartMessage(options, promise);
},
SaveModel: function (options) {
options.iconClass = this._getIconClass(options.element);
this._showStartMessage(options);
this._setSpinnerOnElement(options);
var model = options.model ? options.model : options.context.model;
var promise = model.save();
this._handlePromise(promise, options);
},
_handlePromise: function (promise, options) {
var self = this;
promise.done(function () {
self._onSuccess(options);
});
promise.fail(function (ajaxOptions) {
if (ajaxOptions.readyState === 0 || ajaxOptions.status === 0) {
return;
}
self._onError(options);
});
promise.always(function () {
self._onComplete(options);
});
},
_handleCommands: function () {
var self = this;
_.each(this.trackedCommands, function (trackedCommand) {
if (trackedCommand.completed === true) {
return;
}
var options = trackedCommand.options;
var command = CommandCollection.find({ 'id': trackedCommand.id });
if (!command) {
trackedCommand.completed = true;
self._onError(options, trackedCommand.id);
self._onComplete(options);
return;
}
if (command.get('state') === 'completed') {
trackedCommand.completed = true;
self._onSuccess(options, command.get('id'));
self._onComplete(options);
return;
}
if (command.get('state') === 'failed') {
trackedCommand.completed = true;
self._onError(options, command.get('id'));
self._onComplete(options);
}
});
},
_getIconClass: function (element) {
if (!element) {
return '';
}
return element.find('i').attr('class').match(/(?:^|\s)icon\-.+?(?:$|\s)/)[0];
},
_setSpinnerOnElement: function (options) {
if (!options.element) {
return;
}
if (options.leaveIcon) {
options.element.addClass('icon-spin');
}
else {
options.element.removeClass(options.iconClass);
options.element.addClass('icon-nd-spinner');
}
},
_onSuccess: function (options, id) {
if (options.successMessage) {
Messenger.show({
id : id,
message: options.successMessage,
type : 'success'
});
}
if (options.onSuccess) {
options.onSuccess.call(options.context);
}
},
_onError: function (options, id) {
if (options.errorMessage) {
Messenger.show({
id : id,
message: options.errorMessage,
type : 'error'
});
}
if (options.onError) {
options.onError.call(options.context);
}
},
_onComplete: function (options) {
if (options.button) {
options.button.removeClass('disable');
}
if (options.element) {
if (options.leaveIcon) {
options.element.removeClass('icon-spin');
}
else {
options.element.addClass(options.iconClass);
options.element.removeClass('icon-nd-spinner');
options.element.removeClass('icon-spin');
}
}
if (options.always) {
options.always.call(options.context);
}
},
_showStartMessage: function (options, promise) {
var self = this;
if (!promise) {
if (options.startMessage) {
Messenger.show({
message: options.startMessage
});
}
return;
}
promise.done(function (data) {
self.trackedCommands.push({ id: data.id, options: options });
if (options.startMessage) {
Messenger.show({
id : data.id,
message: options.startMessage
});
}
});
}
});
return new actioneer();
});

View File

@ -3,9 +3,8 @@ define(
[
'app',
'marionette',
'Commands/CommandController',
'Shared/Actioneer'
], function (App, Marionette, CommandController, Actioneer) {
'Commands/CommandController'
], function (App, Marionette, CommandController) {
return Marionette.ItemView.extend({
template : 'Shared/Toolbar/ButtonTemplate',
@ -31,7 +30,7 @@ define(
var command = this.model.get('command');
if (command) {
Actioneer.bindToCommand({
CommandController.bindToCommand({
command: {name: command},
element: this.$el
});