diff --git a/NzbDrone.Api/Settings/SettingsModule.cs b/NzbDrone.Api/Settings/SettingsModule.cs
index e42251347..285b27acc 100644
--- a/NzbDrone.Api/Settings/SettingsModule.cs
+++ b/NzbDrone.Api/Settings/SettingsModule.cs
@@ -1,4 +1,6 @@
-using System.Linq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
using Nancy;
using NzbDrone.Api.Extensions;
using NzbDrone.Core.Configuration;
@@ -18,8 +20,12 @@ namespace NzbDrone.Api.Settings
private Response GetAllSettings()
{
- var settings = _configService.All();
- return settings.AsResponse();
+ var collection = Request.Query.Collection;
+
+ if(collection.HasValue && Boolean.Parse(collection.Value))
+ return _configService.All().AsResponse();
+
+ return _configService.All().ToDictionary(c => c.Key, c => c.Value).AsResponse();
}
}
}
\ No newline at end of file
diff --git a/NzbDrone.Backbone/Controller.js b/NzbDrone.Backbone/Controller.js
index 164d0233a..ec7cfbf73 100644
--- a/NzbDrone.Backbone/Controller.js
+++ b/NzbDrone.Backbone/Controller.js
@@ -3,6 +3,7 @@
'Calendar/CalendarCollectionView', 'Shared/NotificationView',
'Shared/NotFoundView', 'MainMenuView', 'HeaderView',
'Series/Details/SeriesDetailsView', 'Series/EpisodeCollection'],
+ 'Settings/SettingsLayout'],
function (app, modalRegion) {
var controller = Backbone.Marionette.Controller.extend({
@@ -42,6 +43,17 @@
});
},
+ settings: function(action, query) {
+ this.setTitle('Settings');
+
+ var settingsModel = new NzbDrone.Settings.SettingsModel();
+ settingsModel.fetch({
+ success: function(settings){
+ NzbDrone.mainRegion.show(new NzbDrone.Settings.SettingsLayout(this, action, query, settings));
+ }
+ });
+ },
+
notFound: function () {
this.setTitle('Not Found');
NzbDrone.mainRegion.show(new NzbDrone.Shared.NotFoundView(this));
diff --git a/NzbDrone.Backbone/NzbDrone.Backbone.csproj b/NzbDrone.Backbone/NzbDrone.Backbone.csproj
index 10d427023..9053e7d92 100644
--- a/NzbDrone.Backbone/NzbDrone.Backbone.csproj
+++ b/NzbDrone.Backbone/NzbDrone.Backbone.csproj
@@ -147,7 +147,7 @@
-
+
diff --git a/NzbDrone.Backbone/Routing.js b/NzbDrone.Backbone/Routing.js
index 6d8820e92..b29cc4e29 100644
--- a/NzbDrone.Backbone/Routing.js
+++ b/NzbDrone.Backbone/Routing.js
@@ -13,6 +13,8 @@
'upcoming': 'upcoming',
'upcoming/index': 'upcoming',
'calendar': 'calendar',
+ 'settings': 'settings',
+ 'settings/:action(/:query)': 'settings',
':whatever': 'notFound'
}
});
diff --git a/NzbDrone.Backbone/Settings/DownloadClient/DownloadClientTemplate.html b/NzbDrone.Backbone/Settings/DownloadClient/DownloadClientTemplate.html
new file mode 100644
index 000000000..86ac9ebf4
--- /dev/null
+++ b/NzbDrone.Backbone/Settings/DownloadClient/DownloadClientTemplate.html
@@ -0,0 +1,3 @@
+
+ Download Client settings will go here
+
\ No newline at end of file
diff --git a/NzbDrone.Backbone/Settings/DownloadClient/DownloadClientView.js b/NzbDrone.Backbone/Settings/DownloadClient/DownloadClientView.js
new file mode 100644
index 000000000..b062adcb2
--- /dev/null
+++ b/NzbDrone.Backbone/Settings/DownloadClient/DownloadClientView.js
@@ -0,0 +1,29 @@
+'use strict';
+
+define([
+ 'app', 'Settings/SettingsModel'
+
+], function () {
+
+ NzbDrone.Settings.DownloadClient.DownloadClientView = Backbone.Marionette.ItemView.extend({
+ template: 'Settings/DownloadClient/DownloadClientTemplate',
+
+ events: {
+ 'click .x-save': 'save'
+ },
+
+ initialize: function (options) {
+ this.model = options.model;
+ },
+
+ onRender: function () {
+ NzbDrone.ModelBinder.bind(this.model, this.el);
+ },
+
+
+ save: function () {
+ //Todo: Actually save the model
+ alert('Save pressed!');
+ }
+ });
+});
diff --git a/NzbDrone.Backbone/Settings/Indexers/IndexersTemplate.html b/NzbDrone.Backbone/Settings/Indexers/IndexersTemplate.html
new file mode 100644
index 000000000..70e312099
--- /dev/null
+++ b/NzbDrone.Backbone/Settings/Indexers/IndexersTemplate.html
@@ -0,0 +1,3 @@
+
+ Indexer settings will go here
+
\ No newline at end of file
diff --git a/NzbDrone.Backbone/Settings/Indexers/IndexersView.js b/NzbDrone.Backbone/Settings/Indexers/IndexersView.js
new file mode 100644
index 000000000..18ec24ce4
--- /dev/null
+++ b/NzbDrone.Backbone/Settings/Indexers/IndexersView.js
@@ -0,0 +1,29 @@
+'use strict';
+
+define([
+ 'app', 'Settings/SettingsModel'
+
+], function () {
+
+ NzbDrone.Settings.Indexers.IndexersView = Backbone.Marionette.ItemView.extend({
+ template: 'Settings/Indexers/IndexersTemplate',
+
+ events: {
+ 'click .x-save': 'save'
+ },
+
+ initialize: function (options) {
+ this.model = options.model;
+ },
+
+ onRender: function () {
+ NzbDrone.ModelBinder.bind(this.model, this.el);
+ },
+
+
+ save: function () {
+ //Todo: Actually save the model
+ alert('Save pressed!');
+ }
+ });
+});
diff --git a/NzbDrone.Backbone/Settings/Misc/MiscTemplate.html b/NzbDrone.Backbone/Settings/Misc/MiscTemplate.html
new file mode 100644
index 000000000..d2bf14dfe
--- /dev/null
+++ b/NzbDrone.Backbone/Settings/Misc/MiscTemplate.html
@@ -0,0 +1,3 @@
+
+ Misc settings will go here
+
\ No newline at end of file
diff --git a/NzbDrone.Backbone/Settings/Misc/MiscView.js b/NzbDrone.Backbone/Settings/Misc/MiscView.js
new file mode 100644
index 000000000..c62deaa94
--- /dev/null
+++ b/NzbDrone.Backbone/Settings/Misc/MiscView.js
@@ -0,0 +1,29 @@
+'use strict';
+
+define([
+ 'app', 'Settings/SettingsModel'
+
+], function () {
+
+ NzbDrone.Settings.Misc.MiscView = Backbone.Marionette.ItemView.extend({
+ template: 'Settings/Misc/MiscTemplate',
+
+ events: {
+ 'click .x-save': 'save'
+ },
+
+ initialize: function (options) {
+ this.model = options.model;
+ },
+
+ onRender: function () {
+ NzbDrone.ModelBinder.bind(this.model, this.el);
+ },
+
+
+ save: function () {
+ //Todo: Actually save the model
+ alert('Save pressed!');
+ }
+ });
+});
diff --git a/NzbDrone.Backbone/Settings/Naming/NamingTemplate.html b/NzbDrone.Backbone/Settings/Naming/NamingTemplate.html
new file mode 100644
index 000000000..975a07c6c
--- /dev/null
+++ b/NzbDrone.Backbone/Settings/Naming/NamingTemplate.html
@@ -0,0 +1,4 @@
+
+ Naming settings will go here
+ {{uGuid}}
+
\ No newline at end of file
diff --git a/NzbDrone.Backbone/Settings/Naming/NamingView.js b/NzbDrone.Backbone/Settings/Naming/NamingView.js
new file mode 100644
index 000000000..24e6b7cc4
--- /dev/null
+++ b/NzbDrone.Backbone/Settings/Naming/NamingView.js
@@ -0,0 +1,30 @@
+'use strict';
+
+define([
+ 'app', 'Settings/SettingsModel'
+
+], function () {
+
+ NzbDrone.Settings.Naming.NamingView = Backbone.Marionette.ItemView.extend({
+ template: 'Settings/Naming/NamingTemplate',
+
+ events: {
+ 'click .x-save': 'save'
+ },
+
+ initialize: function (options) {
+ this.model = options.model;
+ var test = 1;
+ },
+
+ onRender: function () {
+ NzbDrone.ModelBinder.bind(this.model, this.el);
+ },
+
+
+ save: function () {
+ //Todo: Actually save the model
+ alert('Save pressed!');
+ }
+ });
+});
diff --git a/NzbDrone.Backbone/Settings/Notifications/NotificationsTemplate.html b/NzbDrone.Backbone/Settings/Notifications/NotificationsTemplate.html
new file mode 100644
index 000000000..49f9be984
--- /dev/null
+++ b/NzbDrone.Backbone/Settings/Notifications/NotificationsTemplate.html
@@ -0,0 +1,3 @@
+
+ Notification settings will go here
+
\ No newline at end of file
diff --git a/NzbDrone.Backbone/Settings/Notifications/NotificationsView.js b/NzbDrone.Backbone/Settings/Notifications/NotificationsView.js
new file mode 100644
index 000000000..a05ace819
--- /dev/null
+++ b/NzbDrone.Backbone/Settings/Notifications/NotificationsView.js
@@ -0,0 +1,29 @@
+'use strict';
+
+define([
+ 'app', 'Settings/SettingsModel'
+
+], function () {
+
+ NzbDrone.Settings.Notifications.NotificationsView = Backbone.Marionette.ItemView.extend({
+ template: 'Settings/Notifications/NotificationsTemplate',
+
+ events: {
+ 'click .x-save': 'save'
+ },
+
+ initialize: function (options) {
+ this.model = options.model;
+ },
+
+ onRender: function () {
+ NzbDrone.ModelBinder.bind(this.model, this.el);
+ },
+
+
+ save: function () {
+ //Todo: Actually save the model
+ alert('Save pressed!');
+ }
+ });
+});
diff --git a/NzbDrone.Backbone/Settings/Quality/QualityTemplate.html b/NzbDrone.Backbone/Settings/Quality/QualityTemplate.html
new file mode 100644
index 000000000..9941dfdb1
--- /dev/null
+++ b/NzbDrone.Backbone/Settings/Quality/QualityTemplate.html
@@ -0,0 +1,3 @@
+
+ Quality settings will go here
+
\ No newline at end of file
diff --git a/NzbDrone.Backbone/Settings/Quality/QualityView.js b/NzbDrone.Backbone/Settings/Quality/QualityView.js
new file mode 100644
index 000000000..8c9c0ad20
--- /dev/null
+++ b/NzbDrone.Backbone/Settings/Quality/QualityView.js
@@ -0,0 +1,29 @@
+'use strict';
+
+define([
+ 'app', 'Settings/SettingsModel'
+
+], function () {
+
+ NzbDrone.Settings.Quality.QualityView = Backbone.Marionette.ItemView.extend({
+ template: 'Settings/Quality/QualityTemplate',
+
+ events: {
+ 'click .x-save': 'save'
+ },
+
+ initialize: function (options) {
+ this.model = options.model;
+ },
+
+ onRender: function () {
+ NzbDrone.ModelBinder.bind(this.model, this.el);
+ },
+
+
+ save: function () {
+ //Todo: Actually save the model
+ alert('Save pressed!');
+ }
+ });
+});
diff --git a/NzbDrone.Backbone/Settings/SettingsLayout.js b/NzbDrone.Backbone/Settings/SettingsLayout.js
new file mode 100644
index 000000000..9b6e31236
--- /dev/null
+++ b/NzbDrone.Backbone/Settings/SettingsLayout.js
@@ -0,0 +1,159 @@
+define([
+ 'app',
+ 'Quality/QualityProfileCollection',
+ 'Settings/Naming/NamingView',
+ 'Settings/Quality/QualityView',
+ 'Settings/Indexers/IndexersView',
+ 'Settings/DownloadClient/DownloadClientView',
+ 'Settings/Notifications/NotificationsView',
+ 'Settings/System/SystemView',
+ 'Settings/Misc/MiscView'
+],
+ function (app, qualityProfileCollection) {
+ NzbDrone.Settings.SettingsLayout = Backbone.Marionette.Layout.extend({
+ template: 'Settings/SettingsLayoutTemplate',
+
+ regions: {
+ naming: '#naming',
+ quality: '#quality',
+ indexers: '#indexers',
+ downloadClient: '#download-client',
+ notifications: '#notifications',
+ system: '#system',
+ misc: '#misc'
+ },
+
+ ui: {
+ namingTab: '.x-naming-tab',
+ qualityTab: '.x-quality-tab',
+ indexersTab: '.x-indexers-tab',
+ downloadClientTab: '.x-download-client-tab',
+ notificationsTab: '.x-notifications-tab',
+ systemTab: '.x-system-tab',
+ miscTab: '.x-misc-tab'
+ },
+
+ events: {
+ 'click .x-naming-tab': 'showNaming',
+ 'click .x-quality-tab': 'showQuality',
+ 'click .x-indexers-tab': 'showIndexers',
+ 'click .x-download-client-tab': 'showDownloadClient',
+ 'click .x-notifications-tab': 'showNotifications',
+ 'click .x-system-tab': 'showSystem',
+ 'click .x-misc-tab': 'showMisc'
+ },
+
+ showNaming: function (e) {
+ if (e) {
+ e.preventDefault();
+ }
+
+ this.ui.namingTab.tab('show');
+ NzbDrone.Router.navigate('settings/naming');
+ },
+
+ showQuality: function (e) {
+ if (e) {
+ e.preventDefault();
+ }
+
+ this.ui.qualityTab.tab('show');
+ NzbDrone.Router.navigate('settings/quality');
+ },
+
+ showIndexers: function (e) {
+ if (e) {
+ e.preventDefault();
+ }
+
+ this.ui.indexersTab.tab('show');
+ NzbDrone.Router.navigate('settings/indexers');
+ },
+
+ showDownloadClient: function (e) {
+ if (e) {
+ e.preventDefault();
+ }
+
+ this.ui.downloadClientTab.tab('show');
+ NzbDrone.Router.navigate('settings/downloadclient');
+ },
+
+ showNotifications: function (e) {
+ if (e) {
+ e.preventDefault();
+ }
+
+ this.ui.notificationsTab.tab('show');
+ NzbDrone.Router.navigate('settings/notifications');
+ },
+
+ showSystem: function (e) {
+ if (e) {
+ e.preventDefault();
+ }
+
+ this.ui.systemTab.tab('show');
+ NzbDrone.Router.navigate('settings/system');
+ },
+
+ showMisc: function (e) {
+ if (e) {
+ e.preventDefault();
+ }
+
+ this.ui.miscTab.tab('show');
+ NzbDrone.Router.navigate('settings/misc');
+ },
+
+ initialize: function (context, action, query, settings) {
+ this.settings = settings;
+
+ if (action) {
+ this.action = action.toLowerCase();
+ }
+
+ if (query) {
+ this.query = query.toLowerCase();
+ }
+ },
+
+ onRender: function () {
+ qualityProfileCollection.fetch();
+
+ this.naming.show(new NzbDrone.Settings.Naming.NamingView({model: this.settings}));
+ this.quality.show(new NzbDrone.Settings.Quality.QualityView({model: this.settings}));
+ this.indexers.show(new NzbDrone.Settings.Indexers.IndexersView({model: this.settings}));
+ this.downloadClient.show(new NzbDrone.Settings.DownloadClient.DownloadClientView({model: this.settings}));
+ this.notifications.show(new NzbDrone.Settings.Notifications.NotificationsView({model: this.settings}));
+ this.system.show(new NzbDrone.Settings.System.SystemView({model: this.settings}));
+ this.misc.show(new NzbDrone.Settings.Misc.MiscView({model: this.settings}));
+ },
+
+ onShow: function () {
+ switch (this.action) {
+ case 'quality':
+ this.showQuality();
+ break;
+ case 'indexers':
+ this.showIndexers();
+ break;
+ case 'downloadclient':
+ this.showDownloadClient();
+ break;
+ case 'notifications':
+ this.showNotifications();
+ break;
+ case 'system':
+ this.showSystem();
+ break;
+ case 'misc':
+ this.showMisc();
+ break;
+ default:
+ this.showNaming();
+ }
+ }
+ });
+ });
+
diff --git a/NzbDrone.Backbone/Settings/SettingsLayoutTemplate.html b/NzbDrone.Backbone/Settings/SettingsLayoutTemplate.html
new file mode 100644
index 000000000..5f856284f
--- /dev/null
+++ b/NzbDrone.Backbone/Settings/SettingsLayoutTemplate.html
@@ -0,0 +1,19 @@
+
+
+
+
Naming Settings
+
Quality Settings
+
Indexer Settings
+
Download Client Settings
+
Notification Settings
+
System Settings
+
Misc Settings
+
diff --git a/NzbDrone.Backbone/Settings/SettingsModel.js b/NzbDrone.Backbone/Settings/SettingsModel.js
new file mode 100644
index 000000000..7c30696a8
--- /dev/null
+++ b/NzbDrone.Backbone/Settings/SettingsModel.js
@@ -0,0 +1,5 @@
+define(['app'], function (app) {
+ NzbDrone.Settings.SettingsModel = Backbone.Model.extend({
+ url: NzbDrone.Constants.ApiRoot + '/settings'
+ });
+});
\ No newline at end of file
diff --git a/NzbDrone.Backbone/Settings/System/SystemTemplate.html b/NzbDrone.Backbone/Settings/System/SystemTemplate.html
new file mode 100644
index 000000000..8edf2eb4b
--- /dev/null
+++ b/NzbDrone.Backbone/Settings/System/SystemTemplate.html
@@ -0,0 +1,3 @@
+
+ System settings will go here
+
\ No newline at end of file
diff --git a/NzbDrone.Backbone/Settings/System/SystemView.js b/NzbDrone.Backbone/Settings/System/SystemView.js
new file mode 100644
index 000000000..8e3b042b6
--- /dev/null
+++ b/NzbDrone.Backbone/Settings/System/SystemView.js
@@ -0,0 +1,29 @@
+'use strict';
+
+define([
+ 'app', 'Settings/SettingsModel'
+
+], function () {
+
+ NzbDrone.Settings.System.SystemView = Backbone.Marionette.ItemView.extend({
+ template: 'Settings/System/SystemTemplate',
+
+ events: {
+ 'click .x-save': 'save'
+ },
+
+ initialize: function (options) {
+ this.model = options.model;
+ },
+
+ onRender: function () {
+ NzbDrone.ModelBinder.bind(this.model, this.el);
+ },
+
+
+ save: function () {
+ //Todo: Actually save the model
+ alert('Save pressed!');
+ }
+ });
+});
diff --git a/NzbDrone.Backbone/app.js b/NzbDrone.Backbone/app.js
index c2daa580e..f6ecd5235 100644
--- a/NzbDrone.Backbone/app.js
+++ b/NzbDrone.Backbone/app.js
@@ -28,55 +28,63 @@
define('app', function () {
- window.NzbDrone = new Backbone.Marionette.Application();
- window.NzbDrone.Series = {};
+ window.NzbDrone = new Backbone.Marionette.Application();
+ window.NzbDrone.Series = {};
window.NzbDrone.Series.Index = {};
- window.NzbDrone.Series.Edit = {};
- window.NzbDrone.Series.Delete = {};
- window.NzbDrone.Series.Details = {};
- window.NzbDrone.AddSeries = {};
- window.NzbDrone.AddSeries.New = {};
- window.NzbDrone.AddSeries.Existing = {};
- window.NzbDrone.AddSeries.RootFolders = {};
- window.NzbDrone.Quality = {};
- window.NzbDrone.Shared = {};
- window.NzbDrone.Upcoming = {};
- window.NzbDrone.Calendar = {};
-
- window.NzbDrone.Events = {
- OpenModalDialog :'openModal',
- CloseModalDialog : 'closeModal'
- },
+ window.NzbDrone.Series.Edit = {};
+ window.NzbDrone.Series.Delete = {};
+ window.NzbDrone.Series.Details = {};
+ window.NzbDrone.AddSeries = {};
+ window.NzbDrone.AddSeries.New = {};
+ window.NzbDrone.AddSeries.Existing = {};
+ window.NzbDrone.AddSeries.RootFolders = {};
+ window.NzbDrone.Quality = {};
+ window.NzbDrone.Shared = {};
+ window.NzbDrone.Upcoming = {};
+ window.NzbDrone.Calendar = {};
+ window.NzbDrone.Settings = {};
+ window.NzbDrone.Settings.Naming = {};
+ window.NzbDrone.Settings.Quality = {};
+ window.NzbDrone.Settings.Indexers = {};
+ window.NzbDrone.Settings.DownloadClient = {};
+ window.NzbDrone.Settings.Notifications = {};
+ window.NzbDrone.Settings.System = {};
+ window.NzbDrone.Settings.Misc = {};
+
+ window.NzbDrone.Events = {
+ OpenModalDialog :'openModal',
+ CloseModalDialog : 'closeModal'
+ },
- window.NzbDrone.Constants = {
- ApiRoot: '/api'
- };
+ window.NzbDrone.Constants = {
+ ApiRoot: '/api'
+ };
- window.NzbDrone.addInitializer(function () {
+ window.NzbDrone.addInitializer(function () {
- console.log('starting application');
+ console.log('starting application');
- NzbDrone.ModelBinder = new Backbone.ModelBinder();
+ NzbDrone.ModelBinder = new Backbone.ModelBinder();
- //TODO: move this out of here
- Handlebars.registerHelper("formatStatus", function (status, monitored) {
- if (!monitored) return '';
- if (status === 'Continuing') return '';
+ //TODO: move this out of here
+ Handlebars.registerHelper("formatStatus", function (status, monitored) {
+ if (!monitored) return '';
+ if (status === 'Continuing') return '';
- return '';
- });
+ return '';
+ });
- NzbDrone.addRegions({
- titleRegion: '#title-region',
- mainRegion: '#main-region',
- notificationRegion: '#notification-region',
- });
+ NzbDrone.addRegions({
+ titleRegion: '#title-region',
+ mainRegion: '#main-region',
+ notificationRegion: '#notification-region',
});
+ });
- window.NzbDrone.start();
+ window.NzbDrone.start();
- return NzbDrone;
- });
+ return NzbDrone;
+});
diff --git a/NzbDrone.Core.Test/ParserTests/ParserFixture.cs b/NzbDrone.Core.Test/ParserTests/ParserFixture.cs
index e82c4b3aa..55801234a 100644
--- a/NzbDrone.Core.Test/ParserTests/ParserFixture.cs
+++ b/NzbDrone.Core.Test/ParserTests/ParserFixture.cs
@@ -76,6 +76,7 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("S02E10 6-50 to SLC [SDTV]", "", 2, 10)]
[TestCase("Franklin & Bash S02E10 6-50 to SLC [SDTV]", "Franklin & Bash", 2, 10)]
[TestCase("The_Big_Bang_Theory_-_6x12_-_The_Egg_Salad_Equivalency_[HDTV-720p]", "The Big Bang Theory", 6, 12)]
+ [TestCase("Top_Gear.19x06.720p_HDTV_x264-FoV", "Top Gear", 19, 6)]
public void ParseTitle_single(string postTitle, string title, int seasonNumber, int episodeNumber)
{
var result = Parser.ParseTitle(postTitle);