From e986869e965d5103a60dbdc24aff4f6016d3de6d Mon Sep 17 00:00:00 2001 From: Qstick Date: Tue, 25 Feb 2020 22:10:52 +0000 Subject: [PATCH] New: CustomFormat Naming Token --- .../EditCustomFormatModalContent.js | 15 ++++++++++- .../MediaManagement/Naming/NamingModal.js | 26 +++++++++++++++++++ .../Store/Actions/Settings/customFormats.js | 3 +++ .../MoveMovieFileFixture.cs | 2 +- .../FileNameBuilderTests/CleanTitleFixture.cs | 6 +++++ .../FileNameBuilderFixture.cs | 6 +++++ .../CustomFormats/CustomFormat.cs | 2 ++ .../CustomFormatCalculationService.cs | 20 +++++++++----- .../Migration/169_custom_format_scores.cs | 2 ++ .../Organizer/FileNameBuilder.cs | 20 ++++++++++++-- .../Organizer/FileNameSampleService.cs | 19 +++++++++++++- .../CustomFormats/CustomFormatResource.cs | 5 +++- 12 files changed, 114 insertions(+), 12 deletions(-) diff --git a/frontend/src/Settings/CustomFormats/CustomFormats/EditCustomFormatModalContent.js b/frontend/src/Settings/CustomFormats/CustomFormats/EditCustomFormatModalContent.js index 94518d4db..2a89d1f92 100644 --- a/frontend/src/Settings/CustomFormats/CustomFormats/EditCustomFormatModalContent.js +++ b/frontend/src/Settings/CustomFormats/CustomFormats/EditCustomFormatModalContent.js @@ -80,7 +80,8 @@ class EditCustomFormatModalContent extends Component { const { id, - name + name, + includeCustomFormatWhenRenaming } = item; return ( @@ -120,6 +121,18 @@ class EditCustomFormatModalContent extends Component { onChange={onInputChange} /> + + + Include Custom Format when Renaming + + +
diff --git a/frontend/src/Settings/MediaManagement/Naming/NamingModal.js b/frontend/src/Settings/MediaManagement/Naming/NamingModal.js index 8d976b0fb..f40c3fa50 100644 --- a/frontend/src/Settings/MediaManagement/Naming/NamingModal.js +++ b/frontend/src/Settings/MediaManagement/Naming/NamingModal.js @@ -152,6 +152,10 @@ class NamingModal extends Component { { token: '{Edition Tags}', example: 'IMAX' } ]; + const customFormatTokens = [ + { token: '{Custom Formats}', example: 'Surround Sound x264' } + ]; + const originalTokens = [ { token: '{Original Title}', example: 'Movie.Title.HDTV.x264-EVOLVE' }, { token: '{Original Filename}', example: 'Movie.title.hdtv.x264-EVOLVE' } @@ -348,6 +352,28 @@ class NamingModal extends Component {
+
+
+ { + customFormatTokens.map(({ token, example }) => { + return ( + + ); + } + ) + } +
+
+
{ diff --git a/frontend/src/Store/Actions/Settings/customFormats.js b/frontend/src/Store/Actions/Settings/customFormats.js index 54c2544bd..e8b007c3f 100644 --- a/frontend/src/Store/Actions/Settings/customFormats.js +++ b/frontend/src/Store/Actions/Settings/customFormats.js @@ -51,6 +51,9 @@ export default { isSchemaPopulated: false, isFetching: false, isPopulated: false, + schema: { + includeCustomFormatWhenRenaming: false + }, error: null, isDeleting: false, deleteError: null, diff --git a/src/NzbDrone.Core.Test/MediaFiles/MovieFileMovingServiceTests/MoveMovieFileFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/MovieFileMovingServiceTests/MoveMovieFileFixture.cs index 63b5dc810..0278f41e4 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/MovieFileMovingServiceTests/MoveMovieFileFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/MovieFileMovingServiceTests/MoveMovieFileFixture.cs @@ -39,7 +39,7 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieFileMovingServiceTests .Build(); Mocker.GetMock() - .Setup(s => s.BuildFileName(It.IsAny(), It.IsAny(), null)) + .Setup(s => s.BuildFileName(It.IsAny(), It.IsAny(), null, null)) .Returns("File Name"); Mocker.GetMock() diff --git a/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/CleanTitleFixture.cs b/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/CleanTitleFixture.cs index 626257574..be2153705 100644 --- a/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/CleanTitleFixture.cs +++ b/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/CleanTitleFixture.cs @@ -1,7 +1,9 @@ +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; @@ -36,6 +38,10 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests 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()); } [TestCase("Florence + the Machine", "Florence + the Machine")] diff --git a/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/FileNameBuilderFixture.cs b/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/FileNameBuilderFixture.cs index 344543b67..c7ff556ed 100644 --- a/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/FileNameBuilderFixture.cs +++ b/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/FileNameBuilderFixture.cs @@ -1,9 +1,11 @@ +using System.Collections.Generic; using System.IO; using System.Linq; using FizzWare.NBuilder; using FluentAssertions; using Moq; using NUnit.Framework; +using NzbDrone.Core.CustomFormats; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles.MediaInfo; using NzbDrone.Core.Movies; @@ -40,6 +42,10 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests 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()); } private void GivenProper() diff --git a/src/NzbDrone.Core/CustomFormats/CustomFormat.cs b/src/NzbDrone.Core/CustomFormats/CustomFormat.cs index ceb1ddcba..51e61e287 100644 --- a/src/NzbDrone.Core/CustomFormats/CustomFormat.cs +++ b/src/NzbDrone.Core/CustomFormats/CustomFormat.cs @@ -19,6 +19,8 @@ namespace NzbDrone.Core.CustomFormats public string Name { get; set; } + public bool IncludeCustomFormatWhenRenaming { get; set; } + public List Specifications { get; set; } public override string ToString() diff --git a/src/NzbDrone.Core/CustomFormats/CustomFormatCalculationService.cs b/src/NzbDrone.Core/CustomFormats/CustomFormatCalculationService.cs index 60c3a9518..437e073a1 100644 --- a/src/NzbDrone.Core/CustomFormats/CustomFormatCalculationService.cs +++ b/src/NzbDrone.Core/CustomFormats/CustomFormatCalculationService.cs @@ -33,13 +33,11 @@ namespace NzbDrone.Core.CustomFormats _movieService = movieService; } - public List ParseCustomFormat(ParsedMovieInfo movieInfo) + public static List ParseCustomFormat(ParsedMovieInfo movieInfo, List allCustomFormats) { - var formats = _formatService.All(); - var matches = new List(); - foreach (var customFormat in formats) + foreach (var customFormat in allCustomFormats) { var specificationMatches = customFormat.Specifications .GroupBy(t => t.GetType()) @@ -58,7 +56,7 @@ namespace NzbDrone.Core.CustomFormats return matches; } - public List ParseCustomFormat(MovieFile movieFile) + public static List ParseCustomFormat(MovieFile movieFile, List allCustomFormats) { var info = new ParsedMovieInfo { @@ -78,7 +76,17 @@ namespace NzbDrone.Core.CustomFormats } }; - return ParseCustomFormat(info); + return ParseCustomFormat(info, allCustomFormats); + } + + public List ParseCustomFormat(ParsedMovieInfo movieInfo) + { + return ParseCustomFormat(movieInfo, _formatService.All()); + } + + public List ParseCustomFormat(MovieFile movieFile) + { + return ParseCustomFormat(movieFile, _formatService.All()); } public List ParseCustomFormat(Blacklist blacklist) diff --git a/src/NzbDrone.Core/Datastore/Migration/169_custom_format_scores.cs b/src/NzbDrone.Core/Datastore/Migration/169_custom_format_scores.cs index efe01799e..adcc6e6e4 100644 --- a/src/NzbDrone.Core/Datastore/Migration/169_custom_format_scores.cs +++ b/src/NzbDrone.Core/Datastore/Migration/169_custom_format_scores.cs @@ -20,6 +20,8 @@ namespace NzbDrone.Core.Datastore.Migration Execute.WithConnection(MigrateOrderToScores); Delete.Column("FormatCutoff").FromTable("Profiles"); + + Alter.Table("CustomFormats").AddColumn("IncludeCustomFormatWhenRenaming").AsBoolean().WithDefaultValue(0); } private void MigrateOrderToScores(IDbConnection conn, IDbTransaction tran) diff --git a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs index 83c7fd50b..19d69fc5f 100644 --- a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs +++ b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs @@ -7,6 +7,7 @@ using System.Text.RegularExpressions; using NLog; using NzbDrone.Common.EnsureThat; using NzbDrone.Common.Extensions; +using NzbDrone.Core.CustomFormats; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles.MediaInfo; using NzbDrone.Core.Movies; @@ -16,7 +17,7 @@ namespace NzbDrone.Core.Organizer { public interface IBuildFileNames { - string BuildFileName(Movie movie, MovieFile movieFile, NamingConfig namingConfig = null); + string BuildFileName(Movie movie, MovieFile movieFile, NamingConfig namingConfig = null, List customFormats = null); string BuildFilePath(Movie movie, string fileName, string extension); BasicNamingConfig GetBasicNamingConfig(NamingConfig nameSpec); string GetMovieFolder(Movie movie, NamingConfig namingConfig = null); @@ -29,6 +30,7 @@ namespace NzbDrone.Core.Organizer private readonly INamingConfigService _namingConfigService; private readonly IQualityDefinitionService _qualityDefinitionService; private readonly IUpdateMediaInfo _mediaInfoUpdater; + private readonly ICustomFormatService _formatService; private readonly Logger _logger; private static readonly Regex TitleRegex = new Regex(@"\{(?[- ._\[(]*)(?(?:[a-z0-9]+)(?:(?[- ._]+)(?:[a-z0-9]+))?)(?::(?[a-z0-9]+))?(?[- ._)\]]*)\}", @@ -65,15 +67,17 @@ namespace NzbDrone.Core.Organizer public FileNameBuilder(INamingConfigService namingConfigService, IQualityDefinitionService qualityDefinitionService, IUpdateMediaInfo mediaInfoUpdater, + ICustomFormatService formatService, Logger logger) { _namingConfigService = namingConfigService; _qualityDefinitionService = qualityDefinitionService; _mediaInfoUpdater = mediaInfoUpdater; + _formatService = formatService; _logger = logger; } - public string BuildFileName(Movie movie, MovieFile movieFile, NamingConfig namingConfig = null) + public string BuildFileName(Movie movie, MovieFile movieFile, NamingConfig namingConfig = null, List customFormats = null) { if (namingConfig == null) { @@ -97,6 +101,7 @@ namespace NzbDrone.Core.Organizer AddMediaInfoTokens(tokenHandlers, movieFile); AddMovieFileTokens(tokenHandlers, movieFile); AddTagsTokens(tokenHandlers, movieFile); + AddCustomFormats(tokenHandlers, movie, movieFile, customFormats); var fileName = ReplaceTokens(pattern, tokenHandlers, namingConfig).Trim(); fileName = FileNameCleanupRegex.Replace(fileName, match => match.Captures[0].Value[0].ToString()); @@ -332,6 +337,17 @@ namespace NzbDrone.Core.Organizer m => MediaInfoFormatter.FormatVideoDynamicRange(movieFile.MediaInfo); } + private void AddCustomFormats(Dictionary> tokenHandlers, Movie movie, MovieFile movieFile, List customFormats = null) + { + if (customFormats == null) + { + movieFile.Movie = movie; + customFormats = CustomFormatCalculationService.ParseCustomFormat(movieFile, _formatService.All()); + } + + tokenHandlers["{Custom Formats}"] = m => string.Join(" ", customFormats.Where(x => x.IncludeCustomFormatWhenRenaming)); + } + private string GetLanguagesToken(string mediaInfoLanguages) { List tokens = new List(); diff --git a/src/NzbDrone.Core/Organizer/FileNameSampleService.cs b/src/NzbDrone.Core/Organizer/FileNameSampleService.cs index e2d207ff4..09fb08820 100644 --- a/src/NzbDrone.Core/Organizer/FileNameSampleService.cs +++ b/src/NzbDrone.Core/Organizer/FileNameSampleService.cs @@ -1,3 +1,5 @@ +using System.Collections.Generic; +using NzbDrone.Core.CustomFormats; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles.MediaInfo; using NzbDrone.Core.Movies; @@ -17,6 +19,7 @@ namespace NzbDrone.Core.Organizer private static MovieFile _movieFile; private static Movie _movie; + private static List _customFormats; public FileNameSampleService(IBuildFileNames buildFileNames) { @@ -55,6 +58,20 @@ namespace NzbDrone.Core.Organizer MovieFile = _movieFile, MovieFileId = 1, }; + + _customFormats = new List + { + new CustomFormat + { + Name = "Surround Sound", + IncludeCustomFormatWhenRenaming = true + }, + new CustomFormat + { + Name = "x264", + IncludeCustomFormatWhenRenaming = true + } + }; } public SampleResult GetMovieSample(NamingConfig nameSpec) @@ -76,7 +93,7 @@ namespace NzbDrone.Core.Organizer { try { - return _buildFileNames.BuildFileName(movie, movieFile, nameSpec); + return _buildFileNames.BuildFileName(movie, movieFile, nameSpec, _customFormats); } catch (NamingFormatException) { diff --git a/src/Radarr.Api.V3/CustomFormats/CustomFormatResource.cs b/src/Radarr.Api.V3/CustomFormats/CustomFormatResource.cs index d96237aff..d31e3b063 100644 --- a/src/Radarr.Api.V3/CustomFormats/CustomFormatResource.cs +++ b/src/Radarr.Api.V3/CustomFormats/CustomFormatResource.cs @@ -12,6 +12,7 @@ namespace Radarr.Api.V3.CustomFormats [JsonProperty(DefaultValueHandling = DefaultValueHandling.Include)] public override int Id { get; set; } public string Name { get; set; } + public bool IncludeCustomFormatWhenRenaming { get; set; } public List Specifications { get; set; } } @@ -23,7 +24,8 @@ namespace Radarr.Api.V3.CustomFormats { Id = model.Id, Name = model.Name, - Specifications = model.Specifications.Select(x => x.ToSchema()).ToList(), + IncludeCustomFormatWhenRenaming = model.IncludeCustomFormatWhenRenaming, + Specifications = model.Specifications.Select(x => x.ToSchema()).ToList() }; } @@ -38,6 +40,7 @@ namespace Radarr.Api.V3.CustomFormats { Id = resource.Id, Name = resource.Name, + IncludeCustomFormatWhenRenaming = resource.IncludeCustomFormatWhenRenaming, Specifications = resource.Specifications.Select(x => MapSpecification(x, specifications)).ToList() }; }