diff --git a/src/NzbDrone.Core.Test/OrganizerTests/BuildFilePathFixture.cs b/src/NzbDrone.Core.Test/OrganizerTests/BuildFilePathFixture.cs index 8013ebc07..2bc2b2a49 100644 --- a/src/NzbDrone.Core.Test/OrganizerTests/BuildFilePathFixture.cs +++ b/src/NzbDrone.Core.Test/OrganizerTests/BuildFilePathFixture.cs @@ -26,9 +26,9 @@ namespace NzbDrone.Core.Test.OrganizerTests } [Test] - [TestCase("30 Rock - S01E05 - Episode Title", 1, true, "Season {0season}", @"C:\Test\30 Rock\Season 01\30 Rock - S01E05 - Episode Title.mkv")] + [TestCase("30 Rock - S01E05 - Episode Title", 1, true, "Season {season:00}", @"C:\Test\30 Rock\Season 01\30 Rock - S01E05 - Episode Title.mkv")] [TestCase("30 Rock - S01E05 - Episode Title", 1, true, "Season {season}", @"C:\Test\30 Rock\Season 1\30 Rock - S01E05 - Episode Title.mkv")] - [TestCase("30 Rock - S01E05 - Episode Title", 1, false, "Season {0season}", @"C:\Test\30 Rock\30 Rock - S01E05 - Episode Title.mkv")] + [TestCase("30 Rock - S01E05 - Episode Title", 1, false, "Season {season:00}", @"C:\Test\30 Rock\30 Rock - S01E05 - Episode Title.mkv")] [TestCase("30 Rock - S01E05 - Episode Title", 1, false, "Season {season}", @"C:\Test\30 Rock\30 Rock - S01E05 - Episode Title.mkv")] [TestCase("30 Rock - S01E05 - Episode Title", 1, true, "ReallyUglySeasonFolder {season}", @"C:\Test\30 Rock\ReallyUglySeasonFolder 1\30 Rock - S01E05 - Episode Title.mkv")] [TestCase("30 Rock - S00E05 - Episode Title", 0, true, "Season {season}", @"C:\Test\30 Rock\Specials\30 Rock - S00E05 - Episode Title.mkv")] diff --git a/src/NzbDrone.Core.Test/OrganizerTests/GetNewFilenameFixture.cs b/src/NzbDrone.Core.Test/OrganizerTests/GetNewFilenameFixture.cs index 44efa406c..373a4aa3c 100644 --- a/src/NzbDrone.Core.Test/OrganizerTests/GetNewFilenameFixture.cs +++ b/src/NzbDrone.Core.Test/OrganizerTests/GetNewFilenameFixture.cs @@ -120,8 +120,6 @@ namespace NzbDrone.Core.Test.OrganizerTests .Should().Be("south park"); } - - [Test] public void should_replace_episode_title() { @@ -151,10 +149,10 @@ namespace NzbDrone.Core.Test.OrganizerTests } [Test] - public void should_replace_0season_number_with_two_digits() + public void should_replace_season00_number_with_two_digits() { _episode1.SeasonNumber = 1; - _namingConfig.StandardEpisodeFormat = "{0season}x{episode}"; + _namingConfig.StandardEpisodeFormat = "{season:00}x{episode}"; Subject.BuildFilename(new List { _episode1 }, _series, _episodeFile) .Should().Be("01x6"); @@ -171,10 +169,10 @@ namespace NzbDrone.Core.Test.OrganizerTests } [Test] - public void should_replace_0episode_number_with_two_digits() + public void should_replace_episode00_number_with_two_digits() { _episode1.SeasonNumber = 1; - _namingConfig.StandardEpisodeFormat = "{season}x{0episode}"; + _namingConfig.StandardEpisodeFormat = "{season}x{episode:00}"; Subject.BuildFilename(new List { _episode1 }, _series, _episodeFile) .Should().Be("1x06"); @@ -202,7 +200,7 @@ namespace NzbDrone.Core.Test.OrganizerTests [Test] public void should_replace_all_contents_in_pattern() { - _namingConfig.StandardEpisodeFormat = "{Series Title} - S{0season}E{0episode} - {Episode Title} [{Quality Title}]"; + _namingConfig.StandardEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Episode Title} [{Quality Title}]"; Subject.BuildFilename(new List {_episode1}, _series, _episodeFile) .Should().Be("South Park - S15E06 - City Sushi [HDTV-720p]"); @@ -232,7 +230,7 @@ namespace NzbDrone.Core.Test.OrganizerTests [Test] public void should_only_have_one_episodeTitle_when_episode_titles_are_the_same() { - _namingConfig.StandardEpisodeFormat = "{Series Title} - S{0season}E{0episode} - {Episode Title}"; + _namingConfig.StandardEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Episode Title}"; _namingConfig.MultiEpisodeStyle = 3; var episode = Builder.CreateNew() @@ -255,7 +253,7 @@ namespace NzbDrone.Core.Test.OrganizerTests [Test] public void should_have_two_episodeTitles_when_episode_titles_are_not_the_same() { - _namingConfig.StandardEpisodeFormat = "{Series Title} - S{0season}E{0episode} - {Episode Title}"; + _namingConfig.StandardEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Episode Title}"; _namingConfig.MultiEpisodeStyle = 3; _episode1.Title = "Hello"; @@ -298,7 +296,7 @@ namespace NzbDrone.Core.Test.OrganizerTests [Test] public void should_format_extend_multi_episode_properly() { - _namingConfig.StandardEpisodeFormat = "{Series Title} - S{0season}E{0episode} - {Episode Title}"; + _namingConfig.StandardEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Episode Title}"; _namingConfig.MultiEpisodeStyle = 0; Subject.BuildFilename(new List {_episode1, _episode2}, _series, _episodeFile) @@ -308,7 +306,7 @@ namespace NzbDrone.Core.Test.OrganizerTests [Test] public void should_format_duplicate_multi_episode_properly() { - _namingConfig.StandardEpisodeFormat = "{Series Title} - S{0season}E{0episode} - {Episode Title}"; + _namingConfig.StandardEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Episode Title}"; _namingConfig.MultiEpisodeStyle = 1; Subject.BuildFilename(new List { _episode1, _episode2 }, _series, _episodeFile) @@ -318,7 +316,7 @@ namespace NzbDrone.Core.Test.OrganizerTests [Test] public void should_format_repeat_multi_episode_properly() { - _namingConfig.StandardEpisodeFormat = "{Series Title} - S{0season}E{0episode} - {Episode Title}"; + _namingConfig.StandardEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Episode Title}"; _namingConfig.MultiEpisodeStyle = 2; Subject.BuildFilename(new List { _episode1, _episode2 }, _series, _episodeFile) @@ -328,7 +326,7 @@ namespace NzbDrone.Core.Test.OrganizerTests [Test] public void should_format_scene_multi_episode_properly() { - _namingConfig.StandardEpisodeFormat = "{Series Title} - S{0season}E{0episode} - {Episode Title}"; + _namingConfig.StandardEpisodeFormat = "{Series Title} - S{season:00}E{episode:00} - {Episode Title}"; _namingConfig.MultiEpisodeStyle = 3; Subject.BuildFilename(new List { _episode1, _episode2 }, _series, _episodeFile) diff --git a/src/NzbDrone.Core/Datastore/Migration/029_add_formats_to_naming_config.cs b/src/NzbDrone.Core/Datastore/Migration/029_add_formats_to_naming_config.cs index b723dca46..f3bbba37f 100644 --- a/src/NzbDrone.Core/Datastore/Migration/029_add_formats_to_naming_config.cs +++ b/src/NzbDrone.Core/Datastore/Migration/029_add_formats_to_naming_config.cs @@ -103,7 +103,7 @@ namespace NzbDrone.Core.Datastore.Migration { Id = 0, Name = "1x05", - Pattern = "{season}x{0episode}", + Pattern = "{season}x{episode:00}", EpisodeSeparator = "x" }, @@ -111,21 +111,21 @@ namespace NzbDrone.Core.Datastore.Migration { Id = 1, Name = "01x05", - Pattern = "{0season}x{0episode}", + Pattern = "{season:00}x{episode:00}", EpisodeSeparator = "x" }, new { Id = 2, Name = "S01E05", - Pattern = "S{0season}E{0episode}", + Pattern = "S{season:00}E{episode:00}", EpisodeSeparator = "E" }, new { Id = 3, Name = "s01e05", - Pattern = "s{0season}e{0episode}", + Pattern = "s{season:00}e{episode:00}", EpisodeSeparator = "e" } }; diff --git a/src/NzbDrone.Core/Datastore/Migration/030_update_season_folder_format.cs b/src/NzbDrone.Core/Datastore/Migration/030_update_season_folder_format.cs index 6b57fd00c..133e5146a 100644 --- a/src/NzbDrone.Core/Datastore/Migration/030_update_season_folder_format.cs +++ b/src/NzbDrone.Core/Datastore/Migration/030_update_season_folder_format.cs @@ -28,9 +28,9 @@ namespace NzbDrone.Core.Datastore.Migration value = value.Replace("%sn", "{Series Title}") .Replace("%s.n", "{Series.Title}") .Replace("%s", "{season}") - .Replace("%0s", "{0season}") + .Replace("%0s", "{season:00}") .Replace("%e", "{episode}") - .Replace("%0e", "{0episode}"); + .Replace("%0e", "{episode:00}"); using (IDbCommand updateCmd = conn.CreateCommand()) diff --git a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs index 51076b228..e94d7b0ac 100644 --- a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs +++ b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs @@ -28,13 +28,13 @@ namespace NzbDrone.Core.Organizer private static readonly Regex TitleRegex = new Regex(@"(?\{(?:\w+)(?\s|\W|_)\w+\})", RegexOptions.Compiled | RegexOptions.IgnoreCase); - private static readonly Regex EpisodeRegex = new Regex(@"(?\{0*(?:episode)})", + private static readonly Regex EpisodeRegex = new Regex(@"(?\{episode(?:\:0+)?})", RegexOptions.Compiled | RegexOptions.IgnoreCase); - private static readonly Regex SeasonRegex = new Regex(@"(?\{0*(?:season)})", + private static readonly Regex SeasonRegex = new Regex(@"(?\{season(?:\:0+)?})", RegexOptions.Compiled | RegexOptions.IgnoreCase); - private static readonly Regex SeasonEpisodePatternRegex = new Regex(@"(?(?<=}).+?)?(?s?{0?season}(?e|x)?(?{0?episode}))(?.+?(?={))?", + private static readonly Regex SeasonEpisodePatternRegex = new Regex(@"(?(?<=}).+?)?(?s?{season(?:\:0+)?}(?e|x)?(?{episode(?:\:0+)?}))(?.+?(?={))?", RegexOptions.Compiled | RegexOptions.IgnoreCase); public FileNameBuilder(INamingConfigService namingConfigService, IConfigService configService, Logger logger) @@ -240,10 +240,11 @@ namespace NzbDrone.Core.Organizer private string ReplaceNumberToken(string token, int value) { - var zeroCount = token.Count(z => z == '0'); - return value.ToString().PadLeft(zeroCount + 1, '0'); - } + var split = token.Trim('{', '}').Split(':'); + if (split.Length == 1) return value.ToString("0"); + return value.ToString(split[1]); + } } public enum MultiEpisodeStyle diff --git a/src/NzbDrone.Integration.Test/NamingConfigTests.cs b/src/NzbDrone.Integration.Test/NamingConfigTests.cs index 5006809b6..e2280cbb5 100644 --- a/src/NzbDrone.Integration.Test/NamingConfigTests.cs +++ b/src/NzbDrone.Integration.Test/NamingConfigTests.cs @@ -26,7 +26,7 @@ namespace NzbDrone.Integration.Test { var config = NamingConfig.GetSingle(); config.RenameEpisodes = false; - config.StandardEpisodeFormat = "{Series Title} - {season}x{0episode} - {Episode Title}"; + config.StandardEpisodeFormat = "{Series Title} - {season}x{episode:00} - {Episode Title}"; config.DailyEpisodeFormat = "{Series Title} - {Air-Date} - {Episode Title}"; var result = NamingConfig.Put(config); diff --git a/src/UI/Settings/MediaManagement/Naming/Partials/EpisodeNamingPartial.html b/src/UI/Settings/MediaManagement/Naming/Partials/EpisodeNamingPartial.html index c56795719..4c20f4ffa 100644 --- a/src/UI/Settings/MediaManagement/Naming/Partials/EpisodeNamingPartial.html +++ b/src/UI/Settings/MediaManagement/Naming/Partials/EpisodeNamingPartial.html @@ -2,6 +2,6 @@ Episode diff --git a/src/UI/Settings/MediaManagement/Naming/Partials/SeasonNamingPartial.html b/src/UI/Settings/MediaManagement/Naming/Partials/SeasonNamingPartial.html index 1174a055d..2c56024da 100644 --- a/src/UI/Settings/MediaManagement/Naming/Partials/SeasonNamingPartial.html +++ b/src/UI/Settings/MediaManagement/Naming/Partials/SeasonNamingPartial.html @@ -2,6 +2,6 @@ Season diff --git a/src/UI/Settings/MediaManagement/Naming/Wizard/NamingWizardView.js b/src/UI/Settings/MediaManagement/Naming/Wizard/NamingWizardView.js index 8a6dc9d3e..d98bfb6db 100644 --- a/src/UI/Settings/MediaManagement/Naming/Wizard/NamingWizardView.js +++ b/src/UI/Settings/MediaManagement/Naming/Wizard/NamingWizardView.js @@ -84,16 +84,16 @@ define( switch (this.model.get('numberStyle')) { case '0': - this.standardEpisodeFormat += '{season}x{0episode}'; + this.standardEpisodeFormat += '{season}x{episode:00}'; break; case '1': - this.standardEpisodeFormat += '{0season}x{0episode}'; + this.standardEpisodeFormat += '{season:00}x{episode:00}'; break; case '2': - this.standardEpisodeFormat += 'S{0season}E{0episode}'; + this.standardEpisodeFormat += 'S{season:00}E{episode:00}'; break; case '3': - this.standardEpisodeFormat += 's{0season}e{0episode}'; + this.standardEpisodeFormat += 's{season:00}e{episode:00}'; break; default: this.standardEpisodeFormat += 'Unknown Number Pattern';