diff --git a/src/NzbDrone.Core.Test/OrganizerTests/CleanTitleFixture.cs b/src/NzbDrone.Core.Test/OrganizerTests/CleanTitleFixture.cs index 82b8b2e76..b49084537 100644 --- a/src/NzbDrone.Core.Test/OrganizerTests/CleanTitleFixture.cs +++ b/src/NzbDrone.Core.Test/OrganizerTests/CleanTitleFixture.cs @@ -60,7 +60,7 @@ namespace NzbDrone.Core.Test.OrganizerTests [TestCase("Tamara Ecclestone: Billion $$ Girl", "Tamara Ecclestone Billion $$ Girl")] [TestCase("Marvel's Agents of S.H.I.E.L.D.", "Marvels Agents of S.H.I.E.L.D")] [TestCase("Castle (2009)", "Castle 2009")] -// [TestCase("", "")] + [TestCase("Law & Order (UK)", "Law and Order UK")] // [TestCase("", "")] public void should_get_expected_title_back(string title, string expected) { @@ -70,5 +70,22 @@ namespace NzbDrone.Core.Test.OrganizerTests Subject.BuildFileName(new List { _episode }, _series, _episodeFile) .Should().Be(expected); } + + [Test] + public void should_use_and_as_separator_for_multiple_episodes() + { + var episodes = Builder.CreateListOfSize(2) + .TheFirst(1) + .With(e => e.Title = "Surrender Benson") + .TheNext(1) + .With(e => e.Title = "Imprisoned Lives") + .Build() + .ToList(); + + _namingConfig.StandardEpisodeFormat = "{Episode CleanTitle}"; + + Subject.BuildFileName(episodes, _series, _episodeFile) + .Should().Be(episodes.First().Title + " and " + episodes.Last().Title); + } } } diff --git a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs index 815905375..fb0ba8767 100644 --- a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs +++ b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs @@ -56,7 +56,6 @@ namespace NzbDrone.Core.Organizer private static readonly Regex FileNameCleanupRegex = new Regex(@"([- ._])(\1)+", RegexOptions.Compiled); private static readonly Regex TrimSeparatorsRegex = new Regex(@"[- ._]$", RegexOptions.Compiled); - //private static readonly Regex ScenifyRemoveChars = new Regex(@"(?|\/|\\|;|:|'|""|\||`|~|!|@|$|%|^|&|\*|-|_|=){1}(?=\s)|('|:)(?=s|\s)|(\(|\)|\[|\]|\{|\})", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static readonly Regex ScenifyReplaceChars = new Regex(@"[\/]", RegexOptions.Compiled | RegexOptions.IgnoreCase); @@ -238,6 +237,7 @@ namespace NzbDrone.Core.Organizer public static string CleanTitle(string title) { + title = title.Replace("&", "and"); title = ScenifyReplaceChars.Replace(title, " "); title = ScenifyRemoveChars.Replace(title, String.Empty); @@ -408,8 +408,8 @@ namespace NzbDrone.Core.Organizer tokenHandlers["{Air Date}"] = m => "Unknown"; } - tokenHandlers["{Episode Title}"] = m => GetEpisodeTitle(episodes); - tokenHandlers["{Episode CleanTitle}"] = m => CleanTitle(GetEpisodeTitle(episodes)); + tokenHandlers["{Episode Title}"] = m => GetEpisodeTitle(episodes, "+"); + tokenHandlers["{Episode CleanTitle}"] = m => CleanTitle(GetEpisodeTitle(episodes, "and")); } private void AddEpisodeFileTokens(Dictionary> tokenHandlers, Series series, EpisodeFile episodeFile) @@ -645,8 +645,10 @@ namespace NzbDrone.Core.Organizer }).ToArray()); } - private string GetEpisodeTitle(List episodes) + private string GetEpisodeTitle(List episodes, string separator) { + separator = String.Format(" {0} ", separator.Trim()); + if (episodes.Count == 1) { return episodes.First().Title.TrimEnd(EpisodeTitleTrimCharacters); @@ -657,7 +659,7 @@ namespace NzbDrone.Core.Organizer .Select(Parser.Parser.CleanupEpisodeTitle) .Distinct(); - return String.Join(" + ", titles); + return String.Join(separator, titles); } private string GetQualityProper(Series series, QualityModel quality)