Media Management settings are alive

pull/4/head
Mark McDowall 12 years ago
parent 943a05bc09
commit 3f6a6d53d5

@ -23,7 +23,6 @@ namespace NzbDrone.Api.Config
SharedValidator.RuleFor(c => c.MultiEpisodeStyle).InclusiveBetween(0, 3); SharedValidator.RuleFor(c => c.MultiEpisodeStyle).InclusiveBetween(0, 3);
SharedValidator.RuleFor(c => c.NumberStyle).InclusiveBetween(0, 3); SharedValidator.RuleFor(c => c.NumberStyle).InclusiveBetween(0, 3);
SharedValidator.RuleFor(c => c.SeasonFolderFormat).NotEmpty();
SharedValidator.RuleFor(c => c.Separator).Matches(@"\s|\s\-\s|\."); SharedValidator.RuleFor(c => c.Separator).Matches(@"\s|\s\-\s|\.");
} }
@ -42,10 +41,9 @@ namespace NzbDrone.Api.Config
{ {
public Boolean IncludeEpisodeTitle { get; set; } public Boolean IncludeEpisodeTitle { get; set; }
public Boolean ReplaceSpaces { get; set; } public Boolean ReplaceSpaces { get; set; }
public Boolean UseSceneName { get; set; } public Boolean RenameEpisodes { get; set; }
public Int32 MultiEpisodeStyle { get; set; } public Int32 MultiEpisodeStyle { get; set; }
public Int32 NumberStyle { get; set; } public Int32 NumberStyle { get; set; }
public String SeasonFolderFormat { get; set; }
public String Separator { get; set; } public String Separator { get; set; }
public Boolean IncludeQuality { get; set; } public Boolean IncludeQuality { get; set; }
public Boolean IncludeSeriesTitle { get; set; } public Boolean IncludeSeriesTitle { get; set; }

@ -55,10 +55,8 @@ namespace NzbDrone.Core.Test.MediaFileTests
.Setup(e => e.BuildFilePath(It.IsAny<Series>(), fakeEpisode.First().SeasonNumber, filename, ".avi")) .Setup(e => e.BuildFilePath(It.IsAny<Series>(), fakeEpisode.First().SeasonNumber, filename, ".avi"))
.Returns(fi); .Returns(fi);
var result = Subject.MoveEpisodeFile(file, false); var result = Subject.MoveEpisodeFile(file, false);
result.Should().BeNull(); result.Should().BeNull();
} }

@ -22,24 +22,5 @@ namespace NzbDrone.Core.Test.MediaFileTests
{ {
FileNameBuilder.CleanFilename(name).Should().Be(expectedName); FileNameBuilder.CleanFilename(name).Should().Be(expectedName);
} }
[Test]
[TestCase("30 Rock - S01E05 - Episode Title", 1, true, "Season %0s", @"C:\Test\30 Rock\Season 01\30 Rock - S01E05 - Episode Title.mkv")]
[TestCase("30 Rock - S01E05 - Episode Title", 1, true, "Season %s", @"C:\Test\30 Rock\Season 1\30 Rock - S01E05 - Episode Title.mkv")]
[TestCase("30 Rock - S01E05 - Episode Title", 1, false, "Season %0s", @"C:\Test\30 Rock\30 Rock - S01E05 - Episode Title.mkv")]
[TestCase("30 Rock - S01E05 - Episode Title", 1, false, "Season %s", @"C:\Test\30 Rock\30 Rock - S01E05 - Episode Title.mkv")]
[TestCase("30 Rock - S01E05 - Episode Title", 1, true, "ReallyUglySeasonFolder %s", @"C:\Test\30 Rock\ReallyUglySeasonFolder 1\30 Rock - S01E05 - Episode Title.mkv")]
public void CalculateFilePath_SeasonFolder_SingleNumber(string filename, int seasonNumber, bool useSeasonFolder, string seasonFolderFormat, string expectedPath)
{
var fakeSeries = Builder<Series>.CreateNew()
.With(s => s.Title = "30 Rock")
.With(s => s.Path = @"C:\Test\30 Rock")
.With(s => s.SeasonFolder = useSeasonFolder)
.Build();
Mocker.GetMock<IConfigService>().Setup(e => e.SortingSeasonFolderFormat).Returns(seasonFolderFormat);
Subject.CalculateFilePath(fakeSeries, 1, filename, ".mkv").FullName.Should().Be(expectedPath);
}
} }
} }

@ -161,6 +161,7 @@
<Compile Include="NotificationTests\Xbmc\Json\CheckForErrorFixture.cs" /> <Compile Include="NotificationTests\Xbmc\Json\CheckForErrorFixture.cs" />
<Compile Include="NotificationTests\Xbmc\Json\GetSeriesPathFixture.cs" /> <Compile Include="NotificationTests\Xbmc\Json\GetSeriesPathFixture.cs" />
<Compile Include="NotificationTests\Xbmc\Json\UpdateFixture.cs" /> <Compile Include="NotificationTests\Xbmc\Json\UpdateFixture.cs" />
<Compile Include="OrganizerTests\BuildFilePathFixture.cs" />
<Compile Include="Qualities\QualitySizeRepositoryFixture.cs" /> <Compile Include="Qualities\QualitySizeRepositoryFixture.cs" />
<Compile Include="Qualities\QualityProfileRepositoryFixture.cs" /> <Compile Include="Qualities\QualityProfileRepositoryFixture.cs" />
<Compile Include="RootFolderTests\FreeSpaceOnDrivesFixture.cs" /> <Compile Include="RootFolderTests\FreeSpaceOnDrivesFixture.cs" />

@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.IO;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.OrganizerTests
{
[TestFixture]
public class BuildFilePathFixture : CoreTest<FileNameBuilder>
{
private Series _series;
private NamingConfig namingConfig;
[SetUp]
public void Setup()
{
_series = Builder<Series>
.CreateNew()
.With(s => s.Title = "South Park")
.Build();
namingConfig = new NamingConfig();
Mocker.GetMock<INamingConfigService>()
.Setup(c => c.GetConfig()).Returns(namingConfig);
}
[Test]
[TestCase("30 Rock - S01E05 - Episode Title", 1, true, "Season %0s", @"C:\Test\30 Rock\Season 01\30 Rock - S01E05 - Episode Title.mkv")]
[TestCase("30 Rock - S01E05 - Episode Title", 1, true, "Season %s", @"C:\Test\30 Rock\Season 1\30 Rock - S01E05 - Episode Title.mkv")]
[TestCase("30 Rock - S01E05 - Episode Title", 1, false, "Season %0s", @"C:\Test\30 Rock\30 Rock - S01E05 - Episode Title.mkv")]
[TestCase("30 Rock - S01E05 - Episode Title", 1, false, "Season %s", @"C:\Test\30 Rock\30 Rock - S01E05 - Episode Title.mkv")]
[TestCase("30 Rock - S01E05 - Episode Title", 1, true, "ReallyUglySeasonFolder %s", @"C:\Test\30 Rock\ReallyUglySeasonFolder 1\30 Rock - S01E05 - Episode Title.mkv")]
public void CalculateFilePath_SeasonFolder_SingleNumber(string filename, int seasonNumber, bool useSeasonFolder, string seasonFolderFormat, string expectedPath)
{
var fakeSeries = Builder<Series>.CreateNew()
.With(s => s.Title = "30 Rock")
.With(s => s.Path = @"C:\Test\30 Rock")
.With(s => s.SeasonFolder = useSeasonFolder)
.Build();
Mocker.GetMock<IConfigService>().Setup(e => e.SeasonFolderFormat).Returns(seasonFolderFormat);
Subject.BuildFilePath(fakeSeries, 1, filename, ".mkv").Should().Be(expectedPath);
}
}
}

@ -534,7 +534,7 @@ namespace NzbDrone.Core.Test.OrganizerTests
namingConfig.Separator = "."; ; namingConfig.Separator = "."; ;
namingConfig.NumberStyle = 0; namingConfig.NumberStyle = 0;
namingConfig.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
namingConfig.UseSceneName = true; namingConfig.RenameEpisodes = false;
var episode = Builder<Episode>.CreateNew() var episode = Builder<Episode>.CreateNew()
.With(e => e.Title = "City Sushi") .With(e => e.Title = "City Sushi")
@ -563,7 +563,7 @@ namespace NzbDrone.Core.Test.OrganizerTests
namingConfig.Separator = "."; namingConfig.Separator = ".";
namingConfig.NumberStyle = 0; namingConfig.NumberStyle = 0;
namingConfig.ReplaceSpaces = false; namingConfig.ReplaceSpaces = false;
namingConfig.UseSceneName = true; namingConfig.RenameEpisodes = false;
var episode = Builder<Episode>.CreateNew() var episode = Builder<Episode>.CreateNew()
.With(e => e.Title = "City Sushi") .With(e => e.Title = "City Sushi")

@ -130,7 +130,7 @@ namespace NzbDrone.Core.Configuration
set { SetValue("UseSeasonFolder", value); } set { SetValue("UseSeasonFolder", value); }
} }
public string SortingSeasonFolderFormat public string SeasonFolderFormat
{ {
get { return GetValue("Sorting_SeasonFolderFormat", "Season %s"); } get { return GetValue("Sorting_SeasonFolderFormat", "Season %s"); }
set { SetValue("Sorting_SeasonFolderFormat", value); } set { SetValue("Sorting_SeasonFolderFormat", value); }

@ -21,7 +21,7 @@ namespace NzbDrone.Core.Configuration
SabPriorityType SabRecentTvPriority { get; set; } SabPriorityType SabRecentTvPriority { get; set; }
String DownloadedEpisodesFolder { get; set; } String DownloadedEpisodesFolder { get; set; }
bool UseSeasonFolder { get; set; } bool UseSeasonFolder { get; set; }
string SortingSeasonFolderFormat { get; set; } string SeasonFolderFormat { get; set; }
bool EnableBacklogSearching { get; set; } bool EnableBacklogSearching { get; set; }
bool AutoIgnorePreviouslyDownloadedEpisodes { get; set; } bool AutoIgnorePreviouslyDownloadedEpisodes { get; set; }
int Retention { get; set; } int Retention { get; set; }

@ -0,0 +1,20 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Tags("")]
[Migration(7)]
public class add_renameEpisodes_to_naming : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("NamingConfig")
.AddColumn("RenameEpisodes")
.AsBoolean()
.Nullable();
Execute.Sql("UPDATE NamingConfig SET RenameEpisodes =~ UseSceneName");
}
}
}

@ -72,25 +72,5 @@ namespace NzbDrone.Core.MediaFiles
var files = GetFilesBySeries(message.Series.Id); var files = GetFilesBySeries(message.Series.Id);
_mediaFileRepository.DeleteMany(files); _mediaFileRepository.DeleteMany(files);
} }
public FileInfo CalculateFilePath(Series series, int seasonNumber, string fileName, string extension)
{
string path = series.Path;
if (series.SeasonFolder)
{
var seasonFolder = _configService.SortingSeasonFolderFormat
.Replace("%sn", series.Title)
.Replace("%s.n", series.Title.Replace(' ', '.'))
.Replace("%s_n", series.Title.Replace(' ', '_'))
.Replace("%0s", seasonNumber.ToString("00"))
.Replace("%s", seasonNumber.ToString());
path = Path.Combine(path, seasonFolder);
}
path = Path.Combine(path, fileName + extension);
return new FileInfo(path);
}
} }
} }

@ -211,6 +211,7 @@
<Compile Include="Datastore\Migration\004_updated_history.cs" /> <Compile Include="Datastore\Migration\004_updated_history.cs" />
<Compile Include="Datastore\Migration\005_added_eventtype_to_history.cs" /> <Compile Include="Datastore\Migration\005_added_eventtype_to_history.cs" />
<Compile Include="Datastore\Migration\006_add_index_to_log_time.cs" /> <Compile Include="Datastore\Migration\006_add_index_to_log_time.cs" />
<Compile Include="Datastore\Migration\007_add_renameEpisodes_to_naming.cs" />
<Compile Include="Datastore\Migration\Framework\MigrationController.cs" /> <Compile Include="Datastore\Migration\Framework\MigrationController.cs" />
<Compile Include="Datastore\Migration\Framework\MigrationExtension.cs" /> <Compile Include="Datastore\Migration\Framework\MigrationExtension.cs" />
<Compile Include="Datastore\Migration\Framework\MigrationOptions.cs" /> <Compile Include="Datastore\Migration\Framework\MigrationOptions.cs" />

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using NLog; using NLog;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
@ -50,25 +51,24 @@ namespace NzbDrone.Core.Organizer
} }
} }
public class FileNameBuilder : IBuildFileNames public class FileNameBuilder : IBuildFileNames
{ {
private readonly IConfigService _configService;
private readonly INamingConfigService _namingConfigService; private readonly INamingConfigService _namingConfigService;
private readonly Logger _logger; private readonly Logger _logger;
public FileNameBuilder(INamingConfigService namingConfigService, Logger logger) public FileNameBuilder(INamingConfigService namingConfigService, IConfigService configService, Logger logger)
{ {
_namingConfigService = namingConfigService; _namingConfigService = namingConfigService;
_configService = configService;
_logger = logger; _logger = logger;
} }
public string BuildFilename(IList<Episode> episodes, Series series, EpisodeFile episodeFile) public string BuildFilename(IList<Episode> episodes, Series series, EpisodeFile episodeFile)
{ {
var nameSpec = _namingConfigService.GetConfig(); var nameSpec = _namingConfigService.GetConfig();
if (nameSpec.UseSceneName) if (!nameSpec.RenameEpisodes)
{ {
if (String.IsNullOrWhiteSpace(episodeFile.SceneName)) if (String.IsNullOrWhiteSpace(episodeFile.SceneName))
{ {
@ -162,13 +162,13 @@ 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 = _namingConfigService.GetConfig();
string path = series.Path; string path = series.Path;
if (series.SeasonFolder) if (series.SeasonFolder)
{ {
var seasonFolder = nameSpec.SeasonFolderFormat var seasonFolder = _configService.SeasonFolderFormat
.Replace("%sn", series.Title)
.Replace("%s.n", series.Title.Replace(' ', '.'))
.Replace("%s_n", series.Title.Replace(' ', '_'))
.Replace("%0s", seasonNumber.ToString("00")) .Replace("%0s", seasonNumber.ToString("00"))
.Replace("%s", seasonNumber.ToString()); .Replace("%s", seasonNumber.ToString());
@ -178,7 +178,6 @@ namespace NzbDrone.Core.Organizer
return Path.Combine(path, fileName + extension); return Path.Combine(path, fileName + extension);
} }
public static string CleanFilename(string name) public static string CleanFilename(string name)
{ {
string result = name; string result = name;
@ -191,7 +190,6 @@ namespace NzbDrone.Core.Organizer
return result.Trim(); return result.Trim();
} }
private static readonly List<EpisodeSortingType> NumberStyles = new List<EpisodeSortingType> private static readonly List<EpisodeSortingType> NumberStyles = new List<EpisodeSortingType>
{ {
new EpisodeSortingType new EpisodeSortingType

@ -10,7 +10,7 @@ namespace NzbDrone.Core.Organizer
{ {
return new NamingConfig return new NamingConfig
{ {
UseSceneName = false, RenameEpisodes = true,
Separator = " - ", Separator = " - ",
NumberStyle = 0, NumberStyle = 0,
IncludeSeriesTitle = true, IncludeSeriesTitle = true,
@ -18,12 +18,12 @@ namespace NzbDrone.Core.Organizer
IncludeEpisodeTitle = true, IncludeEpisodeTitle = true,
IncludeQuality = true, IncludeQuality = true,
ReplaceSpaces = false, ReplaceSpaces = false,
SeasonFolderFormat = "Season %s" SeasonFolderFormat = "DO_NOT_USE"
}; };
} }
} }
public bool UseSceneName { get; set; } public bool RenameEpisodes { get; set; }
public string Separator { get; set; } public string Separator { get; set; }
@ -39,6 +39,8 @@ namespace NzbDrone.Core.Organizer
public bool ReplaceSpaces { get; set; } public bool ReplaceSpaces { get; set; }
//Todo: remove - not used
public string SeasonFolderFormat { get; set; } public string SeasonFolderFormat { get; set; }
public bool UseSceneName { get; set; }
} }
} }

@ -2,5 +2,5 @@
{{#each this}} {{#each this}}
<option value="{{id}}">{{path}}</option> <option value="{{id}}">{{path}}</option>
{{/each}} {{/each}}
<option value="addNew">Add a diffrent path</option> <option value="addNew">Add a different path</option>
</select> </select>

@ -1,11 +1,5 @@
.control-group { .control-group {
.controls { .controls {
i.danger {
color : #b94a48;
}
i.warning {
color : #f89406;
}
i { i {
font-size : 16px; font-size : 16px;
color : #595959; color : #595959;
@ -19,8 +13,6 @@
margin-bottom : 0px; margin-bottom : 0px;
} }
.help-inline-checkbox { .help-inline-checkbox {
padding-left : 5px; padding-left : 5px;
display : inline-block; display : inline-block;

@ -57,3 +57,17 @@
.icon-nd-add:before { .icon-nd-add:before {
.icon(@plus); .icon(@plus);
} }
.icon-form-info:before {
.icon(@question-sign);
}
.icon-form-warning:before {
.icon(@warning-sign);
color : #f89406;
}
.icon-form-danger:before {
.icon(@exclamation-sign);
color : #b94a48;
}

@ -0,0 +1,13 @@
'use strict';
define(
[
'marionette',
'Mixins/AsModelBoundView'
], function (Marionette, AsModelBoundView) {
var view = Marionette.ItemView.extend({
template: 'Settings/MediaManagement/FileManagement/ViewTemplate'
});
return AsModelBoundView.call(view);
});

@ -0,0 +1,23 @@
<fieldset>
<legend>File Management</legend>
<div class="control-group">
<label class="control-label">Ignore Deleted Episodes</label>
<div class="controls">
<label class="checkbox toggle well">
<input type="checkbox" name="autoIgnorePreviouslyDownloadedEpisodes"/>
<p>
<span>Yes</span>
<span>No</span>
</p>
<div class="btn btn-primary slide-button"/>
</label>
<span class="help-inline-checkbox">
<i class="icon-question-sign" title="Episodes deleted from disk are automatically ignored in NzbDrone"/>
</span>
</div>
</div>
</fieldset>

@ -0,0 +1,31 @@
"use strict";
define(
[
'marionette',
'Settings/MediaManagement/Naming/View',
'Settings/MediaManagement/Sorting/View',
'Settings/MediaManagement/FileManagement/View'
], function (Marionette, NamingView, SortingView, FileManagementView) {
return Marionette.Layout.extend({
template: 'Settings/MediaManagement/LayoutTemplate',
regions: {
episodeNaming : '#episode-naming',
sorting : '#sorting',
fileManagement : '#file-management'
},
initialize: function (options) {
this.settings = options.settings;
this.namingSettings = options.namingSettings;
},
onRender: function () {
this.episodeNaming.show(new NamingView({ model: this.namingSettings }));
this.sorting.show(new SortingView({ model: this.settings }));
this.fileManagement.show(new FileManagementView({ model: this.settings }));
}
});
});

@ -0,0 +1,5 @@
<div class="form-horizontal">
<div id="episode-naming"></div>
<div id="sorting"></div>
<div id="file-management"></div>
</div>

@ -5,7 +5,7 @@ define(
], function (ModelBase) { ], function (ModelBase) {
return ModelBase.extend({ return ModelBase.extend({
url : window.ApiRoot + '/config/naming', url : window.ApiRoot + '/config/naming',
successMessage: 'Naming settings saved', successMessage: 'MediaManagement settings saved',
errorMessage : 'Couldn\'t save naming settings' errorMessage : 'Couldn\'t save naming settings'
}); });

@ -0,0 +1,43 @@
'use strict';
define(
[
'marionette',
'Mixins/AsModelBoundView'
], function (Marionette, AsModelBoundView) {
var view = Marionette.ItemView.extend({
template: 'Settings/MediaManagement/Naming/ViewTemplate',
ui: {
namingOptions : '.x-naming-options',
renameEpisodesCheckbox : '.x-rename-episodes'
},
events: {
'change .x-rename-episodes': '_toggleNamingOptions'
},
onShow: function () {
var renameEpisodes = this.model.get('renameEpisodes');
this._setNamingOptionsVisibility(renameEpisodes);
},
_toggleNamingOptions: function() {
var checked = this.ui.renameEpisodesCheckbox.prop('checked');
this._setNamingOptionsVisibility(checked);
},
_setNamingOptionsVisibility: function (showNamingOptions) {
if (showNamingOptions) {
this.ui.namingOptions.show();
}
else {
this.ui.namingOptions.hide();
}
}
});
return AsModelBoundView.call(view);
});

@ -1,28 +1,28 @@
<div class="form-horizontal"> <fieldset>
<fieldset> <legend>Episode Naming</legend>
<legend>Episode Naming</legend>
<div class="control-group"> <div class="control-group">
<label class="control-label">Use Scene Name</label> <label class="control-label">Rename Episodes</label>
<div class="controls"> <div class="controls">
<label class="checkbox toggle well"> <label class="checkbox toggle well">
<input type="checkbox" name="useSceneName"/> <input type="checkbox" name="renameEpisodes" class="x-rename-episodes"/>
<p> <p>
<span>Yes</span> <span>Yes</span>
<span>No</span> <span>No</span>
</p> </p>
<div class="btn btn-primary slide-button"/> <div class="btn btn-primary slide-button"/>
</label> </label>
<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 class="icon-form-danger" title="NzbDrone will use the existing file name if set to no"/>
</span> </span>
</div>
</div> </div>
</div>
<div class="x-naming-options">
<div class="control-group"> <div class="control-group">
<label class="control-label">Include Series Title</label> <label class="control-label">Include Series Title</label>
@ -37,10 +37,6 @@
<div class="btn btn-primary slide-button"/> <div class="btn btn-primary slide-button"/>
</label> </label>
<span class="help-inline-checkbox">
<i class="icon-question-sign" title="Should filenames contain the series name when renamed?"/>
</span>
</div> </div>
</div> </div>
@ -58,10 +54,6 @@
<div class="btn btn-primary slide-button"/> <div class="btn btn-primary slide-button"/>
</label> </label>
<span class="help-inline-checkbox">
<i class="icon-question-sign" title="Should filenames contain the episode name when renamed?"/>
</span>
</div> </div>
</div> </div>
@ -79,10 +71,6 @@
<div class="btn btn-primary slide-button"/> <div class="btn btn-primary slide-button"/>
</label> </label>
<span class="help-inline-checkbox">
<i class="icon-question-sign" title="Should filenames have the include the quality?"/>
</span>
</div> </div>
</div> </div>
@ -100,21 +88,6 @@
<div class="btn btn-primary slide-button"/> <div class="btn btn-primary slide-button"/>
</label> </label>
<span class="help-inline-checkbox">
<i class="icon-question-sign" title="Do you want to replace spaces in the filename with periods?"/>
</span>
</div>
</div>
<div class="control-group">
<label class="control-label">Season Folder Format</label>
<div class="controls">
<input type="text" placeholder="Season %s" name="seasonFolderFormat"/>
<span class="help-inline">
<i class="icon-question-sign" title="How should season folders be named? (Use %0s to pad to two digits, %sn for Series Name)"/>
</span>
</div> </div>
</div> </div>
@ -127,9 +100,6 @@
<option value=" ">Space</option> <option value=" ">Space</option>
<option value=".">Period</option> <option value=".">Period</option>
</select> </select>
<span class="help-inline">
<i class="icon-question-sign" title="How should NzbDrone separate sections of the filename?"/>
</span>
</div> </div>
</div> </div>
@ -143,9 +113,6 @@
<option value="2">S01E05</option> <option value="2">S01E05</option>
<option value="3">s01e05</option> <option value="3">s01e05</option>
</select> </select>
<span class="help-inline">
<i class="icon-question-sign" title="What numbering style do you want?"/>
</span>
</div> </div>
</div> </div>
@ -159,10 +126,7 @@
<option value="2">Repeat</option> <option value="2">Repeat</option>
<option value="3">Scene</option> <option value="3">Scene</option>
</select> </select>
<span class="help-inline">
<i class="icon-question-sign" title="How will multi-episode files be named?"/>
</span>
</div> </div>
</div> </div>
</fieldset> </div>
</div> </fieldset>

@ -0,0 +1,13 @@
'use strict';
define(
[
'marionette',
'Mixins/AsModelBoundView'
], function (Marionette, AsModelBoundView) {
var view = Marionette.ItemView.extend({
template: 'Settings/MediaManagement/Sorting/ViewTemplate'
});
return AsModelBoundView.call(view);
});

@ -0,0 +1,32 @@
<fieldset>
<legend>Sorting</legend>
<!--TODO: Remove this and move it to Add Series-->
<div class="control-group">
<label class="control-label">Use Season Folder</label>
<div class="controls">
<label class="checkbox toggle well">
<input type="checkbox" name="useSeasonFolder"/>
<p>
<span>Yes</span>
<span>No</span>
</p>
<div class="btn btn-primary slide-button"/>
</label>
</div>
</div>
<div class="control-group">
<label class="control-label">Season Folder Format</label>
<div class="controls">
<input type="text" placeholder="Season %s" name="seasonFolderFormat"/>
<span class="help-inline">
<i class="icon-question-sign" title="How should season folders be named? (Use %0s to pad to two digits, %sn for Series Name)"/>
</span>
</div>
</div>
</fieldset>

@ -23,26 +23,6 @@
</div> </div>
</div> </div>
<div class="control-group">
<label class="control-label">Ignore Deleted Episodes</label>
<div class="controls">
<label class="checkbox toggle well">
<input type="checkbox" name="autoIgnorePreviouslyDownloadedEpisodes"/>
<p>
<span>Yes</span>
<span>No</span>
</p>
<div class="btn btn-primary slide-button"/>
</label>
<span class="help-inline-checkbox">
<i class="icon-question-sign" title="Episodes deleted from disk are automatically ignored in NzbDrone"/>
</span>
</div>
</div>
<div class="control-group"> <div class="control-group">
<label class="control-label">Nzb Restrictions</label> <label class="control-label">Nzb Restrictions</label>

@ -1,20 +0,0 @@
'use strict';
define(
[
'marionette',
'Settings/Naming/NamingModel',
'Mixins/AsModelBoundView'
], function (Marionette, NamingModel, AsModelBoundView) {
var view = Marionette.ItemView.extend({
template: 'Settings/Naming/NamingTemplate',
initialize: function () {
this.model = new NamingModel();
this.model.fetch();
}
});
return AsModelBoundView.call(view);
});

@ -5,8 +5,8 @@ define(
'marionette', 'marionette',
'Settings/SettingsModel', 'Settings/SettingsModel',
'Settings/General/GeneralSettingsModel', 'Settings/General/GeneralSettingsModel',
'Settings/Naming/NamingModel', 'Settings/MediaManagement/Naming/Model',
'Settings/Naming/NamingView', 'Settings/MediaManagement/Layout',
'Settings/Quality/QualityLayout', 'Settings/Quality/QualityLayout',
'Settings/Indexers/CollectionView', 'Settings/Indexers/CollectionView',
'Settings/Indexers/Collection', 'Settings/Indexers/Collection',
@ -21,7 +21,7 @@ define(
SettingsModel, SettingsModel,
GeneralSettingsModel, GeneralSettingsModel,
NamingModel, NamingModel,
NamingView, MediaManagementLayout,
QualityLayout, QualityLayout,
IndexerCollectionView, IndexerCollectionView,
IndexerCollection, IndexerCollection,
@ -35,47 +35,47 @@ define(
template: 'Settings/SettingsLayoutTemplate', template: 'Settings/SettingsLayoutTemplate',
regions: { regions: {
naming : '#naming', mediaManagement : '#media-management',
quality : '#quality', quality : '#quality',
indexers : '#indexers', indexers : '#indexers',
downloadClient: '#download-client', downloadClient : '#download-client',
notifications : '#notifications', notifications : '#notifications',
general : '#general', general : '#general',
misc : '#misc', misc : '#misc',
loading : '#loading-region' loading : '#loading-region'
}, },
ui: { ui: {
namingTab : '.x-naming-tab', mediaManagementTab : '.x-media-management-tab',
qualityTab : '.x-quality-tab', qualityTab : '.x-quality-tab',
indexersTab : '.x-indexers-tab', indexersTab : '.x-indexers-tab',
downloadClientTab: '.x-download-client-tab', downloadClientTab : '.x-download-client-tab',
notificationsTab : '.x-notifications-tab', notificationsTab : '.x-notifications-tab',
generalTab : '.x-general-tab', generalTab : '.x-general-tab',
miscTab : '.x-misc-tab' miscTab : '.x-misc-tab'
}, },
events: { events: {
'click .x-naming-tab' : 'showNaming', 'click .x-media-management-tab' : '_showMediaManagement',
'click .x-quality-tab' : 'showQuality', 'click .x-quality-tab' : '_showQuality',
'click .x-indexers-tab' : 'showIndexers', 'click .x-indexers-tab' : '_showIndexers',
'click .x-download-client-tab': 'showDownloadClient', 'click .x-download-client-tab' : '_showDownloadClient',
'click .x-notifications-tab' : 'showNotifications', 'click .x-notifications-tab' : '_showNotifications',
'click .x-general-tab' : 'showGeneral', 'click .x-general-tab' : '_showGeneral',
'click .x-misc-tab' : 'showMisc', 'click .x-misc-tab' : '_showMisc',
'click .x-save-settings' : 'save' 'click .x-save-settings' : '_save'
}, },
showNaming: function (e) { _showMediaManagement: function (e) {
if (e) { if (e) {
e.preventDefault(); e.preventDefault();
} }
this.ui.namingTab.tab('show'); this.ui.mediaManagementTab.tab('show');
this._navigate('settings/naming'); this._navigate('settings/mediamanagement');
}, },
showQuality: function (e) { _showQuality: function (e) {
if (e) { if (e) {
e.preventDefault(); e.preventDefault();
} }
@ -84,7 +84,7 @@ define(
this._navigate('settings/quality'); this._navigate('settings/quality');
}, },
showIndexers: function (e) { _showIndexers: function (e) {
if (e) { if (e) {
e.preventDefault(); e.preventDefault();
} }
@ -93,7 +93,7 @@ define(
this._navigate('settings/indexers'); this._navigate('settings/indexers');
}, },
showDownloadClient: function (e) { _showDownloadClient: function (e) {
if (e) { if (e) {
e.preventDefault(); e.preventDefault();
} }
@ -102,7 +102,7 @@ define(
this._navigate('settings/downloadclient'); this._navigate('settings/downloadclient');
}, },
showNotifications: function (e) { _showNotifications: function (e) {
if (e) { if (e) {
e.preventDefault(); e.preventDefault();
} }
@ -111,7 +111,7 @@ define(
this._navigate('settings/notifications'); this._navigate('settings/notifications');
}, },
showGeneral: function (e) { _showGeneral: function (e) {
if (e) { if (e) {
e.preventDefault(); e.preventDefault();
} }
@ -120,7 +120,7 @@ define(
this._navigate('settings/general'); this._navigate('settings/general');
}, },
showMisc: function (e) { _showMisc: function (e) {
if (e) { if (e) {
e.preventDefault(); e.preventDefault();
} }
@ -158,7 +158,7 @@ define(
this.notificationSettings.fetch() this.notificationSettings.fetch()
).done(function () { ).done(function () {
self.loading.$el.hide(); self.loading.$el.hide();
self.naming.show(new NamingView()); self.mediaManagement.show(new MediaManagementLayout({ settings: self.settings, namingSettings: self.namingSettings }));
self.quality.show(new QualityLayout({settings: self.settings})); self.quality.show(new QualityLayout({settings: self.settings}));
self.indexers.show(new IndexerCollectionView({collection: self.indexerSettings})); self.indexers.show(new IndexerCollectionView({collection: self.indexerSettings}));
self.downloadClient.show(new DownloadClientLayout({model: self.settings})); self.downloadClient.show(new DownloadClientLayout({model: self.settings}));
@ -171,29 +171,29 @@ define(
onShow: function () { onShow: function () {
switch (this.action) { switch (this.action) {
case 'quality': case 'quality':
this.showQuality(); this._showQuality();
break; break;
case 'indexers': case 'indexers':
this.showIndexers(); this._showIndexers();
break; break;
case 'downloadclient': case 'downloadclient':
this.showDownloadClient(); this._showDownloadClient();
break; break;
case 'notifications': case 'notifications':
this.showNotifications(); this._showNotifications();
break; break;
case 'general': case 'general':
this.showGeneral(); this._showGeneral();
break; break;
case 'misc': case 'misc':
this.showMisc(); this._showMisc();
break; break;
default: default:
this.showNaming(); this._showMediaManagement();
} }
}, },
save: function () { _save: function () {
App.vent.trigger(App.Commands.SaveSettings); App.vent.trigger(App.Commands.SaveSettings);
} }
}); });

@ -1,5 +1,5 @@
<ul class="nav nav-tabs" id="myTab"> <ul class="nav nav-tabs" id="myTab">
<li><a href="#naming" class="x-naming-tab no-router">Naming</a></li> <li><a href="#media-management" class="x-media-management-tab no-router">Media Management</a></li>
<li><a href="#quality" class="x-quality-tab no-router">Quality</a></li> <li><a href="#quality" class="x-quality-tab no-router">Quality</a></li>
<li><a href="#indexers" class="x-indexers-tab no-router">Indexers</a></li> <li><a href="#indexers" class="x-indexers-tab no-router">Indexers</a></li>
<li><a href="#download-client" class="x-download-client-tab no-router">Download Client</a></li> <li><a href="#download-client" class="x-download-client-tab no-router">Download Client</a></li>
@ -10,13 +10,13 @@
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
<div class="tab-pane" id="naming">Naming Settings</div> <div class="tab-pane" id="media-management"></div>
<div class="tab-pane" id="quality">Quality Settings</div> <div class="tab-pane" id="quality"></div>
<div class="tab-pane" id="indexers">Indexer Settings</div> <div class="tab-pane" id="indexers"></div>
<div class="tab-pane" id="download-client">Download Client Settings</div> <div class="tab-pane" id="download-client"></div>
<div class="tab-pane" id="notifications">Notification Settings</div> <div class="tab-pane" id="notifications"></div>
<div class="tab-pane" id="general">general Settings</div> <div class="tab-pane" id="general"></div>
<div class="tab-pane" id="misc">Misc Settings</div> <div class="tab-pane" id="misc"></div>
</div> </div>
<div id="loading-region"></div> <div id="loading-region"></div>
Loading…
Cancel
Save