mirror of
https://github.com/Radarr/Radarr.git
synced 2024-11-04 10:02:40 +01:00
Basic UI + Wizard for custom naming added
This commit is contained in:
parent
7b54bca3c7
commit
0ec520c4d5
@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using Nancy.Responses;
|
using Nancy.Responses;
|
||||||
using NzbDrone.Core.MediaFiles;
|
using NzbDrone.Core.MediaFiles;
|
||||||
@ -28,6 +29,8 @@ public NamingModule(INamingConfigService namingConfigService, IBuildFileNames bu
|
|||||||
Get["/samples"] = x => GetExamples(this.Bind<NamingConfigResource>());
|
Get["/samples"] = x => GetExamples(this.Bind<NamingConfigResource>());
|
||||||
|
|
||||||
SharedValidator.RuleFor(c => c.MultiEpisodeStyle).InclusiveBetween(0, 3);
|
SharedValidator.RuleFor(c => c.MultiEpisodeStyle).InclusiveBetween(0, 3);
|
||||||
|
SharedValidator.RuleFor(c => c.StandardEpisodeFormat).NotEmpty();
|
||||||
|
SharedValidator.RuleFor(c => c.DailyEpisodeFormat).NotEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateNamingConfig(NamingConfigResource resource)
|
private void UpdateNamingConfig(NamingConfigResource resource)
|
||||||
@ -59,7 +62,8 @@ private JsonResponse<NamingSampleResource> GetExamples(NamingConfigResource conf
|
|||||||
{
|
{
|
||||||
SeasonNumber = 1,
|
SeasonNumber = 1,
|
||||||
EpisodeNumber = 1,
|
EpisodeNumber = 1,
|
||||||
Title = "Episode Title (1)"
|
Title = "Episode Title (1)",
|
||||||
|
AirDate = "2013-10-30"
|
||||||
};
|
};
|
||||||
|
|
||||||
var episode2 = new Episode
|
var episode2 = new Episode
|
||||||
@ -77,19 +81,43 @@ private JsonResponse<NamingSampleResource> GetExamples(NamingConfigResource conf
|
|||||||
|
|
||||||
var sampleResource = new NamingSampleResource();
|
var sampleResource = new NamingSampleResource();
|
||||||
|
|
||||||
sampleResource.SingleEpisodeExample = _buildFileNames.BuildFilename(new List<Episode> { episode1 },
|
sampleResource.SingleEpisodeExample = BuildSample(new List<Episode> { episode1 },
|
||||||
series,
|
series,
|
||||||
episodeFile,
|
episodeFile,
|
||||||
nameSpec);
|
nameSpec);
|
||||||
|
|
||||||
episodeFile.Path = @"C:\Test\Series.Title.S01E01-E02.720p.HDTV.x264-EVOLVE.mkv";
|
episodeFile.Path = @"C:\Test\Series.Title.S01E01-E02.720p.HDTV.x264-EVOLVE.mkv";
|
||||||
|
|
||||||
sampleResource.MultiEpisodeExample = _buildFileNames.BuildFilename(new List<Episode> { episode1, episode2 },
|
sampleResource.MultiEpisodeExample = BuildSample(new List<Episode> { episode1, episode2 },
|
||||||
series,
|
series,
|
||||||
episodeFile,
|
episodeFile,
|
||||||
nameSpec);
|
nameSpec);
|
||||||
|
|
||||||
|
episodeFile.Path = @"C:\Test\Series.Title.2013.10.30.HDTV.x264-EVOLVE.mkv";
|
||||||
|
series.SeriesType = SeriesTypes.Daily;
|
||||||
|
|
||||||
|
sampleResource.DailyEpisodeExample = BuildSample(new List<Episode> { episode1 },
|
||||||
|
series,
|
||||||
|
episodeFile,
|
||||||
|
nameSpec);
|
||||||
|
|
||||||
return sampleResource.AsResponse();
|
return sampleResource.AsResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string BuildSample(List<Episode> episodes, Core.Tv.Series series, EpisodeFile episodeFile, NamingConfig nameSpec)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _buildFileNames.BuildFilename(episodes,
|
||||||
|
series,
|
||||||
|
episodeFile,
|
||||||
|
nameSpec);
|
||||||
|
}
|
||||||
|
catch (NamingFormatException ex)
|
||||||
|
{
|
||||||
|
//Catching to avoid blowing up all samples
|
||||||
|
return String.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,5 +4,6 @@ public class NamingSampleResource
|
|||||||
{
|
{
|
||||||
public string SingleEpisodeExample { get; set; }
|
public string SingleEpisodeExample { get; set; }
|
||||||
public string MultiEpisodeExample { get; set; }
|
public string MultiEpisodeExample { get; set; }
|
||||||
|
public string DailyEpisodeExample { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -38,7 +38,7 @@ private void ConvertConfig(IDbConnection conn, IDbTransaction tran)
|
|||||||
//Output settings
|
//Output settings
|
||||||
var seriesTitlePattern = "";
|
var seriesTitlePattern = "";
|
||||||
var episodeTitlePattern = "";
|
var episodeTitlePattern = "";
|
||||||
var dailyEpisodePattern = "{Air Date}";
|
var dailyEpisodePattern = "{Air-Date}";
|
||||||
var qualityFormat = " [{Quality Title}]";
|
var qualityFormat = " [{Quality Title}]";
|
||||||
|
|
||||||
if (includeSeriesTitle)
|
if (includeSeriesTitle)
|
||||||
@ -61,11 +61,6 @@ private void ConvertConfig(IDbConnection conn, IDbTransaction tran)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (replaceSpaces)
|
|
||||||
{
|
|
||||||
dailyEpisodePattern = "{Air.Date}";
|
|
||||||
}
|
|
||||||
|
|
||||||
var standardEpisodeFormat = String.Format("{0}{1}{2}", seriesTitlePattern,
|
var standardEpisodeFormat = String.Format("{0}{1}{2}", seriesTitlePattern,
|
||||||
GetNumberStyle(numberStyle).Pattern,
|
GetNumberStyle(numberStyle).Pattern,
|
||||||
episodeTitlePattern);
|
episodeTitlePattern);
|
||||||
|
@ -325,6 +325,7 @@
|
|||||||
<Compile Include="Notifications\Xbmc\Model\XbmcJsonResult.cs" />
|
<Compile Include="Notifications\Xbmc\Model\XbmcJsonResult.cs" />
|
||||||
<Compile Include="Notifications\Xbmc\Model\XbmcVersion.cs" />
|
<Compile Include="Notifications\Xbmc\Model\XbmcVersion.cs" />
|
||||||
<Compile Include="Organizer\EpisodeFormat.cs" />
|
<Compile Include="Organizer\EpisodeFormat.cs" />
|
||||||
|
<Compile Include="Organizer\Exception.cs" />
|
||||||
<Compile Include="Organizer\FilenameBuilderTokenEqualityComparer.cs" />
|
<Compile Include="Organizer\FilenameBuilderTokenEqualityComparer.cs" />
|
||||||
<Compile Include="Parser\InvalidDateException.cs" />
|
<Compile Include="Parser\InvalidDateException.cs" />
|
||||||
<Compile Include="Parser\Model\SeriesTitleInfo.cs" />
|
<Compile Include="Parser\Model\SeriesTitleInfo.cs" />
|
||||||
|
15
src/NzbDrone.Core/Organizer/Exception.cs
Normal file
15
src/NzbDrone.Core/Organizer/Exception.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using NzbDrone.Common.Exceptions;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Organizer
|
||||||
|
{
|
||||||
|
public class NamingFormatException : NzbDroneException
|
||||||
|
{
|
||||||
|
public NamingFormatException(string message, params object[] args) : base(message, args)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public NamingFormatException(string message) : base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -96,6 +96,16 @@ public string BuildFilename(IList<Episode> episodes, Series series, EpisodeFile
|
|||||||
return episodeFile.SceneName;
|
return episodeFile.SceneName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (String.IsNullOrWhiteSpace(nameSpec.StandardEpisodeFormat) && series.SeriesType == SeriesTypes.Standard)
|
||||||
|
{
|
||||||
|
throw new NamingFormatException("Standard episode format cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (String.IsNullOrWhiteSpace(nameSpec.DailyEpisodeFormat) && series.SeriesType == SeriesTypes.Daily)
|
||||||
|
{
|
||||||
|
throw new NamingFormatException("Daily episode format cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
var sortedEpisodes = episodes.OrderBy(e => e.EpisodeNumber).ToList();
|
var sortedEpisodes = episodes.OrderBy(e => e.EpisodeNumber).ToList();
|
||||||
var pattern = nameSpec.StandardEpisodeFormat;
|
var pattern = nameSpec.StandardEpisodeFormat;
|
||||||
var episodeTitles = new List<string>
|
var episodeTitles = new List<string>
|
||||||
@ -112,7 +122,7 @@ public string BuildFilename(IList<Episode> episodes, Series series, EpisodeFile
|
|||||||
|
|
||||||
if (!String.IsNullOrWhiteSpace(episodes.First().AirDate))
|
if (!String.IsNullOrWhiteSpace(episodes.First().AirDate))
|
||||||
{
|
{
|
||||||
tokenValues.Add("{Air Date}", episodes.First().AirDate);
|
tokenValues.Add("{Air Date}", episodes.First().AirDate.Replace('-', ' '));
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
@ -218,8 +228,9 @@ private string ReplaceToken(Match match, Dictionary<string, string> tokenValues)
|
|||||||
{
|
{
|
||||||
var separator = match.Groups["separator"].Value;
|
var separator = match.Groups["separator"].Value;
|
||||||
var token = match.Groups["token"].Value;
|
var token = match.Groups["token"].Value;
|
||||||
var replacementText = tokenValues[token];
|
var replacementText = "";
|
||||||
var patternTokenArray = token.ToCharArray();
|
var patternTokenArray = token.ToCharArray();
|
||||||
|
if (!tokenValues.TryGetValue(token, out replacementText)) return null;
|
||||||
|
|
||||||
if (patternTokenArray.All(t => !char.IsLetter(t) || char.IsLower(t)))
|
if (patternTokenArray.All(t => !char.IsLetter(t) || char.IsLower(t)))
|
||||||
{
|
{
|
||||||
|
@ -10,10 +10,10 @@ public static NamingConfig Default
|
|||||||
{
|
{
|
||||||
return new NamingConfig
|
return new NamingConfig
|
||||||
{
|
{
|
||||||
RenameEpisodes = true,
|
RenameEpisodes = false,
|
||||||
MultiEpisodeStyle = 0,
|
MultiEpisodeStyle = 0,
|
||||||
StandardEpisodeFormat = "{Series Title} - {season}x{0episode} - {Episode Title} {Quality Title}",
|
StandardEpisodeFormat = "",
|
||||||
DailyEpisodeFormat = "{Series Title} - {Air Date} - {Episode Title} {Quality Title}"
|
DailyEpisodeFormat = ""
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,11 @@ define(
|
|||||||
this._modelBinder = new ModelBinder();
|
this._modelBinder = new ModelBinder();
|
||||||
}
|
}
|
||||||
|
|
||||||
this._modelBinder.bind(this.model, this.el);
|
var options = {
|
||||||
|
changeTriggers: {'': 'change', '[contenteditable]': 'blur', '[data-onkeyup]': 'keyup'}
|
||||||
|
};
|
||||||
|
|
||||||
|
this._modelBinder.bind(this.model, this.el, null, options);
|
||||||
|
|
||||||
if (originalOnRender) {
|
if (originalOnRender) {
|
||||||
originalOnRender.call(this);
|
originalOnRender.call(this);
|
||||||
|
@ -6,5 +6,4 @@ define(
|
|||||||
return Backbone.Model.extend({
|
return Backbone.Model.extend({
|
||||||
url: window.NzbDrone.ApiRoot + '/config/naming/samples'
|
url: window.NzbDrone.ApiRoot + '/config/naming/samples'
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
|
'vent',
|
||||||
'marionette',
|
'marionette',
|
||||||
'Settings/MediaManagement/Naming/NamingSampleModel',
|
'Settings/MediaManagement/Naming/NamingSampleModel',
|
||||||
'Mixins/AsModelBoundView'
|
'Mixins/AsModelBoundView'
|
||||||
], function (Marionette, NamingSampleModel, AsModelBoundView) {
|
], function (vent, Marionette, NamingSampleModel, AsModelBoundView) {
|
||||||
|
|
||||||
var view = Marionette.ItemView.extend({
|
var view = Marionette.ItemView.extend({
|
||||||
template: 'Settings/MediaManagement/Naming/NamingViewTemplate',
|
template: 'Settings/MediaManagement/Naming/NamingViewTemplate',
|
||||||
@ -13,11 +14,13 @@ define(
|
|||||||
namingOptions : '.x-naming-options',
|
namingOptions : '.x-naming-options',
|
||||||
renameEpisodesCheckbox: '.x-rename-episodes',
|
renameEpisodesCheckbox: '.x-rename-episodes',
|
||||||
singleEpisodeExample : '.x-single-episode-example',
|
singleEpisodeExample : '.x-single-episode-example',
|
||||||
multiEpisodeExample : '.x-multi-episode-example'
|
multiEpisodeExample : '.x-multi-episode-example',
|
||||||
|
dailyEpisodeExample : '.x-daily-episode-example'
|
||||||
},
|
},
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
'change .x-rename-episodes': '_setFailedDownloadOptionsVisibility'
|
'change .x-rename-episodes': '_setFailedDownloadOptionsVisibility',
|
||||||
|
'click .x-show-wizard' : '_showWizard'
|
||||||
},
|
},
|
||||||
|
|
||||||
onRender: function () {
|
onRender: function () {
|
||||||
@ -50,6 +53,11 @@ define(
|
|||||||
_showSamples: function () {
|
_showSamples: function () {
|
||||||
this.ui.singleEpisodeExample.html(this.namingSampleModel.get('singleEpisodeExample'));
|
this.ui.singleEpisodeExample.html(this.namingSampleModel.get('singleEpisodeExample'));
|
||||||
this.ui.multiEpisodeExample.html(this.namingSampleModel.get('multiEpisodeExample'));
|
this.ui.multiEpisodeExample.html(this.namingSampleModel.get('multiEpisodeExample'));
|
||||||
|
this.ui.dailyEpisodeExample.html(this.namingSampleModel.get('dailyEpisodeExample'));
|
||||||
|
},
|
||||||
|
|
||||||
|
_showWizard: function () {
|
||||||
|
vent.trigger(vent.Commands.ShowNamingWizard, { model: this.model });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -24,108 +24,30 @@
|
|||||||
|
|
||||||
<div class="x-naming-options">
|
<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">Wizard</label>
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<label class="checkbox toggle well">
|
<button class="btn x-show-wizard">Show Wizard</button>
|
||||||
<input type="checkbox" name="includeSeriesTitle"/>
|
|
||||||
|
|
||||||
<p>
|
<span class="help-inline">
|
||||||
<span>Yes</span>
|
<i class="icon-nd-form-info" title="Wizard to setup preferred naming style"/>
|
||||||
<span>No</span>
|
</span>
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="btn btn-primary slide-button"/>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label class="control-label">Include Episode Title</label>
|
<label class="control-label">Standard Episode Format</label>
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<label class="checkbox toggle well">
|
<input type="text" class="naming-format" name="standardEpisodeFormat" data-onkeyup="true" />
|
||||||
<input type="checkbox" name="includeEpisodeTitle"/>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<span>Yes</span>
|
|
||||||
<span>No</span>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="btn btn-primary slide-button"/>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label class="control-label">Include Quality</label>
|
<label class="control-label">Daily Episode Format</label>
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<label class="checkbox toggle well">
|
<input type="text" class="naming-format" name="dailyEpisodeFormat" data-onkeyup="true" />
|
||||||
<input type="checkbox" name="includeQuality"/>
|
|
||||||
|
|
||||||
<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">Replace Spaces</label>
|
|
||||||
|
|
||||||
<div class="controls">
|
|
||||||
<label class="checkbox toggle well">
|
|
||||||
<input type="checkbox" name="replaceSpaces"/>
|
|
||||||
|
|
||||||
<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">Separator</label>
|
|
||||||
|
|
||||||
<div class="controls">
|
|
||||||
<select class="inputClass" name="separator">
|
|
||||||
<option value=" - ">Dash</option>
|
|
||||||
<option value=" ">Space</option>
|
|
||||||
<option value=".">Period</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="control-group">
|
|
||||||
<label class="control-label">Numbering Style</label>
|
|
||||||
|
|
||||||
<div class="controls">
|
|
||||||
<select class="inputClass" name="numberStyle">
|
|
||||||
<option value="0">1x05</option>
|
|
||||||
<option value="1">01x05</option>
|
|
||||||
<option value="2">S01E05</option>
|
|
||||||
<option value="3">s01e05</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="control-group">
|
|
||||||
<label class="control-label">Multi-Episode Style</label>
|
|
||||||
|
|
||||||
<div class="controls">
|
|
||||||
<select class="inputClass" name="multiEpisodeStyle">
|
|
||||||
<option value="0">Extend</option>
|
|
||||||
<option value="1">Duplicate</option>
|
|
||||||
<option value="2">Repeat</option>
|
|
||||||
<option value="3">Scene</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -145,4 +67,12 @@
|
|||||||
<span class="x-multi-episode-example naming-example"></span>
|
<span class="x-multi-episode-example naming-example"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label">Daily-Episode Example</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<span class="x-daily-episode-example naming-example"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
'use strict';
|
||||||
|
define(
|
||||||
|
[
|
||||||
|
'backbone'
|
||||||
|
], function (Backbone) {
|
||||||
|
return Backbone.Model.extend({
|
||||||
|
defaults: {
|
||||||
|
includeSeriesTitle : true,
|
||||||
|
includeEpisodeTitle: true,
|
||||||
|
includeQuality : true,
|
||||||
|
replaceSpaces : false,
|
||||||
|
separator : ' - ',
|
||||||
|
numberStyle : '2',
|
||||||
|
multiEpisodeStyle : 0
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,141 @@
|
|||||||
|
'use strict';
|
||||||
|
define(
|
||||||
|
[
|
||||||
|
'vent',
|
||||||
|
'marionette',
|
||||||
|
'Settings/MediaManagement/Naming/NamingSampleModel',
|
||||||
|
'Settings/MediaManagement/Naming/Wizard/NamingWizardModel',
|
||||||
|
'Mixins/AsModelBoundView'
|
||||||
|
], function (vent, Marionette, NamingSampleModel, NamingWizardModel, AsModelBoundView) {
|
||||||
|
|
||||||
|
var view = Marionette.ItemView.extend({
|
||||||
|
template: 'Settings/MediaManagement/Naming/Wizard/NamingWizardViewTemplate',
|
||||||
|
|
||||||
|
ui: {
|
||||||
|
namingOptions : '.x-naming-options',
|
||||||
|
singleEpisodeExample : '.x-single-episode-example',
|
||||||
|
multiEpisodeExample : '.x-multi-episode-example',
|
||||||
|
dailyEpisodeExample : '.x-daily-episode-example'
|
||||||
|
},
|
||||||
|
|
||||||
|
events: {
|
||||||
|
'click .x-apply': '_applyNaming'
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function (options) {
|
||||||
|
this.model = new NamingWizardModel();
|
||||||
|
this.namingModel = options.model;
|
||||||
|
this.namingSampleModel = new NamingSampleModel();
|
||||||
|
},
|
||||||
|
|
||||||
|
onRender: function () {
|
||||||
|
if (!this.model.get('renameEpisodes')) {
|
||||||
|
this.ui.namingOptions.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.listenTo(this.model, 'change', this._buildFormat);
|
||||||
|
this.listenTo(this.namingSampleModel, 'sync', this._showSamples);
|
||||||
|
this._buildFormat();
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateSamples: function () {
|
||||||
|
var data = {
|
||||||
|
renameEpisodes: true,
|
||||||
|
standardEpisodeFormat: this.standardEpisodeFormat,
|
||||||
|
dailyEpisodeFormat: this.dailyEpisodeFormat,
|
||||||
|
multiEpisodeStyle: this.model.get('multiEpisodeStyle')
|
||||||
|
};
|
||||||
|
|
||||||
|
this.namingSampleModel.fetch({data: data});
|
||||||
|
},
|
||||||
|
|
||||||
|
_showSamples: function () {
|
||||||
|
this.ui.singleEpisodeExample.html(this.namingSampleModel.get('singleEpisodeExample'));
|
||||||
|
this.ui.multiEpisodeExample.html(this.namingSampleModel.get('multiEpisodeExample'));
|
||||||
|
this.ui.dailyEpisodeExample.html(this.namingSampleModel.get('dailyEpisodeExample'));
|
||||||
|
},
|
||||||
|
|
||||||
|
_applyNaming: function () {
|
||||||
|
this.namingModel.set('standardEpisodeFormat', this.standardEpisodeFormat);
|
||||||
|
this.namingModel.set('dailyEpisodeFormat', this.dailyEpisodeFormat);
|
||||||
|
this.namingModel.set('multiEpisodeStyle', this.model.get('multiEpisodeStyle'));
|
||||||
|
|
||||||
|
vent.trigger(vent.Commands.CloseModalCommand);
|
||||||
|
},
|
||||||
|
|
||||||
|
_buildFormat: function () {
|
||||||
|
this.standardEpisodeFormat = '';
|
||||||
|
this.dailyEpisodeFormat = '';
|
||||||
|
|
||||||
|
if (this.model.get('includeSeriesTitle')) {
|
||||||
|
if (this.model.get('replaceSpaces')) {
|
||||||
|
this.standardEpisodeFormat += '{Series.Title}';
|
||||||
|
this.dailyEpisodeFormat += '{Series.Title}';
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
this.standardEpisodeFormat += '{Series Title}';
|
||||||
|
this.dailyEpisodeFormat += '{Series Title}';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.standardEpisodeFormat += this.model.get('separator');
|
||||||
|
this.dailyEpisodeFormat += this.model.get('separator');
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (this.model.get('numberStyle')) {
|
||||||
|
case '0':
|
||||||
|
this.standardEpisodeFormat += '{season}x{0episode}';
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
this.standardEpisodeFormat += '{0season}x{0episode}';
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
this.standardEpisodeFormat += 'S{0season}E{0episode}';
|
||||||
|
break;
|
||||||
|
case '3':
|
||||||
|
this.standardEpisodeFormat += 's{0season}e{0episode}';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.standardEpisodeFormat += 'Unknown Number Pattern';
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dailyEpisodeFormat += '{Air-Date}';
|
||||||
|
|
||||||
|
if (this.model.get('includeEpisodeTitle')) {
|
||||||
|
this.standardEpisodeFormat += this.model.get('separator');
|
||||||
|
this.dailyEpisodeFormat += this.model.get('separator');
|
||||||
|
|
||||||
|
if (this.model.get('replaceSpaces')) {
|
||||||
|
this.standardEpisodeFormat += '{Episode.Title}';
|
||||||
|
this.dailyEpisodeFormat += '{Episode.Title}';
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
this.standardEpisodeFormat += '{Episode Title}';
|
||||||
|
this.dailyEpisodeFormat += '{Episode Title}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.model.get('includeQuality')) {
|
||||||
|
if (this.model.get('replaceSpaces')) {
|
||||||
|
this.standardEpisodeFormat += ' {Quality.Title}';
|
||||||
|
this.dailyEpisodeFormat += ' {Quality.Title}';
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
this.standardEpisodeFormat += ' {Quality Title}';
|
||||||
|
this.dailyEpisodeFormat += ' {Quality Title}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.model.get('replaceSpaces')) {
|
||||||
|
this.standardEpisodeFormat = this.standardEpisodeFormat.replace(/\s/g, '.');
|
||||||
|
this.dailyEpisodeFormat = this.dailyEpisodeFormat.replace(/\s/g, '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
this._updateSamples();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return AsModelBoundView.call(view);
|
||||||
|
});
|
@ -0,0 +1,141 @@
|
|||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
|
<h3>Naming Wizard</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="form-horizontal">
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label">Include Series Title</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<label class="checkbox toggle well">
|
||||||
|
<input type="checkbox" name="includeSeriesTitle"/>
|
||||||
|
|
||||||
|
<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">Include Episode Title</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<label class="checkbox toggle well">
|
||||||
|
<input type="checkbox" name="includeEpisodeTitle"/>
|
||||||
|
|
||||||
|
<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">Include Quality</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<label class="checkbox toggle well">
|
||||||
|
<input type="checkbox" name="includeQuality"/>
|
||||||
|
|
||||||
|
<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">Replace Spaces</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<label class="checkbox toggle well">
|
||||||
|
<input type="checkbox" name="replaceSpaces"/>
|
||||||
|
|
||||||
|
<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">Separator</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<select class="inputClass" name="separator">
|
||||||
|
<option value=" - ">Dash</option>
|
||||||
|
<option value=" ">Space</option>
|
||||||
|
<option value=".">Period</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label">Numbering Style</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<select class="inputClass" name="numberStyle">
|
||||||
|
<option value="0">1x05</option>
|
||||||
|
<option value="1">01x05</option>
|
||||||
|
<option value="2">S01E05</option>
|
||||||
|
<option value="3">s01e05</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label">Multi-Episode Style</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<select class="inputClass" name="multiEpisodeStyle">
|
||||||
|
<option value="0">Extend</option>
|
||||||
|
<option value="1">Duplicate</option>
|
||||||
|
<option value="2">Repeat</option>
|
||||||
|
<option value="3">Scene</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label">Single Episode Example</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<span class="x-single-episode-example naming-example"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label">Multi-Episode Example</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<span class="x-multi-episode-example naming-example"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label">Daily-Episode Example</label>
|
||||||
|
|
||||||
|
<div class="controls">
|
||||||
|
<span class="x-daily-episode-example naming-example"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn" data-dismiss="modal">cancel</button>
|
||||||
|
<button class="btn btn-primary x-apply">apply</button>
|
||||||
|
</div>
|
@ -44,9 +44,9 @@
|
|||||||
<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="seasonFolderFormat"/>
|
<input type="text" placeholder="Season {season}" 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, %sn for Series Name)"/>
|
<i class="icon-question-sign" title="How should season folders be named? Please see the wiki for customization options"/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -45,6 +45,10 @@ li.save-and-add:hover {
|
|||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.naming-format {
|
||||||
|
width: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
.advanced-settings-toggle {
|
.advanced-settings-toggle {
|
||||||
margin-right: 40px;
|
margin-right: 40px;
|
||||||
|
|
||||||
@ -77,4 +81,4 @@ li.save-and-add:hover {
|
|||||||
.advanced-setting {
|
.advanced-setting {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,9 @@ define(
|
|||||||
'Series/Delete/DeleteSeriesView',
|
'Series/Delete/DeleteSeriesView',
|
||||||
'Episode/EpisodeDetailsLayout',
|
'Episode/EpisodeDetailsLayout',
|
||||||
'History/Details/HistoryDetailsView',
|
'History/Details/HistoryDetailsView',
|
||||||
'System/Logs/Table/Details/LogDetailsView'
|
'System/Logs/Table/Details/LogDetailsView',
|
||||||
], function (vent, AppLayout, Marionette, EditSeriesView, DeleteSeriesView, EpisodeDetailsLayout, HistoryDetailsView, LogDetailsView) {
|
'Settings/MediaManagement/Naming/Wizard/NamingWizardView'
|
||||||
|
], function (vent, AppLayout, Marionette, EditSeriesView, DeleteSeriesView, EpisodeDetailsLayout, HistoryDetailsView, LogDetailsView, NamingWizardView) {
|
||||||
|
|
||||||
return Marionette.AppRouter.extend({
|
return Marionette.AppRouter.extend({
|
||||||
|
|
||||||
@ -20,6 +21,7 @@ define(
|
|||||||
vent.on(vent.Commands.ShowEpisodeDetails, this._showEpisode, this);
|
vent.on(vent.Commands.ShowEpisodeDetails, this._showEpisode, this);
|
||||||
vent.on(vent.Commands.ShowHistoryDetails, this._showHistory, this);
|
vent.on(vent.Commands.ShowHistoryDetails, this._showHistory, this);
|
||||||
vent.on(vent.Commands.ShowLogDetails, this._showLogDetails, this);
|
vent.on(vent.Commands.ShowLogDetails, this._showLogDetails, this);
|
||||||
|
vent.on(vent.Commands.ShowNamingWizard, this._showNamingWizard, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
_closeModal: function () {
|
_closeModal: function () {
|
||||||
@ -49,6 +51,11 @@ define(
|
|||||||
_showLogDetails: function (options) {
|
_showLogDetails: function (options) {
|
||||||
var view = new LogDetailsView({ model: options.model });
|
var view = new LogDetailsView({ model: options.model });
|
||||||
AppLayout.modalRegion.show(view);
|
AppLayout.modalRegion.show(view);
|
||||||
|
},
|
||||||
|
|
||||||
|
_showNamingWizard: function (options) {
|
||||||
|
var view = new NamingWizardView({ model: options.model });
|
||||||
|
AppLayout.modalRegion.show(view);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -23,7 +23,8 @@ define(
|
|||||||
ShowHistoryDetails : 'ShowHistoryDetails',
|
ShowHistoryDetails : 'ShowHistoryDetails',
|
||||||
ShowLogDetails : 'ShowLogDetails',
|
ShowLogDetails : 'ShowLogDetails',
|
||||||
SaveSettings : 'saveSettings',
|
SaveSettings : 'saveSettings',
|
||||||
ShowLogFile : 'showLogFile'
|
ShowLogFile : 'showLogFile',
|
||||||
|
ShowNamingWizard : 'showNamingWizard'
|
||||||
};
|
};
|
||||||
|
|
||||||
return vent;
|
return vent;
|
||||||
|
Loading…
Reference in New Issue
Block a user