stuff we did :D

pull/4/head
Keivan Beigi 11 years ago
parent 32701d5e84
commit 4cd75cd8aa

@ -1,9 +1,11 @@
using System; using System;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Api.Config;
using NzbDrone.Api.Episodes; using NzbDrone.Api.Episodes;
using NzbDrone.Api.Mapping; using NzbDrone.Api.Mapping;
using NzbDrone.Api.RootFolders; using NzbDrone.Api.RootFolders;
using NzbDrone.Api.Series; using NzbDrone.Api.Series;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.RootFolders; using NzbDrone.Core.RootFolders;
using NzbDrone.Test.Common; using NzbDrone.Test.Common;
@ -15,6 +17,7 @@ namespace NzbDrone.Api.Test.MappingTests
[TestCase(typeof(Core.Tv.Series), typeof(SeriesResource))] [TestCase(typeof(Core.Tv.Series), typeof(SeriesResource))]
[TestCase(typeof(Core.Tv.Episode), typeof(EpisodeResource))] [TestCase(typeof(Core.Tv.Episode), typeof(EpisodeResource))]
[TestCase(typeof(RootFolder), typeof(RootFolderResource))] [TestCase(typeof(RootFolder), typeof(RootFolderResource))]
[TestCase(typeof(NamingConfig), typeof(NamingConfigResource))]
public void matching_fields(Type modelType, Type resourceType) public void matching_fields(Type modelType, Type resourceType)
{ {
MappingValidation.ValidateMapping(modelType, resourceType); MappingValidation.ValidateMapping(modelType, resourceType);

@ -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<NamingConfigResource>
{
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<NamingConfig>(_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<Dictionary<string, object>>();
_configService.SaveValues(request);
return request.AsResponse();
}
}
}

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup> <PropertyGroup>
@ -126,7 +126,7 @@
<Compile Include="Resolvers\AllowedToQualitiesResolver.cs" /> <Compile Include="Resolvers\AllowedToQualitiesResolver.cs" />
<Compile Include="Resolvers\QualitiesToAllowedResolver.cs" /> <Compile Include="Resolvers\QualitiesToAllowedResolver.cs" />
<Compile Include="Resolvers\QualityTypesToIntResolver.cs" /> <Compile Include="Resolvers\QualityTypesToIntResolver.cs" />
<Compile Include="Settings\SettingsModule.cs" /> <Compile Include="Config\SettingsModule.cs" />
<Compile Include="TinyIoCNancyBootstrapper.cs" /> <Compile Include="TinyIoCNancyBootstrapper.cs" />
<Compile Include="Validation\IdValidationRule.cs" /> <Compile Include="Validation\IdValidationRule.cs" />
</ItemGroup> </ItemGroup>

@ -30,12 +30,18 @@ namespace NzbDrone.Api
return model.InjectTo<TResource>(); return model.InjectTo<TResource>();
} }
protected List<TResource> Apply<TModel>(Func<IEnumerable<TModel>> function) where TModel : ModelBase, new() protected List<TResource> ApplyToList<TModel>(Func<IEnumerable<TModel>> function) where TModel : ModelBase, new()
{ {
var modelList = function(); var modelList = function();
return modelList.InjectTo<List<TResource>>(); return modelList.InjectTo<List<TResource>>();
} }
protected TResource Apply<TModel>(Func<TModel> function) where TModel : ModelBase, new()
{
var modelList = function();
return modelList.InjectTo<TResource>();
}
protected TResource Apply<TModel>(Func<int, TModel> action, int id) where TModel : ModelBase, new() protected TResource Apply<TModel>(Func<int, TModel> action, int id) where TModel : ModelBase, new()
{ {
var model = action(id); var model = action(id);

@ -16,6 +16,7 @@ namespace NzbDrone.Api.REST
private Action<int> _deleteResource; private Action<int> _deleteResource;
private Func<int, TResource> _getResourceById; private Func<int, TResource> _getResourceById;
private Func<List<TResource>> _getResourceAll; private Func<List<TResource>> _getResourceAll;
private Func<TResource> _getResourceSingle;
private Func<TResource, TResource> _createResource; private Func<TResource, TResource> _createResource;
private Func<TResource, TResource> _updateResource; private Func<TResource, TResource> _updateResource;
@ -76,6 +77,21 @@ namespace NzbDrone.Api.REST
} }
} }
protected Func<TResource> GetResourceSingle
{
private get { return _getResourceSingle; }
set
{
_getResourceSingle = value;
Get[ROOT_ROUTE] = options =>
{
var resource = GetResourceSingle();
return resource.AsResponse();
};
}
}
protected Func<TResource, TResource> CreateResource protected Func<TResource, TResource> CreateResource
{ {
private get { return _createResource; } private get { return _createResource; }

@ -23,7 +23,7 @@ namespace NzbDrone.Api.RootFolders
private List<RootFolderResource> GetRootFolders() private List<RootFolderResource> GetRootFolders()
{ {
return Apply(_rootFolderService.All); return ApplyToList(_rootFolderService.All);
} }
private void DeleteFolder(int id) private void DeleteFolder(int id)

@ -37,7 +37,7 @@ namespace NzbDrone.Api.Series
private List<SeriesResource> AllSeries() private List<SeriesResource> AllSeries()
{ {
var seriesStats = _seriesStatisticsService.SeriesStatistics(); var seriesStats = _seriesStatisticsService.SeriesStatistics();
var seriesModels = Apply(_seriesService.GetAllSeries); var seriesModels = ApplyToList(_seriesService.GetAllSeries);
foreach (var s in seriesModels) foreach (var s in seriesModels)
{ {

@ -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<Dictionary<string, object>>();
_configService.SaveValues(request);
return request.AsResponse();
}
}
}

@ -30,9 +30,9 @@ namespace NzbDrone.Common
_jsonNetSerializer = new Newtonsoft.Json.JsonSerializer() _jsonNetSerializer = new Newtonsoft.Json.JsonSerializer()
{ {
DateTimeZoneHandling = setting.DateTimeZoneHandling, DateTimeZoneHandling = setting.DateTimeZoneHandling,
NullValueHandling = NullValueHandling.Ignore, NullValueHandling = setting.NullValueHandling,
Formatting = Formatting.Indented, Formatting = setting.Formatting,
DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate, DefaultValueHandling = setting.DefaultValueHandling,
ContractResolver = new CamelCasePropertyNamesContractResolver() ContractResolver = new CamelCasePropertyNamesContractResolver()
}; };
} }

@ -55,6 +55,13 @@ namespace NzbDrone.Core.Test.Datastore
.EqualTo(_basicType); .EqualTo(_basicType);
} }
[Test]
public void should_be_able_to_get_single()
{
Subject.Insert(_basicType);
Subject.SingleOrDefault().Should().NotBeNull();
}
[Test] [Test]
public void getting_model_with_invalid_id_should_throw() public void getting_model_with_invalid_id_should_throw()
{ {

@ -22,7 +22,7 @@ namespace NzbDrone.Core.Test.OrganizerTests
{ {
private Series _series; private Series _series;
private NameSpecification nameSpecification; private NamingConfig namingConfig;
[SetUp] [SetUp]
public void Setup() public void Setup()
@ -33,11 +33,11 @@ namespace NzbDrone.Core.Test.OrganizerTests
.Build(); .Build();
nameSpecification = new NameSpecification(); namingConfig = new NamingConfig();
Mocker.GetMock<IBasicRepository<NameSpecification>>() Mocker.GetMock<IBasicRepository<NamingConfig>>()
.Setup(c => c.SingleOrDefault()).Returns(nameSpecification); .Setup(c => c.SingleOrDefault()).Returns(namingConfig);
} }
@ -49,12 +49,12 @@ namespace NzbDrone.Core.Test.OrganizerTests
nameSpecification.IncludeSeriesName = true; namingConfig.IncludeSeriesTitle = true;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = true; namingConfig.IncludeQuality = true;
nameSpecification.Separator = " - "; namingConfig.Separator = " - ";
nameSpecification.NumberStyle = 2; namingConfig.NumberStyle = 2;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
var episode = Builder<Episode>.CreateNew() var episode = Builder<Episode>.CreateNew()
.With(e => e.Title = "City Sushi") .With(e => e.Title = "City Sushi")
@ -76,12 +76,12 @@ namespace NzbDrone.Core.Test.OrganizerTests
nameSpecification.IncludeSeriesName = false; namingConfig.IncludeSeriesTitle = false;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = true; namingConfig.IncludeQuality = true;
nameSpecification.Separator = " - "; namingConfig.Separator = " - ";
nameSpecification.NumberStyle = 0; namingConfig.NumberStyle = 0;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
var episode = Builder<Episode>.CreateNew() var episode = Builder<Episode>.CreateNew()
.With(e => e.Title = "City Sushi") .With(e => e.Title = "City Sushi")
@ -103,12 +103,12 @@ namespace NzbDrone.Core.Test.OrganizerTests
nameSpecification.IncludeSeriesName = true; namingConfig.IncludeSeriesTitle = true;
nameSpecification.IncludeEpisodeTitle = false; namingConfig.IncludeEpisodeTitle = false;
nameSpecification.AppendQuality = true; namingConfig.IncludeQuality = true;
nameSpecification.Separator = " "; namingConfig.Separator = " ";
nameSpecification.NumberStyle = 1; namingConfig.NumberStyle = 1;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
var episode = Builder<Episode>.CreateNew() var episode = Builder<Episode>.CreateNew()
.With(e => e.Title = "City Sushi") .With(e => e.Title = "City Sushi")
@ -130,12 +130,12 @@ namespace NzbDrone.Core.Test.OrganizerTests
nameSpecification.IncludeSeriesName = true; namingConfig.IncludeSeriesTitle = true;
nameSpecification.IncludeEpisodeTitle = false; namingConfig.IncludeEpisodeTitle = false;
nameSpecification.AppendQuality = false; namingConfig.IncludeQuality = false;
nameSpecification.Separator = " "; namingConfig.Separator = " ";
nameSpecification.NumberStyle = 3; namingConfig.NumberStyle = 3;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
var episode = Builder<Episode>.CreateNew() var episode = Builder<Episode>.CreateNew()
@ -158,12 +158,12 @@ namespace NzbDrone.Core.Test.OrganizerTests
nameSpecification.IncludeSeriesName = true; namingConfig.IncludeSeriesTitle = true;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = false; namingConfig.IncludeQuality = false;
nameSpecification.Separator = " "; namingConfig.Separator = " ";
nameSpecification.NumberStyle = 3; namingConfig.NumberStyle = 3;
nameSpecification.ReplaceSpaces = true; namingConfig.ReplaceSpaces = true;
var episode = Builder<Episode>.CreateNew() var episode = Builder<Episode>.CreateNew()
.With(e => e.Title = "City Sushi") .With(e => e.Title = "City Sushi")
@ -185,12 +185,12 @@ namespace NzbDrone.Core.Test.OrganizerTests
nameSpecification.IncludeSeriesName = true; namingConfig.IncludeSeriesTitle = true;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = true; namingConfig.IncludeQuality = true;
nameSpecification.Separator = " - "; namingConfig.Separator = " - ";
nameSpecification.NumberStyle = 3; namingConfig.NumberStyle = 3;
nameSpecification.ReplaceSpaces = true; namingConfig.ReplaceSpaces = true;
var episode = Builder<Episode>.CreateNew() var episode = Builder<Episode>.CreateNew()
.With(e => e.Title = "City Sushi") .With(e => e.Title = "City Sushi")
@ -212,12 +212,12 @@ namespace NzbDrone.Core.Test.OrganizerTests
nameSpecification.IncludeSeriesName = false; namingConfig.IncludeSeriesTitle = false;
nameSpecification.IncludeEpisodeTitle = false; namingConfig.IncludeEpisodeTitle = false;
nameSpecification.AppendQuality = false; namingConfig.IncludeQuality = false;
nameSpecification.Separator = " - "; namingConfig.Separator = " - ";
nameSpecification.NumberStyle = 2; namingConfig.NumberStyle = 2;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
var episode = Builder<Episode>.CreateNew() var episode = Builder<Episode>.CreateNew()
@ -240,13 +240,13 @@ namespace NzbDrone.Core.Test.OrganizerTests
nameSpecification.IncludeSeriesName = true; namingConfig.IncludeSeriesTitle = true;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = true; namingConfig.IncludeQuality = true;
nameSpecification.Separator = " - "; namingConfig.Separator = " - ";
nameSpecification.NumberStyle = 2; namingConfig.NumberStyle = 2;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
nameSpecification.MultiEpisodeStyle = 3; namingConfig.MultiEpisodeStyle = 3;
var episodeOne = Builder<Episode>.CreateNew() var episodeOne = Builder<Episode>.CreateNew()
.With(e => e.Title = "Strawberries and Cream (1)") .With(e => e.Title = "Strawberries and Cream (1)")
@ -274,13 +274,13 @@ namespace NzbDrone.Core.Test.OrganizerTests
nameSpecification.IncludeSeriesName = false; namingConfig.IncludeSeriesTitle = false;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = true; namingConfig.IncludeQuality = true;
nameSpecification.Separator = " - "; namingConfig.Separator = " - ";
nameSpecification.NumberStyle = 0; namingConfig.NumberStyle = 0;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
nameSpecification.MultiEpisodeStyle = 2; namingConfig.MultiEpisodeStyle = 2;
var episodeOne = Builder<Episode>.CreateNew() var episodeOne = Builder<Episode>.CreateNew()
.With(e => e.Title = "Strawberries and Cream (1)") .With(e => e.Title = "Strawberries and Cream (1)")
@ -308,13 +308,13 @@ namespace NzbDrone.Core.Test.OrganizerTests
nameSpecification.IncludeSeriesName = false; namingConfig.IncludeSeriesTitle = false;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = true; namingConfig.IncludeQuality = true;
nameSpecification.Separator = " "; namingConfig.Separator = " ";
nameSpecification.NumberStyle = 0; namingConfig.NumberStyle = 0;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
nameSpecification.MultiEpisodeStyle = 2; namingConfig.MultiEpisodeStyle = 2;
var episodeOne = Builder<Episode>.CreateNew() var episodeOne = Builder<Episode>.CreateNew()
.With(e => e.Title = "Strawberries and Cream (1)") .With(e => e.Title = "Strawberries and Cream (1)")
@ -342,13 +342,13 @@ namespace NzbDrone.Core.Test.OrganizerTests
nameSpecification.IncludeSeriesName = true; namingConfig.IncludeSeriesTitle = true;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = false; namingConfig.IncludeQuality = false;
nameSpecification.Separator = " "; namingConfig.Separator = " ";
nameSpecification.NumberStyle = 3; namingConfig.NumberStyle = 3;
nameSpecification.ReplaceSpaces = true; namingConfig.ReplaceSpaces = true;
nameSpecification.MultiEpisodeStyle = 1; namingConfig.MultiEpisodeStyle = 1;
var episodeOne = Builder<Episode>.CreateNew() var episodeOne = Builder<Episode>.CreateNew()
.With(e => e.Title = "Strawberries and Cream (1)") .With(e => e.Title = "Strawberries and Cream (1)")
@ -376,13 +376,13 @@ namespace NzbDrone.Core.Test.OrganizerTests
nameSpecification.IncludeSeriesName = true; namingConfig.IncludeSeriesTitle = true;
nameSpecification.IncludeEpisodeTitle = false; namingConfig.IncludeEpisodeTitle = false;
nameSpecification.AppendQuality = false; namingConfig.IncludeQuality = false;
nameSpecification.Separator = " - "; namingConfig.Separator = " - ";
nameSpecification.NumberStyle = 2; namingConfig.NumberStyle = 2;
nameSpecification.ReplaceSpaces = true; namingConfig.ReplaceSpaces = true;
nameSpecification.MultiEpisodeStyle = 0; namingConfig.MultiEpisodeStyle = 0;
var episodeOne = Builder<Episode>.CreateNew() var episodeOne = Builder<Episode>.CreateNew()
.With(e => e.Title = "Strawberries and Cream (1)") .With(e => e.Title = "Strawberries and Cream (1)")
@ -410,13 +410,13 @@ namespace NzbDrone.Core.Test.OrganizerTests
nameSpecification.IncludeSeriesName = false; namingConfig.IncludeSeriesTitle = false;
nameSpecification.IncludeEpisodeTitle = false; namingConfig.IncludeEpisodeTitle = false;
nameSpecification.AppendQuality = false; namingConfig.IncludeQuality = false;
nameSpecification.Separator = " - "; namingConfig.Separator = " - ";
nameSpecification.NumberStyle = 0; namingConfig.NumberStyle = 0;
nameSpecification.ReplaceSpaces = true; namingConfig.ReplaceSpaces = true;
nameSpecification.MultiEpisodeStyle = 2; namingConfig.MultiEpisodeStyle = 2;
var episodeOne = Builder<Episode>.CreateNew() var episodeOne = Builder<Episode>.CreateNew()
.With(e => e.Title = "Strawberries and Cream (1)") .With(e => e.Title = "Strawberries and Cream (1)")
@ -442,12 +442,12 @@ namespace NzbDrone.Core.Test.OrganizerTests
{ {
nameSpecification.IncludeSeriesName = true; namingConfig.IncludeSeriesTitle = true;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = true; namingConfig.IncludeQuality = true;
nameSpecification.Separator = " - "; namingConfig.Separator = " - ";
nameSpecification.NumberStyle = 2; namingConfig.NumberStyle = 2;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
var episode = Builder<Episode>.CreateNew() var episode = Builder<Episode>.CreateNew()
.With(e => e.Title = "City Sushi") .With(e => e.Title = "City Sushi")
@ -467,12 +467,12 @@ namespace NzbDrone.Core.Test.OrganizerTests
{ {
nameSpecification.IncludeSeriesName = true; namingConfig.IncludeSeriesTitle = true;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = true; namingConfig.IncludeQuality = true;
nameSpecification.Separator = " - "; namingConfig.Separator = " - ";
nameSpecification.NumberStyle = 2; namingConfig.NumberStyle = 2;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
var episode = Builder<Episode>.CreateNew() var episode = Builder<Episode>.CreateNew()
.With(e => e.Title = "City Sushi") .With(e => e.Title = "City Sushi")
@ -492,12 +492,12 @@ namespace NzbDrone.Core.Test.OrganizerTests
{ {
nameSpecification.IncludeSeriesName = true; namingConfig.IncludeSeriesTitle = true;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = false; namingConfig.IncludeQuality = false;
nameSpecification.Separator = " - "; namingConfig.Separator = " - ";
nameSpecification.NumberStyle = 2; namingConfig.NumberStyle = 2;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
var episode = Builder<Episode>.CreateNew() var episode = Builder<Episode>.CreateNew()
.With(e => e.Title = "City Sushi") .With(e => e.Title = "City Sushi")
@ -517,13 +517,13 @@ namespace NzbDrone.Core.Test.OrganizerTests
{ {
nameSpecification.IncludeSeriesName = true; namingConfig.IncludeSeriesTitle = true;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = false; namingConfig.IncludeQuality = false;
nameSpecification.Separator = " - "; namingConfig.Separator = " - ";
nameSpecification.NumberStyle = 2; namingConfig.NumberStyle = 2;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
nameSpecification.MultiEpisodeStyle = 3; namingConfig.MultiEpisodeStyle = 3;
var episode = Builder<Episode>.CreateNew() var episode = Builder<Episode>.CreateNew()
.With(e => e.Title = "Hey, Baby, What's Wrong? (1)") .With(e => e.Title = "Hey, Baby, What's Wrong? (1)")
@ -551,12 +551,12 @@ namespace NzbDrone.Core.Test.OrganizerTests
nameSpecification.IncludeSeriesName = true; namingConfig.IncludeSeriesTitle = true;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = true; namingConfig.IncludeQuality = true;
nameSpecification.Separator = "."; namingConfig.Separator = ".";
nameSpecification.NumberStyle = 2; namingConfig.NumberStyle = 2;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
var episode = Builder<Episode>.CreateNew() var episode = Builder<Episode>.CreateNew()
.With(e => e.Title = "City Sushi") .With(e => e.Title = "City Sushi")
@ -578,12 +578,12 @@ namespace NzbDrone.Core.Test.OrganizerTests
nameSpecification.IncludeSeriesName = false; namingConfig.IncludeSeriesTitle = false;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = true; namingConfig.IncludeQuality = true;
nameSpecification.Separator = "."; ; namingConfig.Separator = "."; ;
nameSpecification.NumberStyle = 0; namingConfig.NumberStyle = 0;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
var episode = Builder<Episode>.CreateNew() var episode = Builder<Episode>.CreateNew()
.With(e => e.Title = "City Sushi") .With(e => e.Title = "City Sushi")
@ -603,13 +603,13 @@ namespace NzbDrone.Core.Test.OrganizerTests
{ {
nameSpecification.IncludeSeriesName = false; namingConfig.IncludeSeriesTitle = false;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = true; namingConfig.IncludeQuality = true;
nameSpecification.Separator = "."; ; namingConfig.Separator = "."; ;
nameSpecification.NumberStyle = 0; namingConfig.NumberStyle = 0;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
nameSpecification.UseSceneName = true; namingConfig.UseSceneName = true;
var episode = Builder<Episode>.CreateNew() var episode = Builder<Episode>.CreateNew()
.With(e => e.Title = "City Sushi") .With(e => e.Title = "City Sushi")
@ -634,13 +634,13 @@ namespace NzbDrone.Core.Test.OrganizerTests
{ {
nameSpecification.IncludeSeriesName = false; namingConfig.IncludeSeriesTitle = false;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = true; namingConfig.IncludeQuality = true;
nameSpecification.Separator = "."; namingConfig.Separator = ".";
nameSpecification.NumberStyle = 0; namingConfig.NumberStyle = 0;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
nameSpecification.UseSceneName = true; namingConfig.UseSceneName = true;
var episode = Builder<Episode>.CreateNew() var episode = Builder<Episode>.CreateNew()
.With(e => e.Title = "City Sushi") .With(e => e.Title = "City Sushi")
@ -665,13 +665,13 @@ namespace NzbDrone.Core.Test.OrganizerTests
{ {
nameSpecification.IncludeSeriesName = true; namingConfig.IncludeSeriesTitle = true;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = false; namingConfig.IncludeQuality = false;
nameSpecification.Separator = " - "; namingConfig.Separator = " - ";
nameSpecification.NumberStyle = 2; namingConfig.NumberStyle = 2;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
nameSpecification.MultiEpisodeStyle = 3; namingConfig.MultiEpisodeStyle = 3;
var episode = Builder<Episode>.CreateNew() var episode = Builder<Episode>.CreateNew()
.With(e => e.Title = "Hey, Baby, What's Wrong? (1)") .With(e => e.Title = "Hey, Baby, What's Wrong? (1)")
@ -697,13 +697,13 @@ namespace NzbDrone.Core.Test.OrganizerTests
{ {
nameSpecification.IncludeSeriesName = true; namingConfig.IncludeSeriesTitle = true;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = false; namingConfig.IncludeQuality = false;
nameSpecification.Separator = " - "; namingConfig.Separator = " - ";
nameSpecification.NumberStyle = 2; namingConfig.NumberStyle = 2;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
nameSpecification.MultiEpisodeStyle = 3; namingConfig.MultiEpisodeStyle = 3;
var episode = Builder<Episode>.CreateNew() var episode = Builder<Episode>.CreateNew()
.With(e => e.Title = "Hello") .With(e => e.Title = "Hello")
@ -729,13 +729,13 @@ namespace NzbDrone.Core.Test.OrganizerTests
{ {
nameSpecification.IncludeSeriesName = true; namingConfig.IncludeSeriesTitle = true;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = false; namingConfig.IncludeQuality = false;
nameSpecification.Separator = " - "; namingConfig.Separator = " - ";
nameSpecification.NumberStyle = 2; namingConfig.NumberStyle = 2;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
nameSpecification.MultiEpisodeStyle = 3; namingConfig.MultiEpisodeStyle = 3;
var episode = Builder<Episode>.CreateNew() var episode = Builder<Episode>.CreateNew()
.With(e => e.Title = "Hello (3)") .With(e => e.Title = "Hello (3)")
@ -766,12 +766,12 @@ namespace NzbDrone.Core.Test.OrganizerTests
public void should_use_airDate_if_series_isDaily() public void should_use_airDate_if_series_isDaily()
{ {
nameSpecification.IncludeSeriesName = true; namingConfig.IncludeSeriesTitle = true;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = true; namingConfig.IncludeQuality = true;
nameSpecification.Separator = " - "; namingConfig.Separator = " - ";
nameSpecification.NumberStyle = 2; namingConfig.NumberStyle = 2;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
var series = Builder<Series> var series = Builder<Series>
.CreateNew() .CreateNew()
@ -795,12 +795,12 @@ namespace NzbDrone.Core.Test.OrganizerTests
public void should_use_airDate_if_series_isDaily_no_episode_title() public void should_use_airDate_if_series_isDaily_no_episode_title()
{ {
nameSpecification.IncludeSeriesName = true; namingConfig.IncludeSeriesTitle = true;
nameSpecification.IncludeEpisodeTitle = false; namingConfig.IncludeEpisodeTitle = false;
nameSpecification.AppendQuality = false; namingConfig.IncludeQuality = false;
nameSpecification.Separator = " - "; namingConfig.Separator = " - ";
nameSpecification.NumberStyle = 2; namingConfig.NumberStyle = 2;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
var series = Builder<Series> var series = Builder<Series>
.CreateNew() .CreateNew()
@ -824,12 +824,12 @@ namespace NzbDrone.Core.Test.OrganizerTests
public void should_set_airdate_to_unknown_if_not_available() public void should_set_airdate_to_unknown_if_not_available()
{ {
nameSpecification.IncludeSeriesName = true; namingConfig.IncludeSeriesTitle = true;
nameSpecification.IncludeEpisodeTitle = true; namingConfig.IncludeEpisodeTitle = true;
nameSpecification.AppendQuality = false; namingConfig.IncludeQuality = false;
nameSpecification.Separator = " - "; namingConfig.Separator = " - ";
nameSpecification.NumberStyle = 2; namingConfig.NumberStyle = 2;
nameSpecification.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
var series = Builder<Series> var series = Builder<Series>
.CreateNew() .CreateNew()

@ -29,10 +29,15 @@ namespace NzbDrone.Core.Datastore
bool HasItems(); bool HasItems();
void DeleteMany(IEnumerable<int> ids); void DeleteMany(IEnumerable<int> ids);
void SetFields(TModel model, params Expression<Func<TModel, object>>[] properties); void SetFields(TModel model, params Expression<Func<TModel, object>>[] properties);
TModel Single();
} }
public class BasicRepository<TModel> : IBasicRepository<TModel> where TModel : ModelBase, new() public class BasicRepository<TModel> : IBasicRepository<TModel> where TModel : ModelBase, new()
{ {
//TODO: add assertion to make sure model properly mapped
private readonly IDataMapper _dataMapper; private readonly IDataMapper _dataMapper;
public BasicRepository(IDatabase database) public BasicRepository(IDatabase database)
@ -78,6 +83,11 @@ namespace NzbDrone.Core.Datastore
} }
public TModel SingleOrDefault() public TModel SingleOrDefault()
{
return All().SingleOrDefault();
}
public TModel Single()
{ {
return All().Single(); return All().Single();
} }

@ -127,6 +127,17 @@ namespace NzbDrone.Core.Datastore.Migration
.WithColumn("TvdbId").AsInt32() .WithColumn("TvdbId").AsInt32()
.WithColumn("SeasonNumber").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() protected override void LogDbUpgrade()

@ -13,6 +13,7 @@ using NzbDrone.Core.Indexers.Newznab;
using NzbDrone.Core.Instrumentation; using NzbDrone.Core.Instrumentation;
using NzbDrone.Core.Jobs; using NzbDrone.Core.Jobs;
using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Qualities; using NzbDrone.Core.Qualities;
using NzbDrone.Core.RootFolders; using NzbDrone.Core.RootFolders;
using NzbDrone.Core.SeriesStats; using NzbDrone.Core.SeriesStats;
@ -58,6 +59,8 @@ namespace NzbDrone.Core.Datastore
Mapper.Entity<Log>().RegisterModel("Logs"); Mapper.Entity<Log>().RegisterModel("Logs");
Mapper.Entity<NamingConfig>().RegisterModel("NamingConfig");
Mapper.Entity<SeriesStatistics>().MapResultSet(); Mapper.Entity<SeriesStatistics>().MapResultSet();
} }

@ -342,7 +342,7 @@
<Compile Include="Indexers\Nzbx\NzbxRecentItem.cs" /> <Compile Include="Indexers\Nzbx\NzbxRecentItem.cs" />
<Compile Include="Model\PostDownloadStatusType.cs" /> <Compile Include="Model\PostDownloadStatusType.cs" />
<Compile Include="Model\MisnamedEpisodeModel.cs" /> <Compile Include="Model\MisnamedEpisodeModel.cs" />
<Compile Include="Organizer\NameSpecification.cs" /> <Compile Include="Organizer\NamingConfig.cs" />
<Compile Include="Parser\Language.cs" /> <Compile Include="Parser\Language.cs" />
<Compile Include="Parser\Model\LocalEpisode.cs" /> <Compile Include="Parser\Model\LocalEpisode.cs" />
<Compile Include="Parser\Model\ParsedEpisodeInfo.cs" /> <Compile Include="Parser\Model\ParsedEpisodeInfo.cs" />

@ -15,27 +15,58 @@ namespace NzbDrone.Core.Organizer
string BuildFilePath(Series series, int seasonNumber, string fileName, string extension); string BuildFilePath(Series series, int seasonNumber, string fileName, string extension);
} }
public class FileNameBuilder : IBuildFileNames public interface INamingConfigService
{ {
private readonly IBasicRepository<NameSpecification> _nameSpecificationRepository; NamingConfig GetConfig();
private readonly Logger _logger; NamingConfig Save(NamingConfig namingConfig);
}
public FileNameBuilder(IBasicRepository<NameSpecification> nameSpecificationRepository, Logger logger) public class NamingConfigService : INamingConfigService
{
private readonly IBasicRepository<NamingConfig> _repository;
public NamingConfigService(IBasicRepository<NamingConfig> repository)
{ {
_nameSpecificationRepository = nameSpecificationRepository; _repository = repository;
_logger = logger; }
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 NameSpecification GetSpecification() public class FileNameBuilder : IBuildFileNames
{
private readonly INamingConfigService _namingConfigService;
private readonly Logger _logger;
public FileNameBuilder(INamingConfigService namingConfigService, Logger logger)
{ {
return _nameSpecificationRepository.SingleOrDefault() ?? NameSpecification.Default; _namingConfigService = namingConfigService;
_logger = logger;
} }
public string BuildFilename(IList<Episode> episodes, Series series, EpisodeFile episodeFile) public string BuildFilename(IList<Episode> episodes, Series series, EpisodeFile episodeFile)
{ {
var nameSpec = GetSpecification(); var nameSpec = _namingConfigService.GetConfig();
if (nameSpec.UseSceneName) if (nameSpec.UseSceneName)
{ {
@ -58,7 +89,7 @@ namespace NzbDrone.Core.Organizer
var result = String.Empty; var result = String.Empty;
if (nameSpec.IncludeSeriesName) if (nameSpec.IncludeSeriesTitle)
{ {
result += series.Title + nameSpec.Separator; result += series.Title + nameSpec.Separator;
} }
@ -114,7 +145,7 @@ namespace NzbDrone.Core.Organizer
result += nameSpec.Separator + String.Join(" + ", episodeNames.Distinct()); result += nameSpec.Separator + String.Join(" + ", episodeNames.Distinct());
} }
if (nameSpec.AppendQuality) if (nameSpec.IncludeQuality)
{ {
result += String.Format(" [{0}]", episodeFile.Quality.Quality); result += String.Format(" [{0}]", episodeFile.Quality.Quality);
@ -132,7 +163,7 @@ namespace NzbDrone.Core.Organizer
public string BuildFilePath(Series series, int seasonNumber, string fileName, string extension) public string BuildFilePath(Series series, int seasonNumber, string fileName, string extension)
{ {
var nameSpec = GetSpecification(); var nameSpec = _namingConfigService.GetConfig();
string path = series.Path; string path = series.Path;
if (series.SeasonFolder) if (series.SeasonFolder)

@ -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; }
}
}

@ -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; }
}
}

@ -35,7 +35,7 @@ namespace NzbDrone
Container.Register<Router>().AsSingleton(); Container.Register<Router>().AsSingleton();
Container.Register(typeof(IBasicRepository<RootFolder>), typeof(BasicRepository<RootFolder>)).AsMultiInstance(); Container.Register(typeof(IBasicRepository<RootFolder>), typeof(BasicRepository<RootFolder>)).AsMultiInstance();
Container.Register(typeof(IBasicRepository<NameSpecification>), typeof(BasicRepository<NameSpecification>)).AsMultiInstance(); Container.Register(typeof(IBasicRepository<NamingConfig>), typeof(BasicRepository<NamingConfig>)).AsMultiInstance();
InitDatabase(); InitDatabase();

@ -61,7 +61,7 @@
<option passfail="false" /> <option passfail="false" />
<option white="false" /> <option white="false" />
<option maxerr="50" /> <option maxerr="50" />
<option predef="NzbDrone, define, Backbone, _, window,Handlebars, console,require,$,Marionette, Backgrid" /> <option predef="NzbDrone, define, Backbone, _, window,Handlebars, console,require,$,Marionette, Backgrid, jQuery" />
</component> </component>
</project> </project>

@ -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);
};

@ -25,8 +25,8 @@ define(['app'], function () {
name : 'airDate', name : 'airDate',
label : 'Air Date', label : 'Air Date',
editable : false, editable : false,
cell : 'datetime', cell : 'datetime'
formatter: new Backgrid.AirDateFormatter() //formatter: new Backgrid.AirDateFormatter()
} }
], ],

@ -2,17 +2,12 @@
define([ define([
'app', 'app',
'Series/Index/List/CollectionView', 'Series/Index/List/CollectionView',
<<<<<<< HEAD
'Config'
'Series/Index/Posters/CollectionView', 'Series/Index/Posters/CollectionView',
'Series/Index/EmptyView', 'Series/Index/EmptyView',
'Config',
'Series/Index/Table/AirDateCell', 'Series/Index/Table/AirDateCell',
'Series/Index/Table/SeriesStatusCell' 'Series/Index/Table/SeriesStatusCell',
'Shared/Toolbar/ToolbarView', 'Shared/Toolbar/ToolbarView',
=======
'Shared/Toolbar/ToolbarLayout', 'Shared/Toolbar/ToolbarLayout',
>>>>>>> added support for multi-button groups to toolbar
'Config' 'Config'
], ],
function () { function () {
@ -34,128 +29,74 @@ define([
showTable: function () { showTable: function () {
var columns = 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(
{ {
name: 'status', name : 'status',
label: '', label : '',
editable: false, editable : false,
cell: 'seriesStatus', cell : 'seriesStatus',
headerCell: 'nzbDrone' headerCell: 'nzbDrone'
}, },
{ {
name: 'title', name : 'title',
label: 'Title', label : 'Title',
editable: false, editable : false,
cell: Backgrid.TemplateBackedCell.extend({ template: 'Series/Index/Table/SeriesTitleTemplate' }), cell : Backgrid.TemplateBackedCell.extend({ template: 'Series/Index/Table/SeriesTitleTemplate' }),
headerCell: 'nzbDrone' headerCell: 'nzbDrone'
}, },
{ {
name: 'seasonCount', name : 'seasonCount',
label: 'Seasons', label : 'Seasons',
editable: false, editable : false,
cell: 'integer', cell : 'integer',
headerCell: 'nzbDrone' headerCell: 'nzbDrone'
}, },
{ {
name: 'quality', name : 'quality',
label: 'Quality', label : 'Quality',
editable: false, editable : false,
cell: 'integer', cell : 'integer',
headerCell: 'nzbDrone' headerCell: 'nzbDrone'
}, },
{ {
name: 'network', name : 'network',
label: 'Network', label : 'Network',
editable: false, editable : false,
cell: 'string', cell : 'string',
headerCell: 'nzbDrone' headerCell: 'nzbDrone'
}, },
{ {
name: 'nextAiring', name : 'nextAiring',
label: 'Next Airing', label : 'Next Airing',
editable: false, editable : false,
cell: 'airDate', cell : 'airDate',
headerCell: 'nzbDrone' headerCell: 'nzbDrone'
}, },
{ {
name: 'episodes', name : 'episodes',
label: 'Episodes', label : 'Episodes',
editable: false, editable : false,
sortable: false, sortable : false,
cell: Backgrid.TemplateBackedCell.extend({ template: 'Series/EpisodeProgressTemplate' }), cell : Backgrid.TemplateBackedCell.extend({ template: 'Series/EpisodeProgressTemplate' }),
headerCell: 'nzbDrone' headerCell: 'nzbDrone'
}, },
{ {
name: 'edit', name : 'edit',
label: '', label : '',
editable: false, editable : false,
sortable: false, sortable : false,
cell: Backgrid.TemplateBackedCell.extend({ template: 'Series/Index/Table/ControlsColumnTemplate' }), cell : Backgrid.TemplateBackedCell.extend({ template: 'Series/Index/Table/ControlsColumnTemplate' }),
headerCell: 'nzbDrone' headerCell: 'nzbDrone'
} }
]; ];
this.series.show(new Backgrid.Grid( this.series.show(new Backgrid.Grid(
{ {
row: Backgrid.SeriesIndexTableRow, row : Backgrid.SeriesIndexTableRow,
columns : columns, columns : columns,
collection : this.seriesCollection, collection: this.seriesCollection,
className: 'table table-hover' 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: "RSS Sync", icon: "icon-rss"}));
menuRight.add(new NzbDrone.Shared.Toolbar.CommandModel({title: "Sync Database", icon: "icon-refresh"})); 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) { switch (this.viewStyle) {
case 1: case 1:

@ -9,7 +9,7 @@
margin-top: 0px; margin-top: 0px;
} }
a{ a {
color: #000000; color: #000000;
} }
} }
@ -21,70 +21,71 @@
display: inline-block; display: inline-block;
vertical-align: top; vertical-align: top;
} }
.series-page-header { .series-page-header {
padding-bottom: 50px; padding-bottom: 50px;
}
.series-posters-item {
margin-bottom: 20px;
.center {
display: block;
margin-left:auto;
margin-right:auto;
text-align: center;
} }
.progress { .series-posters-item {
left: 22px; margin-bottom: 20px;
margin-top: 5px;
}
.title { .center {
font-size: 17px; display: block;
text-rendering: optimizelegibility; margin-left: auto;
} margin-right: auto;
text-align: center;
.labels { }
display: inline-block;
opacity: 0.75;
width: 138px;
:hover { .progress {
cursor: default; left: 22px;
margin-top: 5px;
} }
.label { .title {
margin-top: 3px; font-size: 17px;
display: block; text-rendering: optimizelegibility;
} }
.tooltip { .labels {
opacity: 1; 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 { .series-poster-container {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
display: inline-block; display: inline-block;
.ended-banner { .ended-banner {
color: #EEEEEE; color: #eeeeee;
background-color: #B94A48; background-color: #b94a48;
-moz-box-shadow: 2px 2px 20px #888; -moz-box-shadow: 2px 2px 20px #888888;
-moz-transform: rotate(45deg); -moz-transform: rotate(45deg);
-moz-transform-origin: 50% 50%; -moz-transform-origin: 50% 50%;
-webkit-transform: rotate(45deg); -webkit-transform: rotate(45deg);
-webkit-transform-origin: 50% 50%; -webkit-transform-origin: 50% 50%;
position: absolute; position: absolute;
width: 300px; width: 300px;
top: 175px; top: 175px;
left: -122px; left: -122px;
text-align: center; text-align: center;
}
} }
} }

@ -0,0 +1,6 @@
"use strict";
define(['app'], function () {
NzbDrone.Settings.Naming.NamingModel = Backbone.Model.extend({
url: NzbDrone.Constants.ApiRoot + '/config/naming'
});
});

@ -5,9 +5,7 @@
<label class="control-label">Use Scene Name</label> <label class="control-label">Use Scene Name</label>
<div class="controls"> <div class="controls">
<div class="switch"> <input type="checkbox" name="useSceneName"/>
<input type="checkbox" name="sortingUseSceneName"/>
</div>
<span class="help-inline-checkbox"> <span class="help-inline-checkbox">
<i class="icon-question-sign" title="Use the scene name, ignoring all other naming settings"></i> <i class="icon-question-sign" title="Use the scene name, ignoring all other naming settings"></i>
</span> </span>
@ -15,12 +13,10 @@
</div> </div>
<div class="control-group"> <div class="control-group">
<label class="control-label">Series Name</label> <label class="control-label">Include Series Title</label>
<div class="controls"> <div class="controls">
<div class="switch"> <input type="checkbox" name="includeSeriesTitle"/>
<input type="checkbox" name="sortingIncludeSeriesName"/>
</div>
<span class="help-inline-checkbox"> <span class="help-inline-checkbox">
<i class="icon-question-sign" title="Should filenames contain the series name when renamed?"></i> <i class="icon-question-sign" title="Should filenames contain the series name when renamed?"></i>
</span> </span>
@ -28,12 +24,10 @@
</div> </div>
<div class="control-group"> <div class="control-group">
<label class="control-label">Episode Name</label> <label class="control-label">Include Episode Title</label>
<div class="controls"> <div class="controls">
<div class="switch"> <input type="checkbox" name="includeEpisodeTitle"/>
<input type="checkbox" name="sortingIncludeEpisodeTitle"/>
</div>
<span class="help-inline-checkbox"> <span class="help-inline-checkbox">
<i class="icon-question-sign" title="Should filenames contain the episode name when renamed?"></i> <i class="icon-question-sign" title="Should filenames contain the episode name when renamed?"></i>
</span> </span>
@ -45,7 +39,7 @@
<div class="controls"> <div class="controls">
<div class="switch"> <div class="switch">
<input type="checkbox" name="sortingReplaceSpaces"/> <input type="checkbox" name="replaceSpaces"/>
</div> </div>
<span class="help-inline-checkbox"> <span class="help-inline-checkbox">
<i class="icon-question-sign" title="Do you want to replace spaces in the filename with periods?"></i> <i class="icon-question-sign" title="Do you want to replace spaces in the filename with periods?"></i>
@ -54,11 +48,11 @@
</div> </div>
<div class="control-group"> <div class="control-group">
<label class="control-label">Append Quality</label> <label class="control-label">Include Quality</label>
<div class="controls"> <div class="controls">
<div class="switch"> <div class="switch">
<input type="checkbox" name="sortingAppendQuality"/> <input type="checkbox" name="includeQuality"/>
</div> </div>
<span class="help-inline-checkbox"> <span class="help-inline-checkbox">
<i class="icon-question-sign" title="Should filenames have the quality appended to the end?"></i> <i class="icon-question-sign" title="Should filenames have the quality appended to the end?"></i>
@ -67,25 +61,11 @@
</div> </div>
</div> </div>
<div class="control-group">
<label class="control-label">Use Season Folders</label>
<div class="controls">
<div class="switch">
<input type="checkbox" name="useSeasonFolder"/>
</div>
<span class="help-inline-checkbox">
<i class="icon-question-sign" title="Should files be stored in season folders by default? (Applied only when a series is added)"></i>
</span>
</div>
</div>
<div class="control-group"> <div class="control-group">
<label class="control-label">Season Folder Format</label> <label class="control-label">Season Folder Format</label>
<div class="controls"> <div class="controls">
<input type="text" placeholder="Season %s" name="sortingSeasonFolderFormat"/> <input type="text" placeholder="Season %s" name="seasonFolderFormat"/>
<span class="help-inline"> <span class="help-inline">
<i class="icon-question-sign" title="How should season folders be named? (Use %0s to pad to two digits)"></i> <i class="icon-question-sign" title="How should season folders be named? (Use %0s to pad to two digits)"></i>
</span> </span>
@ -93,13 +73,13 @@
</div> </div>
<div class="control-group"> <div class="control-group">
<label class="control-label">Separator Style</label> <label class="control-label">Separator</label>
<div class="controls"> <div class="controls">
<select class="inputClass x-backlog-setting" name="sortingSeparatorStyle"> <select class="inputClass x-backlog-setting" name="separator">
<option value="0">Dash</option> <option value=" - ">Dash</option>
<option value="1">Space</option> <option value=" ">Space</option>
<option value="2">Period</option> <option value=".">Period</option>
</select> </select>
<span class="help-inline"> <span class="help-inline">
<i class="icon-question-sign" title="How should NzbDrone separate sections of the filename?"></i> <i class="icon-question-sign" title="How should NzbDrone separate sections of the filename?"></i>
@ -111,7 +91,7 @@
<label class="control-label">Numbering Style</label> <label class="control-label">Numbering Style</label>
<div class="controls"> <div class="controls">
<select class="inputClass x-backlog-setting" name="sortingNumberStyle"> <select class="inputClass x-backlog-setting" name="numberStyle">
<option value="0">1x05</option> <option value="0">1x05</option>
<option value="1">01x05</option> <option value="1">01x05</option>
<option value="2">S01E05</option> <option value="2">S01E05</option>
@ -127,7 +107,7 @@
<label class="control-label">Multi-Episode Style</label> <label class="control-label">Multi-Episode Style</label>
<div class="controls"> <div class="controls">
<select class="inputClass x-backlog-setting" name="sortingMultiEpisodeStyle"> <select class="inputClass x-backlog-setting" name="multiEpisodeStyle">
<option value="0">Extend</option> <option value="0">Extend</option>
<option value="1">Duplicate</option> <option value="1">Duplicate</option>
<option value="2">Repeat</option> <option value="2">Repeat</option>
@ -168,4 +148,4 @@
</span> </span>
</div> </div>
</div> </div>
</fieldset> </fieldset>

@ -1,9 +1,5 @@
'use strict'; 'use strict';
define(['app', 'Settings/Naming/NamingModel'], function () {
define([
'app', 'Settings/SettingsModel'
], function () {
NzbDrone.Settings.Naming.NamingView = Backbone.Marionette.ItemView.extend({ NzbDrone.Settings.Naming.NamingView = Backbone.Marionette.ItemView.extend({
template : 'Settings/Naming/NamingTemplate', template : 'Settings/Naming/NamingTemplate',
@ -14,11 +10,32 @@ define([
}, },
initialize: function () { 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 () { onRender: function () {
this.ui.tooltip.tooltip({ placement: 'right' }); 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);
}
};
} }
}); });
}); })
;

@ -150,8 +150,22 @@ define([
}, },
save: function () { 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");
}
});
} }
}); })
}); ;
})
;

@ -60,11 +60,16 @@ define('app', function () {
window.NzbDrone.Missing = {}; window.NzbDrone.Missing = {};
window.NzbDrone.Events = { window.NzbDrone.Events = {
//TODO: Move to commands
OpenModalDialog : 'openModal', OpenModalDialog : 'openModal',
CloseModalDialog: 'closeModal', CloseModalDialog: 'closeModal',
SeriesAdded: 'seriesAdded' SeriesAdded: 'seriesAdded'
}; };
window.NzbDrone.Commands = {
SaveSettings : 'saveSettings'
};
window.NzbDrone.Constants = { window.NzbDrone.Constants = {
ApiRoot: '/api' ApiRoot: '/api'
}; };

Loading…
Cancel
Save