diff --git a/src/NzbDrone.Api/Config/NamingConfigModule.cs b/src/NzbDrone.Api/Config/NamingConfigModule.cs index b7b2a035f..3cecff639 100644 --- a/src/NzbDrone.Api/Config/NamingConfigModule.cs +++ b/src/NzbDrone.Api/Config/NamingConfigModule.cs @@ -82,6 +82,7 @@ namespace NzbDrone.Api.Config var multiEpisodeSampleResult = _filenameSampleService.GetMultiEpisodeSample(nameSpec); var dailyEpisodeSampleResult = _filenameSampleService.GetDailySample(nameSpec); var animeEpisodeSampleResult = _filenameSampleService.GetAnimeSample(nameSpec); + var animeMultiEpisodeSampleResult = _filenameSampleService.GetAnimeMultiEpisodeSample(nameSpec); sampleResource.SingleEpisodeExample = _filenameValidationService.ValidateStandardFilename(singleEpisodeSampleResult) != null ? "Invalid format" @@ -99,6 +100,10 @@ namespace NzbDrone.Api.Config ? "Invalid format" : animeEpisodeSampleResult.FileName; + sampleResource.AnimeMultiEpisodeExample = _filenameValidationService.ValidateAnimeFilename(animeMultiEpisodeSampleResult) != null + ? "Invalid format" + : animeMultiEpisodeSampleResult.FileName; + sampleResource.SeriesFolderExample = nameSpec.SeriesFolderFormat.IsNullOrWhiteSpace() ? "Invalid format" : _filenameSampleService.GetSeriesFolderSample(nameSpec); @@ -115,26 +120,22 @@ namespace NzbDrone.Api.Config var singleEpisodeSampleResult = _filenameSampleService.GetStandardSample(nameSpec); var multiEpisodeSampleResult = _filenameSampleService.GetMultiEpisodeSample(nameSpec); var dailyEpisodeSampleResult = _filenameSampleService.GetDailySample(nameSpec); + var animeEpisodeSampleResult = _filenameSampleService.GetAnimeSample(nameSpec); + var animeMultiEpisodeSampleResult = _filenameSampleService.GetAnimeMultiEpisodeSample(nameSpec); + var singleEpisodeValidationResult = _filenameValidationService.ValidateStandardFilename(singleEpisodeSampleResult); var multiEpisodeValidationResult = _filenameValidationService.ValidateStandardFilename(multiEpisodeSampleResult); var dailyEpisodeValidationResult = _filenameValidationService.ValidateDailyFilename(dailyEpisodeSampleResult); + var animeEpisodeValidationResult = _filenameValidationService.ValidateAnimeFilename(animeEpisodeSampleResult); + var animeMultiEpisodeValidationResult = _filenameValidationService.ValidateAnimeFilename(animeMultiEpisodeSampleResult); var validationFailures = new List(); - if (singleEpisodeValidationResult != null) - { - validationFailures.Add(singleEpisodeValidationResult); - } - - if (multiEpisodeValidationResult != null) - { - validationFailures.Add(multiEpisodeValidationResult); - } - - if (dailyEpisodeValidationResult != null) - { - validationFailures.Add(dailyEpisodeValidationResult); - } + validationFailures.AddIfNotNull(singleEpisodeValidationResult); + validationFailures.AddIfNotNull(multiEpisodeValidationResult); + validationFailures.AddIfNotNull(dailyEpisodeValidationResult); + validationFailures.AddIfNotNull(animeEpisodeValidationResult); + validationFailures.AddIfNotNull(animeMultiEpisodeValidationResult); if (validationFailures.Any()) { diff --git a/src/NzbDrone.Api/Config/NamingSampleResource.cs b/src/NzbDrone.Api/Config/NamingSampleResource.cs index 0f8abdcbc..1f9c7f066 100644 --- a/src/NzbDrone.Api/Config/NamingSampleResource.cs +++ b/src/NzbDrone.Api/Config/NamingSampleResource.cs @@ -6,6 +6,7 @@ public string MultiEpisodeExample { get; set; } public string DailyEpisodeExample { get; set; } public string AnimeEpisodeExample { get; set; } + public string AnimeMultiEpisodeExample { get; set; } public string SeriesFolderExample { get; set; } public string SeasonFolderExample { get; set; } } diff --git a/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderFixture.cs b/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderFixture.cs index bd1809135..e2b7b5bb1 100644 --- a/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderFixture.cs +++ b/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderFixture.cs @@ -20,6 +20,7 @@ namespace NzbDrone.Core.Test.OrganizerTests private Series _series; private Episode _episode1; private Episode _episode2; + private Episode _episode3; private EpisodeFile _episodeFile; private NamingConfig _namingConfig; @@ -53,6 +54,13 @@ namespace NzbDrone.Core.Test.OrganizerTests .With(e => e.AbsoluteEpisodeNumber = 101) .Build(); + _episode3 = Builder.CreateNew() + .With(e => e.Title = "City Sushi") + .With(e => e.SeasonNumber = 15) + .With(e => e.EpisodeNumber = 8) + .With(e => e.AbsoluteEpisodeNumber = 102) + .Build(); + _episodeFile = new EpisodeFile { Quality = new QualityModel(Quality.HDTV720p), ReleaseGroup = "DRONE" }; Mocker.GetMock() @@ -549,8 +557,8 @@ namespace NzbDrone.Core.Test.OrganizerTests _namingConfig.MultiEpisodeStyle = (int)MultiEpisodeStyle.Duplicate; _namingConfig.AnimeEpisodeFormat = "{Series Title} - {absolute:000} - {Episode Title}"; - Subject.BuildFileName(new List { _episode1, _episode2 }, _series, _episodeFile) - .Should().Be("South Park - 100 - 101 - City Sushi"); + Subject.BuildFileName(new List { _episode1, _episode2, _episode3 }, _series, _episodeFile) + .Should().Be("South Park - 100 - 101 - 102 - City Sushi"); } [Test] @@ -682,5 +690,59 @@ namespace NzbDrone.Core.Test.OrganizerTests Subject.BuildFileName(new List { _episode1, _episode2 }, _series, _episodeFile) .Should().Be("South Park - 15x06 - 15x07 - [100-101] - City Sushi - HDTV-720p"); } + + [Test] + public void should_format_range_multi_episode_properly() + { + _namingConfig.StandardEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Episode Title}"; + _namingConfig.MultiEpisodeStyle = 4; + + Subject.BuildFileName(new List { _episode1, _episode2, _episode3 }, _series, _episodeFile) + .Should().Be("South Park - S15E06-08 - City Sushi"); + } + + [Test] + public void should_format_range_multi_episode_anime_properly() + { + _series.SeriesType = SeriesTypes.Anime; + _namingConfig.MultiEpisodeStyle = 4; + _namingConfig.AnimeEpisodeFormat = "{Series Title} - {absolute:000} - {Episode Title}"; + + Subject.BuildFileName(new List { _episode1, _episode2, _episode3 }, _series, _episodeFile) + .Should().Be("South Park - 100-102 - City Sushi"); + } + + [Test] + public void should_format_repeat_multi_episode_anime_properly() + { + _series.SeriesType = SeriesTypes.Anime; + _namingConfig.MultiEpisodeStyle = 2; + _namingConfig.AnimeEpisodeFormat = "{Series Title} - {absolute:000} - {Episode Title}"; + + Subject.BuildFileName(new List { _episode1, _episode2, _episode3 }, _series, _episodeFile) + .Should().Be("South Park - 100-101-102 - City Sushi"); + } + + [Test] + public void should_format_single_episode_with_range_multi_episode_properly() + { + _namingConfig.StandardEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Episode Title}"; + _namingConfig.MultiEpisodeStyle = 4; + + Subject.BuildFileName(new List { _episode1 }, _series, _episodeFile) + .Should().Be("South Park - S15E06 - City Sushi"); + } + + [Test] + public void should_format_single_anime_episode_with_range_multi_episode_properly() + { + _series.SeriesType = SeriesTypes.Anime; + _namingConfig.MultiEpisodeStyle = 4; + _namingConfig.AnimeEpisodeFormat = "{Series Title} - {absolute:000} - {Episode Title}"; + + Subject.BuildFileName(new List { _episode1 }, _series, _episodeFile) + .Should().Be("South Park - 100 - City Sushi"); + } + } } \ No newline at end of file diff --git a/src/NzbDrone.Core.Test/ParserTests/AbsoluteEpisodeNumberParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/AbsoluteEpisodeNumberParserFixture.cs index b08738b55..f32328163 100644 --- a/src/NzbDrone.Core.Test/ParserTests/AbsoluteEpisodeNumberParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/AbsoluteEpisodeNumberParserFixture.cs @@ -97,6 +97,7 @@ namespace NzbDrone.Core.Test.ParserTests [TestCase("[ANBU-AonE]_Naruto_26-27_[F224EF26].avi", "Naruto", new[] { 26, 27 })] [TestCase("[Doutei] Recently, My Sister is Unusual - 01-12 [BD][720p-AAC]", "Recently, My Sister is Unusual", new [] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 })] + [TestCase("Series Title (2010) - 01-02-03 - Episode Title (1) HDTV-720p", "Series Title (2010)", new [] { 1, 2, 3 })] public void should_parse_multi_episode_absolute_numbers(string postTitle, string title, int[] absoluteEpisodeNumbers) { var result = Parser.Parser.ParseTitle(postTitle); diff --git a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs index f40aa28bf..87aeb532f 100644 --- a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs +++ b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs @@ -280,32 +280,41 @@ namespace NzbDrone.Core.Organizer foreach (var episodeFormat in episodeFormats) { var seasonEpisodePattern = episodeFormat.SeasonEpisodePattern; + string formatPattern; - foreach (var episode in episodes.Skip(1)) + switch ((MultiEpisodeStyle)namingConfig.MultiEpisodeStyle) { - switch ((MultiEpisodeStyle)namingConfig.MultiEpisodeStyle) - { - case MultiEpisodeStyle.Duplicate: - seasonEpisodePattern += episodeFormat.Separator + episodeFormat.SeasonEpisodePattern; - break; - - case MultiEpisodeStyle.Repeat: - seasonEpisodePattern += episodeFormat.EpisodeSeparator + episodeFormat.EpisodePattern; - break; - - case MultiEpisodeStyle.Scene: - seasonEpisodePattern += "-" + episodeFormat.EpisodeSeparator + episodeFormat.EpisodePattern; - break; - - //MultiEpisodeStyle.Extend - default: - seasonEpisodePattern += "-" + episodeFormat.EpisodePattern; - break; - } + case MultiEpisodeStyle.Duplicate: + formatPattern = episodeFormat.Separator + episodeFormat.SeasonEpisodePattern; + seasonEpisodePattern = FormatNumberTokens(seasonEpisodePattern, formatPattern, episodes); + break; + + case MultiEpisodeStyle.Repeat: + formatPattern = episodeFormat.EpisodeSeparator + episodeFormat.EpisodePattern; + seasonEpisodePattern = FormatNumberTokens(seasonEpisodePattern, formatPattern, episodes); + break; + + case MultiEpisodeStyle.Scene: + formatPattern = "-" + episodeFormat.EpisodeSeparator + episodeFormat.EpisodePattern; + seasonEpisodePattern = FormatNumberTokens(seasonEpisodePattern, formatPattern, episodes); + break; + + case MultiEpisodeStyle.Range: + formatPattern = "-" + episodeFormat.EpisodePattern; + var eps = new List { episodes.First() }; + + if (episodes.Count > 1) eps.Add(episodes.Last()); + + seasonEpisodePattern = FormatNumberTokens(seasonEpisodePattern, formatPattern, eps); + break; + + //MultiEpisodeStyle.Extend + default: + formatPattern = "-" + episodeFormat.EpisodePattern; + seasonEpisodePattern = FormatNumberTokens(seasonEpisodePattern, formatPattern, episodes); + break; } - seasonEpisodePattern = ReplaceNumberTokens(seasonEpisodePattern, episodes); - var token = String.Format("{{Season Episode{0}}}", index++); pattern = pattern.Replace(episodeFormat.SeasonEpisodePattern, token); tokenHandlers[token] = m => seasonEpisodePattern; @@ -339,34 +348,44 @@ namespace NzbDrone.Core.Organizer } var absoluteEpisodePattern = absoluteEpisodeFormat.AbsoluteEpisodePattern; + string formatPattern; - foreach (var episode in episodes.Skip(1)) + switch ((MultiEpisodeStyle) namingConfig.MultiEpisodeStyle) { - switch ((MultiEpisodeStyle)namingConfig.MultiEpisodeStyle) - { - case MultiEpisodeStyle.Duplicate: - absoluteEpisodePattern += absoluteEpisodeFormat.Separator + - absoluteEpisodeFormat.AbsoluteEpisodePattern; - break; - case MultiEpisodeStyle.Repeat: - absoluteEpisodePattern += absoluteEpisodeFormat.Separator + - absoluteEpisodeFormat.AbsoluteEpisodePattern; - break; + case MultiEpisodeStyle.Duplicate: + formatPattern = absoluteEpisodeFormat.Separator + absoluteEpisodeFormat.AbsoluteEpisodePattern; + absoluteEpisodePattern = FormatAbsoluteNumberTokens(absoluteEpisodePattern, formatPattern, episodes); + break; + + case MultiEpisodeStyle.Repeat: + var repeatSeparator = absoluteEpisodeFormat.Separator.Trim().IsNullOrWhiteSpace() ? " " : absoluteEpisodeFormat.Separator.Trim(); + + formatPattern = repeatSeparator + absoluteEpisodeFormat.AbsoluteEpisodePattern; + absoluteEpisodePattern = FormatAbsoluteNumberTokens(absoluteEpisodePattern, formatPattern, episodes); + break; - case MultiEpisodeStyle.Scene: - absoluteEpisodePattern += "-" + absoluteEpisodeFormat.AbsoluteEpisodePattern; - break; + case MultiEpisodeStyle.Scene: + formatPattern = "-" + absoluteEpisodeFormat.AbsoluteEpisodePattern; + absoluteEpisodePattern = FormatAbsoluteNumberTokens(absoluteEpisodePattern, formatPattern, episodes); + break; + + case MultiEpisodeStyle.Range: + formatPattern = "-" + absoluteEpisodeFormat.AbsoluteEpisodePattern; + var eps = new List {episodes.First()}; + + if (episodes.Count > 1) eps.Add(episodes.Last()); + + absoluteEpisodePattern = FormatAbsoluteNumberTokens(absoluteEpisodePattern, formatPattern, eps); + break; //MultiEpisodeStyle.Extend - default: - absoluteEpisodePattern += "-" + absoluteEpisodeFormat.AbsoluteEpisodePattern; - break; - } + default: + formatPattern = "-" + absoluteEpisodeFormat.AbsoluteEpisodePattern; + absoluteEpisodePattern = FormatAbsoluteNumberTokens(absoluteEpisodePattern, formatPattern, episodes); + break; } - absoluteEpisodePattern = ReplaceAbsoluteNumberTokens(absoluteEpisodePattern, episodes); - var token = String.Format("{{Absolute Pattern{0}}}", index++); pattern = pattern.Replace(absoluteEpisodeFormat.AbsoluteEpisodePattern, token); tokenHandlers[token] = m => absoluteEpisodePattern; @@ -554,31 +573,30 @@ namespace NzbDrone.Core.Organizer return replacementText; } - private string ReplaceNumberTokens(string pattern, List episodes) + private string FormatNumberTokens(string basePattern, string formatPattern, List episodes) { - var episodeIndex = 0; - pattern = EpisodeRegex.Replace(pattern, match => + var pattern = String.Empty; + + for (int i = 0; i < episodes.Count; i++) { - var episode = episodes[episodeIndex]; - episodeIndex++; + var patternToReplace = i == 0 ? basePattern : formatPattern; - return ReplaceNumberToken(match.Groups["episode"].Value, episode.EpisodeNumber); - }); + pattern += EpisodeRegex.Replace(patternToReplace, match => ReplaceNumberToken(match.Groups["episode"].Value, episodes[i].EpisodeNumber)); + } return ReplaceSeasonTokens(pattern, episodes.First().SeasonNumber); } - private string ReplaceAbsoluteNumberTokens(string pattern, List episodes) + private string FormatAbsoluteNumberTokens(string basePattern, string formatPattern, List episodes) { - var episodeIndex = 0; - pattern = AbsoluteEpisodeRegex.Replace(pattern, match => + var pattern = String.Empty; + + for (int i = 0; i < episodes.Count; i++) { - var episode = episodes[episodeIndex]; - episodeIndex++; + var patternToReplace = i == 0 ? basePattern : formatPattern; - //TODO: We need to handle this null check somewhere, I think earlier is better... - return ReplaceNumberToken(match.Groups["absolute"].Value, episode.AbsoluteEpisodeNumber.Value); - }); + pattern += AbsoluteEpisodeRegex.Replace(patternToReplace, match => ReplaceNumberToken(match.Groups["absolute"].Value, episodes[i].AbsoluteEpisodeNumber.Value)); + } return ReplaceSeasonTokens(pattern, episodes.First().SeasonNumber); } @@ -684,6 +702,7 @@ namespace NzbDrone.Core.Organizer Extend = 0, Duplicate = 1, Repeat = 2, - Scene = 3 + Scene = 3, + Range = 4 } } \ No newline at end of file diff --git a/src/NzbDrone.Core/Organizer/FilenameSampleService.cs b/src/NzbDrone.Core/Organizer/FilenameSampleService.cs index af4efac85..5cacb1158 100644 --- a/src/NzbDrone.Core/Organizer/FilenameSampleService.cs +++ b/src/NzbDrone.Core/Organizer/FilenameSampleService.cs @@ -13,6 +13,7 @@ namespace NzbDrone.Core.Organizer SampleResult GetMultiEpisodeSample(NamingConfig nameSpec); SampleResult GetDailySample(NamingConfig nameSpec); SampleResult GetAnimeSample(NamingConfig nameSpec); + SampleResult GetAnimeMultiEpisodeSample(NamingConfig nameSpec); String GetSeriesFolderSample(NamingConfig nameSpec); String GetSeasonFolderSample(NamingConfig nameSpec); } @@ -25,12 +26,14 @@ namespace NzbDrone.Core.Organizer private static Series _animeSeries; private static Episode _episode1; private static Episode _episode2; + private static Episode _episode3; private static List _singleEpisode; private static List _multiEpisodes; private static EpisodeFile _singleEpisodeFile; private static EpisodeFile _multiEpisodeFile; private static EpisodeFile _dailyEpisodeFile; private static EpisodeFile _animeEpisodeFile; + private static EpisodeFile _animeMultiEpisodeFile; public FileNameSampleService(IBuildFileNames buildFileNames) { @@ -71,8 +74,16 @@ namespace NzbDrone.Core.Organizer AbsoluteEpisodeNumber = 2 }; + _episode3 = new Episode + { + SeasonNumber = 1, + EpisodeNumber = 3, + Title = "Episode Title (3)", + AbsoluteEpisodeNumber = 3 + }; + _singleEpisode = new List { _episode1 }; - _multiEpisodes = new List { _episode1, _episode2 }; + _multiEpisodes = new List { _episode1, _episode2, _episode3 }; var mediaInfo = new MediaInfoModel() { @@ -102,8 +113,8 @@ namespace NzbDrone.Core.Organizer _multiEpisodeFile = new EpisodeFile { Quality = new QualityModel(Quality.HDTV720p), - RelativePath = "Series.Title.S01E01-E02.720p.HDTV.x264-EVOLVE.mkv", - SceneName = "Series.Title.S01E01-E02.720p.HDTV.x264-EVOLVE", + RelativePath = "Series.Title.S01E01-E03.720p.HDTV.x264-EVOLVE.mkv", + SceneName = "Series.Title.S01E01-E03.720p.HDTV.x264-EVOLVE", ReleaseGroup = "RlsGrp", MediaInfo = mediaInfo, }; @@ -120,8 +131,17 @@ namespace NzbDrone.Core.Organizer _animeEpisodeFile = new EpisodeFile { Quality = new QualityModel(Quality.HDTV720p), - RelativePath = "Series.Title.001.HDTV.x264-EVOLVE.mkv", - SceneName = "Series.Title.001.HDTV.x264-EVOLVE", + RelativePath = "[RlsGroup] Series Title - 001 [720p].mkv", + SceneName = "[RlsGroup] Series Title - 001 [720p]", + ReleaseGroup = "RlsGrp", + MediaInfo = mediaInfoAnime + }; + + _animeMultiEpisodeFile = new EpisodeFile + { + Quality = new QualityModel(Quality.HDTV720p), + RelativePath = "[RlsGroup] Series Title - 001 - 103 [720p].mkv", + SceneName = "[RlsGroup] Series Title - 001 - 103 [720p]", ReleaseGroup = "RlsGrp", MediaInfo = mediaInfoAnime }; @@ -179,6 +199,19 @@ namespace NzbDrone.Core.Organizer return result; } + public SampleResult GetAnimeMultiEpisodeSample(NamingConfig nameSpec) + { + var result = new SampleResult + { + FileName = BuildSample(_multiEpisodes, _animeSeries, _animeMultiEpisodeFile, nameSpec), + Series = _animeSeries, + Episodes = _multiEpisodes, + EpisodeFile = _animeMultiEpisodeFile + }; + + return result; + } + public string GetSeriesFolderSample(NamingConfig nameSpec) { return _buildFileNames.GetSeriesFolder(_standardSeries, nameSpec); diff --git a/src/NzbDrone.Core/Organizer/FilenameValidationService.cs b/src/NzbDrone.Core/Organizer/FilenameValidationService.cs index 13d91aca6..9367c11d8 100644 --- a/src/NzbDrone.Core/Organizer/FilenameValidationService.cs +++ b/src/NzbDrone.Core/Organizer/FilenameValidationService.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using FluentValidation.Results; using NzbDrone.Core.Parser.Model; diff --git a/src/NzbDrone.Core/Parser/Parser.cs b/src/NzbDrone.Core/Parser/Parser.cs index 13a5a468e..491c55ab1 100644 --- a/src/NzbDrone.Core/Parser/Parser.cs +++ b/src/NzbDrone.Core/Parser/Parser.cs @@ -87,7 +87,7 @@ namespace NzbDrone.Core.Parser RegexOptions.IgnoreCase | RegexOptions.Compiled), //Episodes with airdate - new Regex(@"^(?.+?)?\W*(?<airyear>\d{4})\W+(?<airmonth>[0-1][0-9])\W+(?<airday>[0-3][0-9])", + new Regex(@"^(?<title>.+?)?\W*(?<airyear>\d{4})\W+(?<airmonth>[0-1][0-9])\W+(?<airday>[0-3][0-9])(?!\W+[0-3][0-9])", RegexOptions.IgnoreCase | RegexOptions.Compiled), //Supports 1103/1113 naming diff --git a/src/UI/Settings/MediaManagement/Naming/NamingView.js b/src/UI/Settings/MediaManagement/Naming/NamingView.js index bd86e1490..4bcf60c56 100644 --- a/src/UI/Settings/MediaManagement/Naming/NamingView.js +++ b/src/UI/Settings/MediaManagement/Naming/NamingView.js @@ -13,16 +13,17 @@ define( template: 'Settings/MediaManagement/Naming/NamingViewTemplate', ui: { - namingOptions : '.x-naming-options', - renameEpisodesCheckbox: '.x-rename-episodes', - singleEpisodeExample : '.x-single-episode-example', - multiEpisodeExample : '.x-multi-episode-example', - dailyEpisodeExample : '.x-daily-episode-example', - animeEpisodeExample : '.x-anime-episode-example', - namingTokenHelper : '.x-naming-token-helper', - multiEpisodeStyle : '.x-multi-episode-style', - seriesFolderExample : '.x-series-folder-example', - seasonFolderExample : '.x-season-folder-example' + namingOptions : '.x-naming-options', + renameEpisodesCheckbox : '.x-rename-episodes', + singleEpisodeExample : '.x-single-episode-example', + multiEpisodeExample : '.x-multi-episode-example', + dailyEpisodeExample : '.x-daily-episode-example', + animeEpisodeExample : '.x-anime-episode-example', + animeMultiEpisodeExample : '.x-anime-multi-episode-example', + namingTokenHelper : '.x-naming-token-helper', + multiEpisodeStyle : '.x-multi-episode-style', + seriesFolderExample : '.x-series-folder-example', + seasonFolderExample : '.x-season-folder-example' }, events: { @@ -70,6 +71,7 @@ define( this.ui.multiEpisodeExample.html(this.namingSampleModel.get('multiEpisodeExample')); this.ui.dailyEpisodeExample.html(this.namingSampleModel.get('dailyEpisodeExample')); this.ui.animeEpisodeExample.html(this.namingSampleModel.get('animeEpisodeExample')); + this.ui.animeMultiEpisodeExample.html(this.namingSampleModel.get('animeMultiEpisodeExample')); this.ui.seriesFolderExample.html(this.namingSampleModel.get('seriesFolderExample')); this.ui.seasonFolderExample.html(this.namingSampleModel.get('seasonFolderExample')); }, diff --git a/src/UI/Settings/MediaManagement/Naming/NamingViewTemplate.hbs b/src/UI/Settings/MediaManagement/Naming/NamingViewTemplate.hbs index 7ee9b5bed..9232dd5a3 100644 --- a/src/UI/Settings/MediaManagement/Naming/NamingViewTemplate.hbs +++ b/src/UI/Settings/MediaManagement/Naming/NamingViewTemplate.hbs @@ -175,6 +175,7 @@ <option value="1">Duplicate</option> <option value="2">Repeat</option> <option value="3">Scene</option> + <option value="4">Range</option> </select> </div> </div> @@ -212,6 +213,14 @@ </div> </div> + <div class="form-group"> + <label class="col-sm-3 control-label">Anime Multi-Episode Example</label> + + <div class="col-sm-8"> + <p class="form-control-static x-anime-multi-episode-example naming-example"></p> + </div> + </div> + <div class="form-group"> <label class="col-sm-3 control-label">Series Folder Example</label>