From 7142d1f2249c1cbea1a1035476216c4b8350cb19 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Mon, 28 Mar 2022 17:34:15 -0700 Subject: [PATCH] Improve usage of Original Title renaming token Closes #7168 Fixed: Don't recursively add the current file name to new file name when '{Original Title}' is used in addition to other naming tokens (cherry picked from commit ebb48a19cc792c71bfbd57d5f106067190d95339) --- .../OriginalTitleFixture.cs | 88 +++++++++++++++++++ .../Organizer/FileNameBuilder.cs | 27 +++--- 2 files changed, 105 insertions(+), 10 deletions(-) create mode 100644 src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/OriginalTitleFixture.cs diff --git a/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/OriginalTitleFixture.cs b/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/OriginalTitleFixture.cs new file mode 100644 index 000000000..b0668f557 --- /dev/null +++ b/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/OriginalTitleFixture.cs @@ -0,0 +1,88 @@ +using System.Collections.Generic; +using System.Linq; +using FizzWare.NBuilder; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.CustomFormats; +using NzbDrone.Core.MediaFiles; +using NzbDrone.Core.Movies; +using NzbDrone.Core.Organizer; +using NzbDrone.Core.Qualities; +using NzbDrone.Core.Test.Framework; + +namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests +{ + [TestFixture] + public class OriginalTitleFixture : CoreTest + { + private Movie _movie; + private MovieFile _movieFile; + private NamingConfig _namingConfig; + + [SetUp] + public void Setup() + { + _movie = Builder + .CreateNew() + .With(s => s.Title = "My Movie") + .Build(); + + _movieFile = new MovieFile { Quality = new QualityModel(Quality.HDTV720p), ReleaseGroup = "RadarrTest" }; + + _namingConfig = NamingConfig.Default; + _namingConfig.RenameMovies = true; + + Mocker.GetMock() + .Setup(c => c.GetConfig()).Returns(_namingConfig); + + Mocker.GetMock() + .Setup(v => v.Get(Moq.It.IsAny())) + .Returns(v => Quality.DefaultQualityDefinitions.First(c => c.Quality == v)); + + Mocker.GetMock() + .Setup(v => v.All()) + .Returns(new List()); + } + + [Test] + public void should_not_recursively_include_current_filename() + { + _movieFile.RelativePath = "My Movie"; + _namingConfig.StandardMovieFormat = "{Movie Title} {[Original Title]}"; + + Subject.BuildFileName(_movie, _movieFile) + .Should().Be("My Movie"); + } + + [Test] + public void should_include_original_title_if_not_current_file_name() + { + _movieFile.SceneName = "my.movie.2008"; + _movieFile.RelativePath = "My Movie"; + _namingConfig.StandardMovieFormat = "{Movie Title} {[Original Title]}"; + + Subject.BuildFileName(_movie, _movieFile) + .Should().Be("My Movie [my.movie.2008]"); + } + + [Test] + public void should_include_current_filename_if_not_renaming_files() + { + _movieFile.SceneName = "my.movie.2008"; + _namingConfig.RenameMovies = false; + + Subject.BuildFileName(_movie, _movieFile) + .Should().Be("my.movie.2008"); + } + + [Test] + public void should_include_current_filename_if_not_including_multiple_naming_tokens() + { + _movieFile.RelativePath = "My Movie"; + _namingConfig.StandardMovieFormat = "{Original Title}"; + + Subject.BuildFileName(_movie, _movieFile) + .Should().Be("My Movie"); + } + } +} diff --git a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs index 75a758d38..0cdd580fe 100644 --- a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs +++ b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs @@ -103,11 +103,12 @@ public string BuildFileName(Movie movie, MovieFile movieFile, NamingConfig namin if (!namingConfig.RenameMovies) { - return GetOriginalTitle(movieFile); + return GetOriginalTitle(movieFile, false); } var pattern = namingConfig.StandardMovieFormat; var tokenHandlers = new Dictionary>(FileNameBuilderTokenEqualityComparer.Instance); + var multipleTokens = TitleRegex.Matches(pattern).Count > 1; UpdateMediaInfoIfNeeded(pattern, movieFile, movie); @@ -116,7 +117,7 @@ public string BuildFileName(Movie movie, MovieFile movieFile, NamingConfig namin AddIdTokens(tokenHandlers, movie); AddQualityTokens(tokenHandlers, movie, movieFile); AddMediaInfoTokens(tokenHandlers, movieFile); - AddMovieFileTokens(tokenHandlers, movieFile); + AddMovieFileTokens(tokenHandlers, movieFile, multipleTokens); AddEditionTagsTokens(tokenHandlers, movieFile); AddCustomFormats(tokenHandlers, movie, movieFile, customFormats); @@ -167,6 +168,7 @@ public string GetMovieFolder(Movie movie, NamingConfig namingConfig = null) var pattern = namingConfig.MovieFolderFormat; var tokenHandlers = new Dictionary>(FileNameBuilderTokenEqualityComparer.Instance); + var multipleTokens = TitleRegex.Matches(pattern).Count > 1; AddMovieTokens(tokenHandlers, movie); AddReleaseDateTokens(tokenHandlers, movie.Year); @@ -176,12 +178,12 @@ public string GetMovieFolder(Movie movie, NamingConfig namingConfig = null) { AddQualityTokens(tokenHandlers, movie, movieFile); AddMediaInfoTokens(tokenHandlers, movieFile); - AddMovieFileTokens(tokenHandlers, movieFile); + AddMovieFileTokens(tokenHandlers, movieFile, multipleTokens); AddEditionTagsTokens(tokenHandlers, movieFile); } else { - AddMovieFileTokens(tokenHandlers, new MovieFile { SceneName = $"{movie.Title} {movie.Year}", RelativePath = $"{movie.Title} {movie.Year}" }); + AddMovieFileTokens(tokenHandlers, new MovieFile { SceneName = $"{movie.Title} {movie.Year}", RelativePath = $"{movie.Title} {movie.Year}" }, multipleTokens); } var splitPatterns = pattern.Split(new char[] { '\\', '/' }, StringSplitOptions.RemoveEmptyEntries); @@ -306,10 +308,10 @@ private void AddIdTokens(Dictionary> tokenHandl tokenHandlers["{TmdbId}"] = m => movie.MovieMetadata.Value.TmdbId.ToString(); } - private void AddMovieFileTokens(Dictionary> tokenHandlers, MovieFile movieFile) + private void AddMovieFileTokens(Dictionary> tokenHandlers, MovieFile movieFile, bool multipleTokens) { - tokenHandlers["{Original Title}"] = m => GetOriginalTitle(movieFile); - tokenHandlers["{Original Filename}"] = m => GetOriginalFileName(movieFile); + tokenHandlers["{Original Title}"] = m => GetOriginalTitle(movieFile, multipleTokens); + tokenHandlers["{Original Filename}"] = m => GetOriginalFileName(movieFile, multipleTokens); tokenHandlers["{Release Group}"] = m => movieFile.ReleaseGroup ?? m.DefaultValue("Radarr"); } @@ -572,18 +574,23 @@ private string GetQualityReal(Movie movie, QualityModel quality) return string.Empty; } - private string GetOriginalTitle(MovieFile movieFile) + private string GetOriginalTitle(MovieFile movieFile, bool multipleTokens) { if (movieFile.SceneName.IsNullOrWhiteSpace()) { - return GetOriginalFileName(movieFile); + return GetOriginalFileName(movieFile, multipleTokens); } return movieFile.SceneName; } - private string GetOriginalFileName(MovieFile movieFile) + private string GetOriginalFileName(MovieFile movieFile, bool multipleTokens) { + if (multipleTokens) + { + return string.Empty; + } + if (movieFile.RelativePath.IsNullOrWhiteSpace()) { return Path.GetFileNameWithoutExtension(movieFile.Path);