diff options
| author | Tommaso Stocchi <tommasostocchi@outlook.com> | 2021-06-03 17:15:32 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-06-03 17:15:32 +0200 |
| commit | 2b232df07ff1e6b82005deb9e2797260fdd48b8b (patch) | |
| tree | bafa3828f2299d8e2ff23faef415871d7818ad3a /Emby.Naming | |
| parent | dc261b815f4ce5fbace33e787902636c43618881 (diff) | |
| parent | b060d9d0f1b3dac523288a3aaf182f7e35cf875c (diff) | |
Merge branch 'master' into bug/authorization-header-issue
Diffstat (limited to 'Emby.Naming')
| -rw-r--r-- | Emby.Naming/Audio/AudioFileParser.cs | 6 | ||||
| -rw-r--r-- | Emby.Naming/AudioBook/AudioBookInfo.cs | 8 | ||||
| -rw-r--r-- | Emby.Naming/AudioBook/AudioBookListResolver.cs | 2 | ||||
| -rw-r--r-- | Emby.Naming/Common/NamingOptions.cs | 15 | ||||
| -rw-r--r-- | Emby.Naming/Emby.Naming.csproj | 8 | ||||
| -rw-r--r-- | Emby.Naming/TV/EpisodeResolver.cs | 5 | ||||
| -rw-r--r-- | Emby.Naming/TV/SeasonPathParser.cs | 2 | ||||
| -rw-r--r-- | Emby.Naming/Video/CleanStringParser.cs | 11 | ||||
| -rw-r--r-- | Emby.Naming/Video/ExtraResolver.cs | 95 | ||||
| -rw-r--r-- | Emby.Naming/Video/VideoListResolver.cs | 24 | ||||
| -rw-r--r-- | Emby.Naming/Video/VideoResolver.cs | 25 |
11 files changed, 108 insertions, 93 deletions
diff --git a/Emby.Naming/Audio/AudioFileParser.cs b/Emby.Naming/Audio/AudioFileParser.cs index 8b47dd12e..af4aa0059 100644 --- a/Emby.Naming/Audio/AudioFileParser.cs +++ b/Emby.Naming/Audio/AudioFileParser.cs @@ -1,7 +1,7 @@ using System; using System.IO; -using System.Linq; using Emby.Naming.Common; +using MediaBrowser.Common.Extensions; namespace Emby.Naming.Audio { @@ -18,8 +18,8 @@ namespace Emby.Naming.Audio /// <returns>True if file at path is audio file.</returns> public static bool IsAudioFile(string path, NamingOptions options) { - var extension = Path.GetExtension(path); - return options.AudioFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase); + var extension = Path.GetExtension(path.AsSpan()); + return options.AudioFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase); } } } diff --git a/Emby.Naming/AudioBook/AudioBookInfo.cs b/Emby.Naming/AudioBook/AudioBookInfo.cs index adf403ab6..15702ff2c 100644 --- a/Emby.Naming/AudioBook/AudioBookInfo.cs +++ b/Emby.Naming/AudioBook/AudioBookInfo.cs @@ -15,13 +15,13 @@ namespace Emby.Naming.AudioBook /// <param name="files">List of files composing the actual audiobook.</param> /// <param name="extras">List of extra files.</param> /// <param name="alternateVersions">Alternative version of files.</param> - public AudioBookInfo(string name, int? year, List<AudioBookFileInfo>? files, List<AudioBookFileInfo>? extras, List<AudioBookFileInfo>? alternateVersions) + public AudioBookInfo(string name, int? year, List<AudioBookFileInfo> files, List<AudioBookFileInfo> extras, List<AudioBookFileInfo> alternateVersions) { Name = name; Year = year; - Files = files ?? new List<AudioBookFileInfo>(); - Extras = extras ?? new List<AudioBookFileInfo>(); - AlternateVersions = alternateVersions ?? new List<AudioBookFileInfo>(); + Files = files; + Extras = extras; + AlternateVersions = alternateVersions; } /// <summary> diff --git a/Emby.Naming/AudioBook/AudioBookListResolver.cs b/Emby.Naming/AudioBook/AudioBookListResolver.cs index e9ea9b7a5..ca5322890 100644 --- a/Emby.Naming/AudioBook/AudioBookListResolver.cs +++ b/Emby.Naming/AudioBook/AudioBookListResolver.cs @@ -73,7 +73,7 @@ namespace Emby.Naming.AudioBook var haveChaptersOrPages = stackFiles.Any(x => x.ChapterNumber != null || x.PartNumber != null); var groupedBy = stackFiles.GroupBy(file => new { file.ChapterNumber, file.PartNumber }); - var nameWithReplacedDots = nameParserResult.Name.Replace(" ", "."); + var nameWithReplacedDots = nameParserResult.Name.Replace(' ', '.'); foreach (var group in groupedBy) { diff --git a/Emby.Naming/Common/NamingOptions.cs b/Emby.Naming/Common/NamingOptions.cs index 035d1b228..22a3e8bb4 100644 --- a/Emby.Naming/Common/NamingOptions.cs +++ b/Emby.Naming/Common/NamingOptions.cs @@ -282,7 +282,13 @@ namespace Emby.Naming.Common SupportsAbsoluteEpisodeNumbers = true }, - // Case Closed (1996-2007)/Case Closed - 317.mkv + // Not a Kodi rule as well, but below rule also causes false positives for triple-digit episode names + // [bar] Foo - 1 [baz] special case of below expression to prevent false positives with digits in the series name + new EpisodeExpression(@".*?(\[.*?\])+.*?(?<seriesname>[\w\s]+?)[\s_]*-[\s_]*(?<epnumber>[0-9]+).*$") + { + IsNamed = true + }, + // /server/anything_102.mp4 // /server/james.corden.2017.04.20.anne.hathaway.720p.hdtv.x264-crooks.mkv // /server/anything_1996.11.14.mp4 @@ -299,11 +305,6 @@ namespace Emby.Naming.Common // *** End Kodi Standard Naming - // [bar] Foo - 1 [baz] - new EpisodeExpression(@".*?(\[.*?\])+.*?(?<seriesname>[\w\s]+?)[-\s_]+(?<epnumber>[0-9]+).*$") - { - IsNamed = true - }, new EpisodeExpression(@".*(\\|\/)[sS]?(?<seasonnumber>[0-9]+)[xX](?<epnumber>[0-9]+)[^\\\/]*$") { IsNamed = true @@ -587,7 +588,7 @@ namespace Emby.Naming.Common AudioBookNamesExpressions = new[] { // Detect year usually in brackets after name Batman (2020) - @"^(?<name>.+?)\s*\(\s*(?<year>\d{4})\s*\)\s*$", + @"^(?<name>.+?)\s*\(\s*(?<year>[0-9]{4})\s*\)\s*$", @"^\s*(?<name>[^ ].*?)\s*$" }; diff --git a/Emby.Naming/Emby.Naming.csproj b/Emby.Naming/Emby.Naming.csproj index 24c15759d..3224ff412 100644 --- a/Emby.Naming/Emby.Naming.csproj +++ b/Emby.Naming/Emby.Naming.csproj @@ -23,17 +23,18 @@ </PropertyGroup> <ItemGroup> - <Compile Include="..\SharedVersion.cs" /> + <Compile Include="../SharedVersion.cs" /> </ItemGroup> <ItemGroup> - <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" /> + <ProjectReference Include="../MediaBrowser.Common/MediaBrowser.Common.csproj" /> + <ProjectReference Include="../MediaBrowser.Model/MediaBrowser.Model.csproj" /> </ItemGroup> <PropertyGroup> <Authors>Jellyfin Contributors</Authors> <PackageId>Jellyfin.Naming</PackageId> - <VersionPrefix>10.7.0</VersionPrefix> + <VersionPrefix>10.8.0</VersionPrefix> <RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl> <PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression> </PropertyGroup> @@ -44,7 +45,6 @@ <!-- Code Analyzers--> <ItemGroup Condition=" '$(Configuration)' == 'Debug' "> - <!-- TODO: <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8" PrivateAssets="All" /> --> <PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" /> <PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" /> <PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" /> diff --git a/Emby.Naming/TV/EpisodeResolver.cs b/Emby.Naming/TV/EpisodeResolver.cs index f7df58786..c63aec64e 100644 --- a/Emby.Naming/TV/EpisodeResolver.cs +++ b/Emby.Naming/TV/EpisodeResolver.cs @@ -68,6 +68,11 @@ namespace Emby.Naming.TV var parsingResult = new EpisodePathParser(_options) .Parse(path, isDirectory, isNamed, isOptimistic, supportsAbsoluteNumbers, fillExtendedInfo); + if (!parsingResult.Success && !isStub) + { + return null; + } + return new EpisodeInfo(path) { Container = container, diff --git a/Emby.Naming/TV/SeasonPathParser.cs b/Emby.Naming/TV/SeasonPathParser.cs index d11c7c99e..6236f86c4 100644 --- a/Emby.Naming/TV/SeasonPathParser.cs +++ b/Emby.Naming/TV/SeasonPathParser.cs @@ -60,7 +60,7 @@ namespace Emby.Naming.TV bool supportSpecialAliases, bool supportNumericSeasonFolders) { - var filename = Path.GetFileName(path) ?? string.Empty; + string filename = Path.GetFileName(path); if (supportSpecialAliases) { diff --git a/Emby.Naming/Video/CleanStringParser.cs b/Emby.Naming/Video/CleanStringParser.cs index 09a0cd189..4eef3ebc5 100644 --- a/Emby.Naming/Video/CleanStringParser.cs +++ b/Emby.Naming/Video/CleanStringParser.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Text.RegularExpressions; namespace Emby.Naming.Video @@ -16,8 +17,14 @@ namespace Emby.Naming.Video /// <param name="expressions">List of regex to parse name and year from.</param> /// <param name="newName">Parsing result string.</param> /// <returns>True if parsing was successful.</returns> - public static bool TryClean(string name, IReadOnlyList<Regex> expressions, out ReadOnlySpan<char> newName) + public static bool TryClean([NotNullWhen(true)] string? name, IReadOnlyList<Regex> expressions, out ReadOnlySpan<char> newName) { + if (string.IsNullOrEmpty(name)) + { + newName = ReadOnlySpan<char>.Empty; + return false; + } + var len = expressions.Count; for (int i = 0; i < len; i++) { @@ -41,7 +48,7 @@ namespace Emby.Naming.Video return true; } - newName = string.Empty; + newName = ReadOnlySpan<char>.Empty; return false; } } diff --git a/Emby.Naming/Video/ExtraResolver.cs b/Emby.Naming/Video/ExtraResolver.cs index 1d3b36a1a..f9d06c09b 100644 --- a/Emby.Naming/Video/ExtraResolver.cs +++ b/Emby.Naming/Video/ExtraResolver.cs @@ -30,69 +30,72 @@ namespace Emby.Naming.Video /// <returns>Returns <see cref="ExtraResult"/> object.</returns> public ExtraResult GetExtraInfo(string path) { - return _options.VideoExtraRules - .Select(i => GetExtraInfo(path, i)) - .FirstOrDefault(i => i.ExtraType != null) ?? new ExtraResult(); - } - - private ExtraResult GetExtraInfo(string path, ExtraRule rule) - { var result = new ExtraResult(); - if (rule.MediaType == MediaType.Audio) + for (var i = 0; i < _options.VideoExtraRules.Length; i++) { - if (!AudioFileParser.IsAudioFile(path, _options)) + var rule = _options.VideoExtraRules[i]; + if (rule.MediaType == MediaType.Audio) { - return result; + if (!AudioFileParser.IsAudioFile(path, _options)) + { + continue; + } } - } - else if (rule.MediaType == MediaType.Video) - { - if (!new VideoResolver(_options).IsVideoFile(path)) + else if (rule.MediaType == MediaType.Video) { - return result; + if (!new VideoResolver(_options).IsVideoFile(path)) + { + continue; + } } - } - - if (rule.RuleType == ExtraRuleType.Filename) - { - var filename = Path.GetFileNameWithoutExtension(path); - if (string.Equals(filename, rule.Token, StringComparison.OrdinalIgnoreCase)) + var pathSpan = path.AsSpan(); + if (rule.RuleType == ExtraRuleType.Filename) { - result.ExtraType = rule.ExtraType; - result.Rule = rule; - } - } - else if (rule.RuleType == ExtraRuleType.Suffix) - { - var filename = Path.GetFileNameWithoutExtension(path); + var filename = Path.GetFileNameWithoutExtension(pathSpan); - if (filename.IndexOf(rule.Token, StringComparison.OrdinalIgnoreCase) > 0) + if (filename.Equals(rule.Token, StringComparison.OrdinalIgnoreCase)) + { + result.ExtraType = rule.ExtraType; + result.Rule = rule; + } + } + else if (rule.RuleType == ExtraRuleType.Suffix) { - result.ExtraType = rule.ExtraType; - result.Rule = rule; + var filename = Path.GetFileNameWithoutExtension(pathSpan); + + if (filename.Contains(rule.Token, StringComparison.OrdinalIgnoreCase)) + { + result.ExtraType = rule.ExtraType; + result.Rule = rule; + } } - } - else if (rule.RuleType == ExtraRuleType.Regex) - { - var filename = Path.GetFileName(path); + else if (rule.RuleType == ExtraRuleType.Regex) + { + var filename = Path.GetFileName(path); - var regex = new Regex(rule.Token, RegexOptions.IgnoreCase); + var regex = new Regex(rule.Token, RegexOptions.IgnoreCase); - if (regex.IsMatch(filename)) + if (regex.IsMatch(filename)) + { + result.ExtraType = rule.ExtraType; + result.Rule = rule; + } + } + else if (rule.RuleType == ExtraRuleType.DirectoryName) { - result.ExtraType = rule.ExtraType; - result.Rule = rule; + var directoryName = Path.GetFileName(Path.GetDirectoryName(pathSpan)); + if (directoryName.Equals(rule.Token, StringComparison.OrdinalIgnoreCase)) + { + result.ExtraType = rule.ExtraType; + result.Rule = rule; + } } - } - else if (rule.RuleType == ExtraRuleType.DirectoryName) - { - var directoryName = Path.GetFileName(Path.GetDirectoryName(path)); - if (string.Equals(directoryName, rule.Token, StringComparison.OrdinalIgnoreCase)) + + if (result.ExtraType != null) { - result.ExtraType = rule.ExtraType; - result.Rule = rule; + return result; } } diff --git a/Emby.Naming/Video/VideoListResolver.cs b/Emby.Naming/Video/VideoListResolver.cs index fd1677473..7b6a1705b 100644 --- a/Emby.Naming/Video/VideoListResolver.cs +++ b/Emby.Naming/Video/VideoListResolver.cs @@ -185,8 +185,8 @@ namespace Emby.Naming.Video if (!string.IsNullOrEmpty(folderName) && folderName.Length > 1 && videos.All(i => i.Files.Count == 1 - && IsEligibleForMultiVersion(folderName, i.Files[0].Path)) - && HaveSameYear(videos)) + && IsEligibleForMultiVersion(folderName, i.Files[0].Path)) + && HaveSameYear(videos)) { var ordered = videos.OrderBy(i => i.Name).ToList(); @@ -216,26 +216,26 @@ namespace Emby.Naming.Video return videos.Select(i => i.Year ?? -1).Distinct().Count() < 2; } - private bool IsEligibleForMultiVersion(string folderName, string? testFilename) + private bool IsEligibleForMultiVersion(string folderName, string testFilePath) { - testFilename = Path.GetFileNameWithoutExtension(testFilename) ?? string.Empty; - + string testFilename = Path.GetFileNameWithoutExtension(testFilePath); if (testFilename.StartsWith(folderName, StringComparison.OrdinalIgnoreCase)) { - if (CleanStringParser.TryClean(testFilename, _options.CleanStringRegexes, out var cleanName)) + // Remove the folder name before cleaning as we don't care about cleaning that part + if (folderName.Length <= testFilename.Length) { - testFilename = cleanName.ToString(); + testFilename = testFilename.Substring(folderName.Length).Trim(); } - if (folderName.Length <= testFilename.Length) + if (CleanStringParser.TryClean(testFilename, _options.CleanStringRegexes, out var cleanName)) { - testFilename = testFilename.Substring(folderName.Length).Trim(); + testFilename = cleanName.Trim().ToString(); } + // The CleanStringParser should have removed common keywords etc. return string.IsNullOrEmpty(testFilename) - || testFilename[0].Equals('-') - || testFilename[0].Equals('_') - || string.IsNullOrWhiteSpace(Regex.Replace(testFilename, @"\[([^]]*)\]", string.Empty)); + || testFilename[0] == '-' + || Regex.IsMatch(testFilename, @"^\[([^]]*)\]"); } return false; diff --git a/Emby.Naming/Video/VideoResolver.cs b/Emby.Naming/Video/VideoResolver.cs index d7165d8d7..27e73208c 100644 --- a/Emby.Naming/Video/VideoResolver.cs +++ b/Emby.Naming/Video/VideoResolver.cs @@ -1,7 +1,8 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.IO; -using System.Linq; using Emby.Naming.Common; +using MediaBrowser.Common.Extensions; namespace Emby.Naming.Video { @@ -58,15 +59,15 @@ namespace Emby.Naming.Video } bool isStub = false; - string? container = null; + ReadOnlySpan<char> container = ReadOnlySpan<char>.Empty; string? stubType = null; if (!isDirectory) { - var extension = Path.GetExtension(path); + var extension = Path.GetExtension(path.AsSpan()); // Check supported extensions - if (!_options.VideoFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)) + if (!_options.VideoFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase)) { // It's not supported. Check stub extensions if (!StubResolver.TryResolveFile(path, _options, out stubType)) @@ -85,9 +86,7 @@ namespace Emby.Naming.Video var extraResult = new ExtraResolver(_options).GetExtraInfo(path); - var name = isDirectory - ? Path.GetFileName(path) - : Path.GetFileNameWithoutExtension(path); + var name = Path.GetFileNameWithoutExtension(path); int? year = null; @@ -106,7 +105,7 @@ namespace Emby.Naming.Video return new VideoFileInfo( path: path, - container: container, + container: container.IsEmpty ? null : container.ToString(), isStub: isStub, name: name, year: year, @@ -125,8 +124,8 @@ namespace Emby.Naming.Video /// <returns>True if is video file.</returns> public bool IsVideoFile(string path) { - var extension = Path.GetExtension(path) ?? string.Empty; - return _options.VideoFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase); + var extension = Path.GetExtension(path.AsSpan()); + return _options.VideoFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase); } /// <summary> @@ -136,8 +135,8 @@ namespace Emby.Naming.Video /// <returns>True if is video file stub.</returns> public bool IsStubFile(string path) { - var extension = Path.GetExtension(path) ?? string.Empty; - return _options.StubFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase); + var extension = Path.GetExtension(path.AsSpan()); + return _options.StubFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase); } /// <summary> @@ -146,7 +145,7 @@ namespace Emby.Naming.Video /// <param name="name">Raw name.</param> /// <param name="newName">Clean name.</param> /// <returns>True if cleaning of name was successful.</returns> - public bool TryCleanString(string name, out ReadOnlySpan<char> newName) + public bool TryCleanString([NotNullWhen(true)] string? name, out ReadOnlySpan<char> newName) { return CleanStringParser.TryClean(name, _options.CleanStringRegexes, out newName); } |
