From 4cd75cd8aa3b4c251f37a380de0c5e6bbea288ca Mon Sep 17 00:00:00 2001 From: Keivan Beigi Date: Wed, 24 Apr 2013 21:27:49 -0700 Subject: [PATCH] stuff we did :D --- .../MappingTests/ResourceMappingFixture.cs | 3 + NzbDrone.Api/Config/SettingsModule.cs | 86 +++++ NzbDrone.Api/NzbDrone.Api.csproj | 4 +- NzbDrone.Api/NzbDroneRestModule.cs | 8 +- NzbDrone.Api/REST/RestModule.cs | 16 + NzbDrone.Api/RootFolders/RootFolderModule.cs | 2 +- NzbDrone.Api/Series/SeriesModule.cs | 2 +- NzbDrone.Api/Settings/SettingsModule.cs | 41 -- NzbDrone.Common/IJsonSerializer.cs | 6 +- .../Datastore/BasicRepositoryFixture.cs | 7 + .../OrganizerTests/GetNewFilenameFixture.cs | 356 +++++++++--------- NzbDrone.Core/Datastore/BasicRepository.cs | 10 + .../Datastore/Migration/Migration20130324.cs | 11 + NzbDrone.Core/Datastore/TableMapping.cs | 3 + NzbDrone.Core/NzbDrone.Core.csproj | 2 +- NzbDrone.Core/Organizer/FileNameBuilder.cs | 55 ++- NzbDrone.Core/Organizer/NameSpecification.cs | 30 -- NzbDrone.Core/Organizer/NamingConfig.cs | 44 +++ NzbDrone/MainAppContainerBuilder.cs | 2 +- UI/.idea/jsLinters/jshint.xml | 2 +- UI/Mixins/backbone.bootstrap.switch.mixin.js | 59 +++ UI/Series/Details/SeasonLayout.js | 4 +- UI/Series/Index/SeriesIndexLayout.js | 143 +++---- UI/Series/series.less | 113 +++--- UI/Settings/Naming/NamingModel.js | 6 + UI/Settings/Naming/NamingTemplate.html | 54 +-- UI/Settings/Naming/NamingView.js | 31 +- UI/Settings/SettingsLayout.js | 22 +- UI/app.js | 5 + 29 files changed, 648 insertions(+), 479 deletions(-) create mode 100644 NzbDrone.Api/Config/SettingsModule.cs delete mode 100644 NzbDrone.Api/Settings/SettingsModule.cs delete mode 100644 NzbDrone.Core/Organizer/NameSpecification.cs create mode 100644 NzbDrone.Core/Organizer/NamingConfig.cs create mode 100644 UI/Mixins/backbone.bootstrap.switch.mixin.js create mode 100644 UI/Settings/Naming/NamingModel.js diff --git a/NzbDrone.Api.Test/MappingTests/ResourceMappingFixture.cs b/NzbDrone.Api.Test/MappingTests/ResourceMappingFixture.cs index 87ccf537b..264d0b34f 100644 --- a/NzbDrone.Api.Test/MappingTests/ResourceMappingFixture.cs +++ b/NzbDrone.Api.Test/MappingTests/ResourceMappingFixture.cs @@ -1,9 +1,11 @@ using System; using NUnit.Framework; +using NzbDrone.Api.Config; using NzbDrone.Api.Episodes; using NzbDrone.Api.Mapping; using NzbDrone.Api.RootFolders; using NzbDrone.Api.Series; +using NzbDrone.Core.Organizer; using NzbDrone.Core.RootFolders; using NzbDrone.Test.Common; @@ -15,6 +17,7 @@ public class ResourceMappingFixture : TestBase [TestCase(typeof(Core.Tv.Series), typeof(SeriesResource))] [TestCase(typeof(Core.Tv.Episode), typeof(EpisodeResource))] [TestCase(typeof(RootFolder), typeof(RootFolderResource))] + [TestCase(typeof(NamingConfig), typeof(NamingConfigResource))] public void matching_fields(Type modelType, Type resourceType) { MappingValidation.ValidateMapping(modelType, resourceType); diff --git a/NzbDrone.Api/Config/SettingsModule.cs b/NzbDrone.Api/Config/SettingsModule.cs new file mode 100644 index 000000000..c6fefa8e1 --- /dev/null +++ b/NzbDrone.Api/Config/SettingsModule.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using Nancy; +using NzbDrone.Api.Extensions; +using NzbDrone.Api.REST; +using NzbDrone.Core.Configuration; +using NzbDrone.Core.Organizer; +using FluentValidation; + +namespace NzbDrone.Api.Config +{ + public class NamingModule : NzbDroneRestModule + { + private readonly INamingConfigService _namingConfigService; + + public NamingModule(INamingConfigService namingConfigService) + : base("config/naming") + { + _namingConfigService = namingConfigService; + GetResourceSingle = GetNamingConfig; + + UpdateResource = UpdateNamingConfig; + + SharedValidator.RuleFor(c => c.MultiEpisodeStyle).InclusiveBetween(0, 3); + SharedValidator.RuleFor(c => c.NumberStyle).InclusiveBetween(0, 3); + SharedValidator.RuleFor(c => c.SeasonFolderFormat).NotEmpty(); + SharedValidator.RuleFor(c => c.Separator).NotEmpty(); + } + + private NamingConfigResource UpdateNamingConfig(NamingConfigResource resource) + { + return Apply(_namingConfigService.Save, resource); + } + + private NamingConfigResource GetNamingConfig() + { + return Apply(_namingConfigService.GetConfig); + } + } + + public class NamingConfigResource : RestResource + { + public Boolean IncludeEpisodeTitle { get; set; } + public Boolean ReplaceSpaces { get; set; } + public Boolean UseSceneName { get; set; } + public Int32 MultiEpisodeStyle { get; set; } + public Int32 NumberStyle { get; set; } + public String SeasonFolderFormat { get; set; } + public String Separator { get; set; } + public Boolean IncludeQuality { get; set; } + public Boolean IncludeSeriesTitle { get; set; } + } + + + public class SettingsModule : NzbDroneApiModule + { + private readonly IConfigService _configService; + + public SettingsModule(IConfigService configService) + : base("/settings") + { + _configService = configService; + Get["/"] = x => GetAllSettings(); + Post["/"] = x => SaveSettings(); + } + + private Response GetAllSettings() + { + var collection = Request.Query.Collection; + + if (collection.HasValue && Boolean.Parse(collection.Value)) + return _configService.All().AsResponse(); + + return _configService.AllWithDefaults().AsResponse(); + } + + private Response SaveSettings() + { + var request = Request.Body.FromJson>(); + _configService.SaveValues(request); + + + return request.AsResponse(); + } + } +} \ No newline at end of file diff --git a/NzbDrone.Api/NzbDrone.Api.csproj b/NzbDrone.Api/NzbDrone.Api.csproj index 500b43e30..57c11430f 100644 --- a/NzbDrone.Api/NzbDrone.Api.csproj +++ b/NzbDrone.Api/NzbDrone.Api.csproj @@ -1,4 +1,4 @@ - + @@ -126,7 +126,7 @@ - + diff --git a/NzbDrone.Api/NzbDroneRestModule.cs b/NzbDrone.Api/NzbDroneRestModule.cs index e5ba93fdf..0b026eea3 100644 --- a/NzbDrone.Api/NzbDroneRestModule.cs +++ b/NzbDrone.Api/NzbDroneRestModule.cs @@ -30,12 +30,18 @@ protected NzbDroneRestModule(string resource) return model.InjectTo(); } - protected List Apply(Func> function) where TModel : ModelBase, new() + protected List ApplyToList(Func> function) where TModel : ModelBase, new() { var modelList = function(); return modelList.InjectTo>(); } + protected TResource Apply(Func function) where TModel : ModelBase, new() + { + var modelList = function(); + return modelList.InjectTo(); + } + protected TResource Apply(Func action, int id) where TModel : ModelBase, new() { var model = action(id); diff --git a/NzbDrone.Api/REST/RestModule.cs b/NzbDrone.Api/REST/RestModule.cs index b0a234ee6..15747d1bd 100644 --- a/NzbDrone.Api/REST/RestModule.cs +++ b/NzbDrone.Api/REST/RestModule.cs @@ -16,6 +16,7 @@ public abstract class RestModule : NancyModule private Action _deleteResource; private Func _getResourceById; private Func> _getResourceAll; + private Func _getResourceSingle; private Func _createResource; private Func _updateResource; @@ -76,6 +77,21 @@ protected Func> GetResourceAll } } + protected Func GetResourceSingle + { + private get { return _getResourceSingle; } + set + { + _getResourceSingle = value; + + Get[ROOT_ROUTE] = options => + { + var resource = GetResourceSingle(); + return resource.AsResponse(); + }; + } + } + protected Func CreateResource { private get { return _createResource; } diff --git a/NzbDrone.Api/RootFolders/RootFolderModule.cs b/NzbDrone.Api/RootFolders/RootFolderModule.cs index 82226114e..0b9ad2ccf 100644 --- a/NzbDrone.Api/RootFolders/RootFolderModule.cs +++ b/NzbDrone.Api/RootFolders/RootFolderModule.cs @@ -23,7 +23,7 @@ private RootFolderResource CreateRootFolder(RootFolderResource rootFolderResourc private List GetRootFolders() { - return Apply(_rootFolderService.All); + return ApplyToList(_rootFolderService.All); } private void DeleteFolder(int id) diff --git a/NzbDrone.Api/Series/SeriesModule.cs b/NzbDrone.Api/Series/SeriesModule.cs index 57cafeb0c..bc761fa6e 100644 --- a/NzbDrone.Api/Series/SeriesModule.cs +++ b/NzbDrone.Api/Series/SeriesModule.cs @@ -37,7 +37,7 @@ public SeriesModule(ISeriesService seriesService, ISeriesStatisticsService serie private List AllSeries() { var seriesStats = _seriesStatisticsService.SeriesStatistics(); - var seriesModels = Apply(_seriesService.GetAllSeries); + var seriesModels = ApplyToList(_seriesService.GetAllSeries); foreach (var s in seriesModels) { diff --git a/NzbDrone.Api/Settings/SettingsModule.cs b/NzbDrone.Api/Settings/SettingsModule.cs deleted file mode 100644 index a9bd74782..000000000 --- a/NzbDrone.Api/Settings/SettingsModule.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Nancy; -using NzbDrone.Api.Extensions; -using NzbDrone.Core.Configuration; - -namespace NzbDrone.Api.Settings -{ - public class SettingsModule : NzbDroneApiModule - { - private readonly IConfigService _configService; - - public SettingsModule(IConfigService configService) - : base("/settings") - { - _configService = configService; - Get["/"] = x => GetAllSettings(); - Post["/"] = x => SaveSettings(); - } - - private Response GetAllSettings() - { - var collection = Request.Query.Collection; - - if(collection.HasValue && Boolean.Parse(collection.Value)) - return _configService.All().AsResponse(); - - return _configService.AllWithDefaults().AsResponse(); - } - - private Response SaveSettings() - { - var request = Request.Body.FromJson>(); - _configService.SaveValues(request); - - - return request.AsResponse(); - } - } -} \ No newline at end of file diff --git a/NzbDrone.Common/IJsonSerializer.cs b/NzbDrone.Common/IJsonSerializer.cs index 17af14151..0151f1eb1 100644 --- a/NzbDrone.Common/IJsonSerializer.cs +++ b/NzbDrone.Common/IJsonSerializer.cs @@ -30,9 +30,9 @@ public JsonSerializer() _jsonNetSerializer = new Newtonsoft.Json.JsonSerializer() { DateTimeZoneHandling = setting.DateTimeZoneHandling, - NullValueHandling = NullValueHandling.Ignore, - Formatting = Formatting.Indented, - DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate, + NullValueHandling = setting.NullValueHandling, + Formatting = setting.Formatting, + DefaultValueHandling = setting.DefaultValueHandling, ContractResolver = new CamelCasePropertyNamesContractResolver() }; } diff --git a/NzbDrone.Core.Test/Datastore/BasicRepositoryFixture.cs b/NzbDrone.Core.Test/Datastore/BasicRepositoryFixture.cs index 865ce94bb..27d0813c1 100644 --- a/NzbDrone.Core.Test/Datastore/BasicRepositoryFixture.cs +++ b/NzbDrone.Core.Test/Datastore/BasicRepositoryFixture.cs @@ -55,6 +55,13 @@ public void should_be_able_to_find_by_id() .EqualTo(_basicType); } + [Test] + public void should_be_able_to_get_single() + { + Subject.Insert(_basicType); + Subject.SingleOrDefault().Should().NotBeNull(); + } + [Test] public void getting_model_with_invalid_id_should_throw() { diff --git a/NzbDrone.Core.Test/OrganizerTests/GetNewFilenameFixture.cs b/NzbDrone.Core.Test/OrganizerTests/GetNewFilenameFixture.cs index e45d77d1b..09a84b568 100644 --- a/NzbDrone.Core.Test/OrganizerTests/GetNewFilenameFixture.cs +++ b/NzbDrone.Core.Test/OrganizerTests/GetNewFilenameFixture.cs @@ -22,7 +22,7 @@ public class MediaFileProvider_GetNewFilenameTest : CoreTest { private Series _series; - private NameSpecification nameSpecification; + private NamingConfig namingConfig; [SetUp] public void Setup() @@ -33,11 +33,11 @@ public void Setup() .Build(); - nameSpecification = new NameSpecification(); + namingConfig = new NamingConfig(); - Mocker.GetMock>() - .Setup(c => c.SingleOrDefault()).Returns(nameSpecification); + Mocker.GetMock>() + .Setup(c => c.SingleOrDefault()).Returns(namingConfig); } @@ -49,12 +49,12 @@ public void GetNewFilename_Series_Episode_Quality_S01E05_Dash() - nameSpecification.IncludeSeriesName = true; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = true; - nameSpecification.Separator = " - "; - nameSpecification.NumberStyle = 2; - nameSpecification.ReplaceSpaces = false; + namingConfig.IncludeSeriesTitle = true; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = true; + namingConfig.Separator = " - "; + namingConfig.NumberStyle = 2; + namingConfig.ReplaceSpaces = false; var episode = Builder.CreateNew() .With(e => e.Title = "City Sushi") @@ -76,12 +76,12 @@ public void GetNewFilename_Episode_Quality_1x05_Dash() - nameSpecification.IncludeSeriesName = false; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = true; - nameSpecification.Separator = " - "; - nameSpecification.NumberStyle = 0; - nameSpecification.ReplaceSpaces = false; + namingConfig.IncludeSeriesTitle = false; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = true; + namingConfig.Separator = " - "; + namingConfig.NumberStyle = 0; + namingConfig.ReplaceSpaces = false; var episode = Builder.CreateNew() .With(e => e.Title = "City Sushi") @@ -103,12 +103,12 @@ public void GetNewFilename_Series_Quality_01x05_Space() - nameSpecification.IncludeSeriesName = true; - nameSpecification.IncludeEpisodeTitle = false; - nameSpecification.AppendQuality = true; - nameSpecification.Separator = " "; - nameSpecification.NumberStyle = 1; - nameSpecification.ReplaceSpaces = false; + namingConfig.IncludeSeriesTitle = true; + namingConfig.IncludeEpisodeTitle = false; + namingConfig.IncludeQuality = true; + namingConfig.Separator = " "; + namingConfig.NumberStyle = 1; + namingConfig.ReplaceSpaces = false; var episode = Builder.CreateNew() .With(e => e.Title = "City Sushi") @@ -130,12 +130,12 @@ public void GetNewFilename_Series_s01e05_Space() - nameSpecification.IncludeSeriesName = true; - nameSpecification.IncludeEpisodeTitle = false; - nameSpecification.AppendQuality = false; - nameSpecification.Separator = " "; - nameSpecification.NumberStyle = 3; - nameSpecification.ReplaceSpaces = false; + namingConfig.IncludeSeriesTitle = true; + namingConfig.IncludeEpisodeTitle = false; + namingConfig.IncludeQuality = false; + namingConfig.Separator = " "; + namingConfig.NumberStyle = 3; + namingConfig.ReplaceSpaces = false; var episode = Builder.CreateNew() @@ -158,12 +158,12 @@ public void GetNewFilename_Series_Episode_s01e05_Periods() - nameSpecification.IncludeSeriesName = true; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = false; - nameSpecification.Separator = " "; - nameSpecification.NumberStyle = 3; - nameSpecification.ReplaceSpaces = true; + namingConfig.IncludeSeriesTitle = true; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = false; + namingConfig.Separator = " "; + namingConfig.NumberStyle = 3; + namingConfig.ReplaceSpaces = true; var episode = Builder.CreateNew() .With(e => e.Title = "City Sushi") @@ -185,12 +185,12 @@ public void GetNewFilename_Series_Episode_s01e05_Dash_Periods_Quality() - nameSpecification.IncludeSeriesName = true; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = true; - nameSpecification.Separator = " - "; - nameSpecification.NumberStyle = 3; - nameSpecification.ReplaceSpaces = true; + namingConfig.IncludeSeriesTitle = true; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = true; + namingConfig.Separator = " - "; + namingConfig.NumberStyle = 3; + namingConfig.ReplaceSpaces = true; var episode = Builder.CreateNew() .With(e => e.Title = "City Sushi") @@ -212,12 +212,12 @@ public void GetNewFilename_S01E05_Dash() - nameSpecification.IncludeSeriesName = false; - nameSpecification.IncludeEpisodeTitle = false; - nameSpecification.AppendQuality = false; - nameSpecification.Separator = " - "; - nameSpecification.NumberStyle = 2; - nameSpecification.ReplaceSpaces = false; + namingConfig.IncludeSeriesTitle = false; + namingConfig.IncludeEpisodeTitle = false; + namingConfig.IncludeQuality = false; + namingConfig.Separator = " - "; + namingConfig.NumberStyle = 2; + namingConfig.ReplaceSpaces = false; var episode = Builder.CreateNew() @@ -240,13 +240,13 @@ public void GetNewFilename_multi_Series_Episode_Quality_S01E05_Scene_Dash() - nameSpecification.IncludeSeriesName = true; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = true; - nameSpecification.Separator = " - "; - nameSpecification.NumberStyle = 2; - nameSpecification.ReplaceSpaces = false; - nameSpecification.MultiEpisodeStyle = 3; + namingConfig.IncludeSeriesTitle = true; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = true; + namingConfig.Separator = " - "; + namingConfig.NumberStyle = 2; + namingConfig.ReplaceSpaces = false; + namingConfig.MultiEpisodeStyle = 3; var episodeOne = Builder.CreateNew() .With(e => e.Title = "Strawberries and Cream (1)") @@ -274,13 +274,13 @@ public void GetNewFilename_multi_Episode_Quality_1x05_Repeat_Dash() - nameSpecification.IncludeSeriesName = false; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = true; - nameSpecification.Separator = " - "; - nameSpecification.NumberStyle = 0; - nameSpecification.ReplaceSpaces = false; - nameSpecification.MultiEpisodeStyle = 2; + namingConfig.IncludeSeriesTitle = false; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = true; + namingConfig.Separator = " - "; + namingConfig.NumberStyle = 0; + namingConfig.ReplaceSpaces = false; + namingConfig.MultiEpisodeStyle = 2; var episodeOne = Builder.CreateNew() .With(e => e.Title = "Strawberries and Cream (1)") @@ -308,13 +308,13 @@ public void GetNewFilename_multi_Episode_Quality_01x05_Repeat_Space() - nameSpecification.IncludeSeriesName = false; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = true; - nameSpecification.Separator = " "; - nameSpecification.NumberStyle = 0; - nameSpecification.ReplaceSpaces = false; - nameSpecification.MultiEpisodeStyle = 2; + namingConfig.IncludeSeriesTitle = false; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = true; + namingConfig.Separator = " "; + namingConfig.NumberStyle = 0; + namingConfig.ReplaceSpaces = false; + namingConfig.MultiEpisodeStyle = 2; var episodeOne = Builder.CreateNew() .With(e => e.Title = "Strawberries and Cream (1)") @@ -342,13 +342,13 @@ public void GetNewFilename_multi_Series_Episode_s01e05_Duplicate_Period() - nameSpecification.IncludeSeriesName = true; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = false; - nameSpecification.Separator = " "; - nameSpecification.NumberStyle = 3; - nameSpecification.ReplaceSpaces = true; - nameSpecification.MultiEpisodeStyle = 1; + namingConfig.IncludeSeriesTitle = true; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = false; + namingConfig.Separator = " "; + namingConfig.NumberStyle = 3; + namingConfig.ReplaceSpaces = true; + namingConfig.MultiEpisodeStyle = 1; var episodeOne = Builder.CreateNew() .With(e => e.Title = "Strawberries and Cream (1)") @@ -376,13 +376,13 @@ public void GetNewFilename_multi_Series_S01E05_Extend_Dash_Period() - nameSpecification.IncludeSeriesName = true; - nameSpecification.IncludeEpisodeTitle = false; - nameSpecification.AppendQuality = false; - nameSpecification.Separator = " - "; - nameSpecification.NumberStyle = 2; - nameSpecification.ReplaceSpaces = true; - nameSpecification.MultiEpisodeStyle = 0; + namingConfig.IncludeSeriesTitle = true; + namingConfig.IncludeEpisodeTitle = false; + namingConfig.IncludeQuality = false; + namingConfig.Separator = " - "; + namingConfig.NumberStyle = 2; + namingConfig.ReplaceSpaces = true; + namingConfig.MultiEpisodeStyle = 0; var episodeOne = Builder.CreateNew() .With(e => e.Title = "Strawberries and Cream (1)") @@ -410,13 +410,13 @@ public void GetNewFilename_multi_1x05_Repeat_Dash_Period() - nameSpecification.IncludeSeriesName = false; - nameSpecification.IncludeEpisodeTitle = false; - nameSpecification.AppendQuality = false; - nameSpecification.Separator = " - "; - nameSpecification.NumberStyle = 0; - nameSpecification.ReplaceSpaces = true; - nameSpecification.MultiEpisodeStyle = 2; + namingConfig.IncludeSeriesTitle = false; + namingConfig.IncludeEpisodeTitle = false; + namingConfig.IncludeQuality = false; + namingConfig.Separator = " - "; + namingConfig.NumberStyle = 0; + namingConfig.ReplaceSpaces = true; + namingConfig.MultiEpisodeStyle = 2; var episodeOne = Builder.CreateNew() .With(e => e.Title = "Strawberries and Cream (1)") @@ -442,12 +442,12 @@ public void GetNewFilename_should_append_proper_when_proper_and_append_quality_i { - nameSpecification.IncludeSeriesName = true; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = true; - nameSpecification.Separator = " - "; - nameSpecification.NumberStyle = 2; - nameSpecification.ReplaceSpaces = false; + namingConfig.IncludeSeriesTitle = true; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = true; + namingConfig.Separator = " - "; + namingConfig.NumberStyle = 2; + namingConfig.ReplaceSpaces = false; var episode = Builder.CreateNew() .With(e => e.Title = "City Sushi") @@ -467,12 +467,12 @@ public void GetNewFilename_should_not_append_proper_when_not_proper_and_append_q { - nameSpecification.IncludeSeriesName = true; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = true; - nameSpecification.Separator = " - "; - nameSpecification.NumberStyle = 2; - nameSpecification.ReplaceSpaces = false; + namingConfig.IncludeSeriesTitle = true; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = true; + namingConfig.Separator = " - "; + namingConfig.NumberStyle = 2; + namingConfig.ReplaceSpaces = false; var episode = Builder.CreateNew() .With(e => e.Title = "City Sushi") @@ -492,12 +492,12 @@ public void GetNewFilename_should_not_append_proper_when_proper_and_append_quali { - nameSpecification.IncludeSeriesName = true; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = false; - nameSpecification.Separator = " - "; - nameSpecification.NumberStyle = 2; - nameSpecification.ReplaceSpaces = false; + namingConfig.IncludeSeriesTitle = true; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = false; + namingConfig.Separator = " - "; + namingConfig.NumberStyle = 2; + namingConfig.ReplaceSpaces = false; var episode = Builder.CreateNew() .With(e => e.Title = "City Sushi") @@ -517,13 +517,13 @@ public void GetNewFilename_should_order_multiple_episode_files_in_numerical_orde { - nameSpecification.IncludeSeriesName = true; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = false; - nameSpecification.Separator = " - "; - nameSpecification.NumberStyle = 2; - nameSpecification.ReplaceSpaces = false; - nameSpecification.MultiEpisodeStyle = 3; + namingConfig.IncludeSeriesTitle = true; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = false; + namingConfig.Separator = " - "; + namingConfig.NumberStyle = 2; + namingConfig.ReplaceSpaces = false; + namingConfig.MultiEpisodeStyle = 3; var episode = Builder.CreateNew() .With(e => e.Title = "Hey, Baby, What's Wrong? (1)") @@ -551,12 +551,12 @@ public void GetNewFilename_Series_Episode_Quality_S01E05_Period() - nameSpecification.IncludeSeriesName = true; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = true; - nameSpecification.Separator = "."; - nameSpecification.NumberStyle = 2; - nameSpecification.ReplaceSpaces = false; + namingConfig.IncludeSeriesTitle = true; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = true; + namingConfig.Separator = "."; + namingConfig.NumberStyle = 2; + namingConfig.ReplaceSpaces = false; var episode = Builder.CreateNew() .With(e => e.Title = "City Sushi") @@ -578,12 +578,12 @@ public void GetNewFilename_Episode_Quality_1x05_Period() - nameSpecification.IncludeSeriesName = false; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = true; - nameSpecification.Separator = "."; ; - nameSpecification.NumberStyle = 0; - nameSpecification.ReplaceSpaces = false; + namingConfig.IncludeSeriesTitle = false; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = true; + namingConfig.Separator = "."; ; + namingConfig.NumberStyle = 0; + namingConfig.ReplaceSpaces = false; var episode = Builder.CreateNew() .With(e => e.Title = "City Sushi") @@ -603,13 +603,13 @@ public void GetNewFilename_UseSceneName_when_sceneName_isNull() { - nameSpecification.IncludeSeriesName = false; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = true; - nameSpecification.Separator = "."; ; - nameSpecification.NumberStyle = 0; - nameSpecification.ReplaceSpaces = false; - nameSpecification.UseSceneName = true; + namingConfig.IncludeSeriesTitle = false; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = true; + namingConfig.Separator = "."; ; + namingConfig.NumberStyle = 0; + namingConfig.ReplaceSpaces = false; + namingConfig.UseSceneName = true; var episode = Builder.CreateNew() .With(e => e.Title = "City Sushi") @@ -634,13 +634,13 @@ public void GetNewFilename_UseSceneName_when_sceneName_isNotNull() { - nameSpecification.IncludeSeriesName = false; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = true; - nameSpecification.Separator = "."; - nameSpecification.NumberStyle = 0; - nameSpecification.ReplaceSpaces = false; - nameSpecification.UseSceneName = true; + namingConfig.IncludeSeriesTitle = false; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = true; + namingConfig.Separator = "."; + namingConfig.NumberStyle = 0; + namingConfig.ReplaceSpaces = false; + namingConfig.UseSceneName = true; var episode = Builder.CreateNew() .With(e => e.Title = "City Sushi") @@ -665,13 +665,13 @@ public void should_only_have_one_episodeTitle_when_episode_titles_are_the_same() { - nameSpecification.IncludeSeriesName = true; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = false; - nameSpecification.Separator = " - "; - nameSpecification.NumberStyle = 2; - nameSpecification.ReplaceSpaces = false; - nameSpecification.MultiEpisodeStyle = 3; + namingConfig.IncludeSeriesTitle = true; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = false; + namingConfig.Separator = " - "; + namingConfig.NumberStyle = 2; + namingConfig.ReplaceSpaces = false; + namingConfig.MultiEpisodeStyle = 3; var episode = Builder.CreateNew() .With(e => e.Title = "Hey, Baby, What's Wrong? (1)") @@ -697,13 +697,13 @@ public void should_have_two_episodeTitles_when_episode_titles_are_not_the_same() { - nameSpecification.IncludeSeriesName = true; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = false; - nameSpecification.Separator = " - "; - nameSpecification.NumberStyle = 2; - nameSpecification.ReplaceSpaces = false; - nameSpecification.MultiEpisodeStyle = 3; + namingConfig.IncludeSeriesTitle = true; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = false; + namingConfig.Separator = " - "; + namingConfig.NumberStyle = 2; + namingConfig.ReplaceSpaces = false; + namingConfig.MultiEpisodeStyle = 3; var episode = Builder.CreateNew() .With(e => e.Title = "Hello") @@ -729,13 +729,13 @@ public void should_have_two_episodeTitles_when_distinct_count_is_two() { - nameSpecification.IncludeSeriesName = true; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = false; - nameSpecification.Separator = " - "; - nameSpecification.NumberStyle = 2; - nameSpecification.ReplaceSpaces = false; - nameSpecification.MultiEpisodeStyle = 3; + namingConfig.IncludeSeriesTitle = true; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = false; + namingConfig.Separator = " - "; + namingConfig.NumberStyle = 2; + namingConfig.ReplaceSpaces = false; + namingConfig.MultiEpisodeStyle = 3; var episode = Builder.CreateNew() .With(e => e.Title = "Hello (3)") @@ -766,12 +766,12 @@ public void should_have_two_episodeTitles_when_distinct_count_is_two() public void should_use_airDate_if_series_isDaily() { - nameSpecification.IncludeSeriesName = true; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = true; - nameSpecification.Separator = " - "; - nameSpecification.NumberStyle = 2; - nameSpecification.ReplaceSpaces = false; + namingConfig.IncludeSeriesTitle = true; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = true; + namingConfig.Separator = " - "; + namingConfig.NumberStyle = 2; + namingConfig.ReplaceSpaces = false; var series = Builder .CreateNew() @@ -795,12 +795,12 @@ public void should_use_airDate_if_series_isDaily() public void should_use_airDate_if_series_isDaily_no_episode_title() { - nameSpecification.IncludeSeriesName = true; - nameSpecification.IncludeEpisodeTitle = false; - nameSpecification.AppendQuality = false; - nameSpecification.Separator = " - "; - nameSpecification.NumberStyle = 2; - nameSpecification.ReplaceSpaces = false; + namingConfig.IncludeSeriesTitle = true; + namingConfig.IncludeEpisodeTitle = false; + namingConfig.IncludeQuality = false; + namingConfig.Separator = " - "; + namingConfig.NumberStyle = 2; + namingConfig.ReplaceSpaces = false; var series = Builder .CreateNew() @@ -824,12 +824,12 @@ public void should_use_airDate_if_series_isDaily_no_episode_title() public void should_set_airdate_to_unknown_if_not_available() { - nameSpecification.IncludeSeriesName = true; - nameSpecification.IncludeEpisodeTitle = true; - nameSpecification.AppendQuality = false; - nameSpecification.Separator = " - "; - nameSpecification.NumberStyle = 2; - nameSpecification.ReplaceSpaces = false; + namingConfig.IncludeSeriesTitle = true; + namingConfig.IncludeEpisodeTitle = true; + namingConfig.IncludeQuality = false; + namingConfig.Separator = " - "; + namingConfig.NumberStyle = 2; + namingConfig.ReplaceSpaces = false; var series = Builder .CreateNew() diff --git a/NzbDrone.Core/Datastore/BasicRepository.cs b/NzbDrone.Core/Datastore/BasicRepository.cs index c0041ac18..9d8369fd5 100644 --- a/NzbDrone.Core/Datastore/BasicRepository.cs +++ b/NzbDrone.Core/Datastore/BasicRepository.cs @@ -29,10 +29,15 @@ namespace NzbDrone.Core.Datastore bool HasItems(); void DeleteMany(IEnumerable ids); void SetFields(TModel model, params Expression>[] properties); + TModel Single(); } public class BasicRepository : IBasicRepository where TModel : ModelBase, new() { + + //TODO: add assertion to make sure model properly mapped + + private readonly IDataMapper _dataMapper; public BasicRepository(IDatabase database) @@ -78,6 +83,11 @@ public IEnumerable Get(IEnumerable ids) } public TModel SingleOrDefault() + { + return All().SingleOrDefault(); + } + + public TModel Single() { return All().Single(); } diff --git a/NzbDrone.Core/Datastore/Migration/Migration20130324.cs b/NzbDrone.Core/Datastore/Migration/Migration20130324.cs index 4dc03f3a8..080053575 100644 --- a/NzbDrone.Core/Datastore/Migration/Migration20130324.cs +++ b/NzbDrone.Core/Datastore/Migration/Migration20130324.cs @@ -127,6 +127,17 @@ protected override void MainDbUpgrade() .WithColumn("TvdbId").AsInt32() .WithColumn("SeasonNumber").AsInt32(); + + Create.TableForModel("NamingConfig") + .WithColumn("UseSceneName").AsBoolean() + .WithColumn("Separator").AsString() + .WithColumn("NumberStyle").AsInt32() + .WithColumn("IncludeSeriesTitle").AsBoolean() + .WithColumn("MultiEpisodeStyle").AsInt32() + .WithColumn("IncludeEpisodeTitle").AsBoolean() + .WithColumn("IncludeQuality").AsBoolean() + .WithColumn("ReplaceSpaces").AsBoolean() + .WithColumn("SeasonFolderFormat").AsString(); } protected override void LogDbUpgrade() diff --git a/NzbDrone.Core/Datastore/TableMapping.cs b/NzbDrone.Core/Datastore/TableMapping.cs index a43f17444..2215f385f 100644 --- a/NzbDrone.Core/Datastore/TableMapping.cs +++ b/NzbDrone.Core/Datastore/TableMapping.cs @@ -13,6 +13,7 @@ using NzbDrone.Core.Instrumentation; using NzbDrone.Core.Jobs; using NzbDrone.Core.MediaFiles; +using NzbDrone.Core.Organizer; using NzbDrone.Core.Qualities; using NzbDrone.Core.RootFolders; using NzbDrone.Core.SeriesStats; @@ -58,6 +59,8 @@ public static void Map() Mapper.Entity().RegisterModel("Logs"); + Mapper.Entity().RegisterModel("NamingConfig"); + Mapper.Entity().MapResultSet(); } diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index c09d8c947..07efb651c 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -342,7 +342,7 @@ - + diff --git a/NzbDrone.Core/Organizer/FileNameBuilder.cs b/NzbDrone.Core/Organizer/FileNameBuilder.cs index 176843fda..6a42129e7 100644 --- a/NzbDrone.Core/Organizer/FileNameBuilder.cs +++ b/NzbDrone.Core/Organizer/FileNameBuilder.cs @@ -15,27 +15,58 @@ public interface IBuildFileNames string BuildFilePath(Series series, int seasonNumber, string fileName, string extension); } + public interface INamingConfigService + { + NamingConfig GetConfig(); + NamingConfig Save(NamingConfig namingConfig); + } + + public class NamingConfigService : INamingConfigService + { + private readonly IBasicRepository _repository; + + public NamingConfigService(IBasicRepository repository) + { + _repository = repository; + } + + + public NamingConfig GetConfig() + { + var config = _repository.SingleOrDefault(); + + if (config == null) + { + _repository.Insert(NamingConfig.Default); + config = _repository.Single(); + } + + return config; + } + + public NamingConfig Save(NamingConfig namingConfig) + { + return _repository.Upsert(namingConfig); + } + } + + public class FileNameBuilder : IBuildFileNames { - private readonly IBasicRepository _nameSpecificationRepository; + private readonly INamingConfigService _namingConfigService; private readonly Logger _logger; - public FileNameBuilder(IBasicRepository nameSpecificationRepository, Logger logger) + public FileNameBuilder(INamingConfigService namingConfigService, Logger logger) { - _nameSpecificationRepository = nameSpecificationRepository; + _namingConfigService = namingConfigService; _logger = logger; } - public NameSpecification GetSpecification() - { - return _nameSpecificationRepository.SingleOrDefault() ?? NameSpecification.Default; - } - public string BuildFilename(IList episodes, Series series, EpisodeFile episodeFile) { - var nameSpec = GetSpecification(); + var nameSpec = _namingConfigService.GetConfig(); if (nameSpec.UseSceneName) { @@ -58,7 +89,7 @@ public string BuildFilename(IList episodes, Series series, EpisodeFile var result = String.Empty; - if (nameSpec.IncludeSeriesName) + if (nameSpec.IncludeSeriesTitle) { result += series.Title + nameSpec.Separator; } @@ -114,7 +145,7 @@ public string BuildFilename(IList episodes, Series series, EpisodeFile result += nameSpec.Separator + String.Join(" + ", episodeNames.Distinct()); } - if (nameSpec.AppendQuality) + if (nameSpec.IncludeQuality) { result += String.Format(" [{0}]", episodeFile.Quality.Quality); @@ -132,7 +163,7 @@ public string BuildFilename(IList episodes, Series series, EpisodeFile public string BuildFilePath(Series series, int seasonNumber, string fileName, string extension) { - var nameSpec = GetSpecification(); + var nameSpec = _namingConfigService.GetConfig(); string path = series.Path; if (series.SeasonFolder) diff --git a/NzbDrone.Core/Organizer/NameSpecification.cs b/NzbDrone.Core/Organizer/NameSpecification.cs deleted file mode 100644 index 081f5494c..000000000 --- a/NzbDrone.Core/Organizer/NameSpecification.cs +++ /dev/null @@ -1,30 +0,0 @@ -using NzbDrone.Core.Datastore; - -namespace NzbDrone.Core.Organizer -{ - public class NameSpecification : ModelBase - { - public static NameSpecification Default - { - get { return new NameSpecification(); } - } - - public bool UseSceneName { get; set; } - - public string Separator { get; set; } - - public int NumberStyle { get; set; } - - public bool IncludeSeriesName { get; set; } - - public int MultiEpisodeStyle { get; set; } - - public bool IncludeEpisodeTitle { get; set; } - - public bool AppendQuality { get; set; } - - public bool ReplaceSpaces { get; set; } - - public string SeasonFolderFormat { get; set; } - } -} \ No newline at end of file diff --git a/NzbDrone.Core/Organizer/NamingConfig.cs b/NzbDrone.Core/Organizer/NamingConfig.cs new file mode 100644 index 000000000..524c7201d --- /dev/null +++ b/NzbDrone.Core/Organizer/NamingConfig.cs @@ -0,0 +1,44 @@ +using NzbDrone.Core.Datastore; + +namespace NzbDrone.Core.Organizer +{ + public class NamingConfig : ModelBase + { + public static NamingConfig Default + { + get + { + return new NamingConfig + { + UseSceneName = false, + Separator = "-", + NumberStyle = 0, + IncludeSeriesTitle = true, + MultiEpisodeStyle = 0, + IncludeEpisodeTitle = true, + IncludeQuality = true, + ReplaceSpaces = false, + SeasonFolderFormat = "Season %s" + }; + } + } + + public bool UseSceneName { get; set; } + + public string Separator { get; set; } + + public int NumberStyle { get; set; } + + public bool IncludeSeriesTitle { get; set; } + + public bool IncludeEpisodeTitle { get; set; } + + public bool IncludeQuality { get; set; } + + public int MultiEpisodeStyle { get; set; } + + public bool ReplaceSpaces { get; set; } + + public string SeasonFolderFormat { get; set; } + } +} \ No newline at end of file diff --git a/NzbDrone/MainAppContainerBuilder.cs b/NzbDrone/MainAppContainerBuilder.cs index 799f1bcb2..991536a6f 100644 --- a/NzbDrone/MainAppContainerBuilder.cs +++ b/NzbDrone/MainAppContainerBuilder.cs @@ -35,7 +35,7 @@ private MainAppContainerBuilder() Container.Register().AsSingleton(); Container.Register(typeof(IBasicRepository), typeof(BasicRepository)).AsMultiInstance(); - Container.Register(typeof(IBasicRepository), typeof(BasicRepository)).AsMultiInstance(); + Container.Register(typeof(IBasicRepository), typeof(BasicRepository)).AsMultiInstance(); InitDatabase(); diff --git a/UI/.idea/jsLinters/jshint.xml b/UI/.idea/jsLinters/jshint.xml index 5718af90f..103e7ac67 100644 --- a/UI/.idea/jsLinters/jshint.xml +++ b/UI/.idea/jsLinters/jshint.xml @@ -61,7 +61,7 @@ diff --git a/UI/Mixins/backbone.bootstrap.switch.mixin.js b/UI/Mixins/backbone.bootstrap.switch.mixin.js new file mode 100644 index 000000000..4ebc2a9cb --- /dev/null +++ b/UI/Mixins/backbone.bootstrap.switch.mixin.js @@ -0,0 +1,59 @@ +'use strict'; + +var oldItemViewRender = Marionette.ItemView.prototype.render; +var oldItemCollectionViewRender = Marionette.CollectionView.prototype.render; + + +Marionette.View.prototype.viewName = function () { + if (this.template) { + var regex = new RegExp('\/', 'g'); + + return this.template + .toLocaleLowerCase() + .replace('template', '') + .replace(regex, '-'); + } + + return undefined; +}; + +Marionette.ItemView.prototype.self$ = function (selector) { + return this.$(selector).not("[class*='iv-'] " + selector); +}; + +Marionette.ItemView.prototype.render = function () { + + var result = oldItemViewRender.apply(this, arguments); + + + //check to see if el has bindings (name attribute) + // any element that has a name attribute and isn't child of another view. + if (this.self$('[name]').length > 0) { + if (!this.model) { + throw 'view ' + this.viewName() + ' has binding attributes but model is not defined'; + } + + if (!this._modelBinder) { + this._modelBinder = new Backbone.ModelBinder(); + } + + window.console.log('binding ' + this.viewName()); + + this._modelBinder.bind(this.model, this.el); + } + + this.self$('.switch').bootstrapSwitch(); + this.$el.addClass('iv-' + this.viewName()); + + + return result; +}; + +Marionette.CollectionView.prototype.render = function () { + + if (this.model) { + NzbDrone.ModelBinder.bind(this.model, this.el); + } + + return oldItemCollectionViewRender.apply(this, arguments); +}; \ No newline at end of file diff --git a/UI/Series/Details/SeasonLayout.js b/UI/Series/Details/SeasonLayout.js index c2a585aa9..f71d1780c 100644 --- a/UI/Series/Details/SeasonLayout.js +++ b/UI/Series/Details/SeasonLayout.js @@ -25,8 +25,8 @@ define(['app'], function () { name : 'airDate', label : 'Air Date', editable : false, - cell : 'datetime', - formatter: new Backgrid.AirDateFormatter() + cell : 'datetime' + //formatter: new Backgrid.AirDateFormatter() } ], diff --git a/UI/Series/Index/SeriesIndexLayout.js b/UI/Series/Index/SeriesIndexLayout.js index fac745a6c..e78b9e7bd 100644 --- a/UI/Series/Index/SeriesIndexLayout.js +++ b/UI/Series/Index/SeriesIndexLayout.js @@ -2,17 +2,12 @@ define([ 'app', 'Series/Index/List/CollectionView', -<<<<<<< HEAD - 'Config' 'Series/Index/Posters/CollectionView', 'Series/Index/EmptyView', - 'Config', 'Series/Index/Table/AirDateCell', - 'Series/Index/Table/SeriesStatusCell' + 'Series/Index/Table/SeriesStatusCell', 'Shared/Toolbar/ToolbarView', -======= 'Shared/Toolbar/ToolbarLayout', ->>>>>>> added support for multi-button groups to toolbar 'Config' ], function () { @@ -34,128 +29,74 @@ define([ showTable: function () { - var columns = - [ - { - name : 'status', - label : '', - editable: false, - cell : 'seriesStatus' - }, - { - name : 'title', - label : 'Title', - editable: false, - cell : 'string' - }, - { - name : 'seasonCount', - label : 'Seasons', - editable: false, - cell : 'integer' - }, - { - name : 'quality', - label : 'Quality', - editable: false, - cell : 'integer' - }, - { - name : 'network', - label : 'Network', - editable: false, - cell : 'string' - }, - { - name : 'nextAiring', - label : 'Next Airing', - editable : false, - cell : 'datetime', - formatter: new Backgrid.AirDateFormatter() - }, - { - name : 'episodes', - label : 'Episodes', - editable: false, - sortable: false, - cell : 'string' - }, - { - name : 'edit', - label : '', - editable: false, - sortable: false, - cell : 'string' - } - ]; - - var grid = new Backgrid.Grid( + var columns = [ { - name: 'status', - label: '', - editable: false, - cell: 'seriesStatus', + name : 'status', + label : '', + editable : false, + cell : 'seriesStatus', headerCell: 'nzbDrone' }, { - name: 'title', - label: 'Title', - editable: false, - cell: Backgrid.TemplateBackedCell.extend({ template: 'Series/Index/Table/SeriesTitleTemplate' }), + name : 'title', + label : 'Title', + editable : false, + cell : Backgrid.TemplateBackedCell.extend({ template: 'Series/Index/Table/SeriesTitleTemplate' }), headerCell: 'nzbDrone' }, { - name: 'seasonCount', - label: 'Seasons', - editable: false, - cell: 'integer', + name : 'seasonCount', + label : 'Seasons', + editable : false, + cell : 'integer', headerCell: 'nzbDrone' }, { - name: 'quality', - label: 'Quality', - editable: false, - cell: 'integer', + name : 'quality', + label : 'Quality', + editable : false, + cell : 'integer', headerCell: 'nzbDrone' }, { - name: 'network', - label: 'Network', - editable: false, - cell: 'string', + name : 'network', + label : 'Network', + editable : false, + cell : 'string', headerCell: 'nzbDrone' }, { - name: 'nextAiring', - label: 'Next Airing', - editable: false, - cell: 'airDate', + name : 'nextAiring', + label : 'Next Airing', + editable : false, + cell : 'airDate', headerCell: 'nzbDrone' }, { - name: 'episodes', - label: 'Episodes', - editable: false, - sortable: false, - cell: Backgrid.TemplateBackedCell.extend({ template: 'Series/EpisodeProgressTemplate' }), + name : 'episodes', + label : 'Episodes', + editable : false, + sortable : false, + cell : Backgrid.TemplateBackedCell.extend({ template: 'Series/EpisodeProgressTemplate' }), headerCell: 'nzbDrone' }, { - name: 'edit', - label: '', - editable: false, - sortable: false, - cell: Backgrid.TemplateBackedCell.extend({ template: 'Series/Index/Table/ControlsColumnTemplate' }), + name : 'edit', + label : '', + editable : false, + sortable : false, + cell : Backgrid.TemplateBackedCell.extend({ template: 'Series/Index/Table/ControlsColumnTemplate' }), headerCell: 'nzbDrone' } ]; + this.series.show(new Backgrid.Grid( { - row: Backgrid.SeriesIndexTableRow, - columns : columns, - collection : this.seriesCollection, - className: 'table table-hover' + row : Backgrid.SeriesIndexTableRow, + columns : columns, + collection: this.seriesCollection, + className : 'table table-hover' })); }, @@ -196,7 +137,7 @@ define([ menuRight.add(new NzbDrone.Shared.Toolbar.CommandModel({title: "RSS Sync", icon: "icon-rss"})); menuRight.add(new NzbDrone.Shared.Toolbar.CommandModel({title: "Sync Database", icon: "icon-refresh"})); - this.toolbar.show(new NzbDrone.Shared.Toolbar.ToolbarLayout({left: [ menuLeft], right: [menuRight]})); + this.toolbar.show(new NzbDrone.Shared.Toolbar.ToolbarLayout({left: [ menuLeft, menuLeft], right: [menuRight]})); switch (this.viewStyle) { case 1: diff --git a/UI/Series/series.less b/UI/Series/series.less index 935c37ef0..ed49c1116 100644 --- a/UI/Series/series.less +++ b/UI/Series/series.less @@ -9,7 +9,7 @@ margin-top: 0px; } - a{ + a { color: #000000; } } @@ -21,70 +21,71 @@ display: inline-block; vertical-align: top; } -.series-page-header { - padding-bottom: 50px; -} - -.series-posters-item { - margin-bottom: 20px; - - .center { - display: block; - margin-left:auto; - margin-right:auto; - text-align: center; + .series-page-header { + padding-bottom: 50px; } - .progress { - left: 22px; - margin-top: 5px; - } + .series-posters-item { + margin-bottom: 20px; - .title { - font-size: 17px; - text-rendering: optimizelegibility; - } - - .labels { - display: inline-block; - opacity: 0.75; - width: 138px; - - :hover { - cursor: default; - } - - .label { - margin-top: 3px; + .center { display: block; + margin-left: auto; + margin-right: auto; + text-align: center; } - .tooltip { - opacity: 1; + .progress { + left: 22px; + margin-top: 5px; + } + + .title { + font-size: 17px; + text-rendering: optimizelegibility; + } + + .labels { + display: inline-block; + opacity: 0.75; + width: 138px; + + :hover { + cursor: default; + } + + .label { + margin-top: 3px; + display: block; + } + + .tooltip { + opacity: 1; + } + } + .series-season { + padding-bottom: 20px; } } -.series-season { - padding-bottom: 20px; -} -} -.series-poster-container { - position: relative; - overflow: hidden; - display: inline-block; + .series-poster-container { + position: relative; + overflow: hidden; + display: inline-block; - .ended-banner { - color: #EEEEEE; - background-color: #B94A48; - -moz-box-shadow: 2px 2px 20px #888; - -moz-transform: rotate(45deg); - -moz-transform-origin: 50% 50%; - -webkit-transform: rotate(45deg); - -webkit-transform-origin: 50% 50%; - position: absolute; - width: 300px; - top: 175px; - left: -122px; - text-align: center; + .ended-banner { + color: #eeeeee; + background-color: #b94a48; + -moz-box-shadow: 2px 2px 20px #888888; + -moz-transform: rotate(45deg); + -moz-transform-origin: 50% 50%; + -webkit-transform: rotate(45deg); + -webkit-transform-origin: 50% 50%; + position: absolute; + width: 300px; + top: 175px; + left: -122px; + text-align: center; + } } } diff --git a/UI/Settings/Naming/NamingModel.js b/UI/Settings/Naming/NamingModel.js new file mode 100644 index 000000000..9d596e6f2 --- /dev/null +++ b/UI/Settings/Naming/NamingModel.js @@ -0,0 +1,6 @@ +"use strict"; +define(['app'], function () { + NzbDrone.Settings.Naming.NamingModel = Backbone.Model.extend({ + url: NzbDrone.Constants.ApiRoot + '/config/naming' + }); +}); diff --git a/UI/Settings/Naming/NamingTemplate.html b/UI/Settings/Naming/NamingTemplate.html index 84e381644..efdfcf310 100644 --- a/UI/Settings/Naming/NamingTemplate.html +++ b/UI/Settings/Naming/NamingTemplate.html @@ -5,9 +5,7 @@
-
- -
+ @@ -15,12 +13,10 @@
- +
-
- -
+ @@ -28,12 +24,10 @@
- +
-
- -
+ @@ -45,7 +39,7 @@
- +
@@ -54,11 +48,11 @@
- +
- +
@@ -67,25 +61,11 @@
-
- - -
-
- -
- - - - -
-
-
- + @@ -93,13 +73,13 @@
- +
- + + + @@ -111,7 +91,7 @@
- @@ -127,7 +107,7 @@
- @@ -168,4 +148,4 @@
- \ No newline at end of file + diff --git a/UI/Settings/Naming/NamingView.js b/UI/Settings/Naming/NamingView.js index 2f61c6e87..c11516506 100644 --- a/UI/Settings/Naming/NamingView.js +++ b/UI/Settings/Naming/NamingView.js @@ -1,9 +1,5 @@ 'use strict'; - -define([ - 'app', 'Settings/SettingsModel' - -], function () { +define(['app', 'Settings/Naming/NamingModel'], function () { NzbDrone.Settings.Naming.NamingView = Backbone.Marionette.ItemView.extend({ template : 'Settings/Naming/NamingTemplate', @@ -14,11 +10,32 @@ define([ }, initialize: function () { - //Listen to save event + this.model = new NzbDrone.Settings.Naming.NamingModel(); + this.model.fetch(); + + NzbDrone.vent.on(NzbDrone.Commands.SaveSettings, this.saveSettings, this); }, onRender: function () { this.ui.tooltip.tooltip({ placement: 'right' }); + }, + + saveSettings: function () { + this.model.save(undefined, this.syncNotification("Naming Settings Saved", "Couldn't Save Naming Settings")); + }, + + + syncNotification: function (success, error) { + return { + success: function () { + window.alert(success); + }, + + error: function () { + window.alert(error); + } + }; } }); -}); +}) +; diff --git a/UI/Settings/SettingsLayout.js b/UI/Settings/SettingsLayout.js index 381d8d434..9430dc096 100644 --- a/UI/Settings/SettingsLayout.js +++ b/UI/Settings/SettingsLayout.js @@ -150,8 +150,22 @@ define([ }, save: function () { - this.settings.save(); - } - }); - }); + + NzbDrone.vent.trigger(NzbDrone.Commands.SaveSettings); + + this.settings.save(undefined, + { + success: function () { + window.alert('Saved'); + }, + error : function () { + window.alert("couldn't save settings"); + } + }); + + } + }) + ; + }) +; diff --git a/UI/app.js b/UI/app.js index 263416f5a..4659f15c0 100644 --- a/UI/app.js +++ b/UI/app.js @@ -60,11 +60,16 @@ define('app', function () { window.NzbDrone.Missing = {}; window.NzbDrone.Events = { + //TODO: Move to commands OpenModalDialog : 'openModal', CloseModalDialog: 'closeModal', SeriesAdded: 'seriesAdded' }; + window.NzbDrone.Commands = { + SaveSettings : 'saveSettings' + }; + window.NzbDrone.Constants = { ApiRoot: '/api' };