From a6f9ceedd82fe34a8d1f088d91f7c217ee070aad Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Fri, 10 May 2019 20:37:42 +0200 Subject: [PATCH] Fix more warnings --- Emby.Naming/Audio/AlbumParser.cs | 26 ++++--- Emby.Naming/Audio/MultiPartResult.cs | 2 + Emby.Naming/AudioBook/AudioBookFileInfo.cs | 29 ++++++- .../AudioBook/AudioBookFilePathParser.cs | 13 ++-- .../AudioBookFilePathParserResult.cs | 2 + Emby.Naming/AudioBook/AudioBookInfo.cs | 21 ++++-- .../AudioBook/AudioBookListResolver.cs | 2 +- Emby.Naming/AudioBook/AudioBookResolver.cs | 11 +-- Emby.Naming/Common/EpisodeExpression.cs | 17 ++++- Emby.Naming/Common/MediaType.cs | 2 + Emby.Naming/Common/NamingOptions.cs | 75 ++++++++++--------- Emby.Naming/Emby.Naming.csproj | 18 ++++- Emby.Naming/Extensions/StringExtensions.cs | 1 + Emby.Naming/StringExtensions.cs | 30 -------- Emby.Naming/Subtitles/SubtitleInfo.cs | 3 + Emby.Naming/TV/EpisodeInfo.cs | 11 +++ Emby.Naming/TV/EpisodePathParser.cs | 52 ++++++------- Emby.Naming/TV/EpisodePathParserResult.cs | 7 ++ Emby.Naming/TV/EpisodeResolver.cs | 12 ++- Emby.Naming/TV/SeasonPathParser.cs | 42 +++++------ Emby.Naming/TV/SeasonPathParserResult.cs | 2 + Emby.Naming/Video/CleanDateTimeParser.cs | 20 ++--- Emby.Naming/Video/ExtraResolver.cs | 2 - Emby.Naming/Video/FileStack.cs | 4 +- Emby.Naming/Video/Format3DParser.cs | 10 ++- Emby.Naming/Video/Format3DResult.cs | 12 +-- Emby.Naming/Video/StackResolver.cs | 19 +++-- Emby.Naming/Video/StubResolver.cs | 32 +++++--- Emby.Naming/Video/StubResult.cs | 1 + Emby.Naming/Video/StubTypeRule.cs | 1 + Emby.Naming/Video/VideoFileInfo.cs | 12 ++- Emby.Naming/Video/VideoInfo.cs | 4 + Emby.Naming/Video/VideoListResolver.cs | 40 +++++----- Emby.Naming/Video/VideoResolver.cs | 12 +-- .../Emby.Server.Implementations.csproj | 4 +- .../Library/LibraryManager.cs | 2 +- .../Library/Resolvers/TV/SeasonResolver.cs | 2 +- .../Library/Resolvers/TV/SeriesResolver.cs | 4 +- Jellyfin.Server/Jellyfin.Server.csproj | 6 +- Jellyfin.Server/Program.cs | 6 +- jellyfin.ruleset | 5 ++ 41 files changed, 339 insertions(+), 237 deletions(-) delete mode 100644 Emby.Naming/StringExtensions.cs diff --git a/Emby.Naming/Audio/AlbumParser.cs b/Emby.Naming/Audio/AlbumParser.cs index 7d029a9f49..e8d7655525 100644 --- a/Emby.Naming/Audio/AlbumParser.cs +++ b/Emby.Naming/Audio/AlbumParser.cs @@ -33,27 +33,29 @@ namespace Emby.Naming.Audio // Normalize // Remove whitespace - filename = filename.Replace("-", " "); - filename = filename.Replace(".", " "); - filename = filename.Replace("(", " "); - filename = filename.Replace(")", " "); + filename = filename.Replace('-', ' '); + filename = filename.Replace('.', ' '); + filename = filename.Replace('(', ' '); + filename = filename.Replace(')', ' '); filename = Regex.Replace(filename, @"\s+", " "); filename = filename.TrimStart(); foreach (var prefix in _options.AlbumStackingPrefixes) { - if (filename.IndexOf(prefix, StringComparison.OrdinalIgnoreCase) == 0) + if (filename.IndexOf(prefix, StringComparison.OrdinalIgnoreCase) != 0) { - var tmp = filename.Substring(prefix.Length); + continue; + } + + var tmp = filename.Substring(prefix.Length); - tmp = tmp.Trim().Split(' ').FirstOrDefault() ?? string.Empty; + tmp = tmp.Trim().Split(' ').FirstOrDefault() ?? string.Empty; - if (int.TryParse(tmp, NumberStyles.Integer, CultureInfo.InvariantCulture, out var val)) - { - result.IsMultiPart = true; - break; - } + if (int.TryParse(tmp, NumberStyles.Integer, CultureInfo.InvariantCulture, out _)) + { + result.IsMultiPart = true; + break; } } diff --git a/Emby.Naming/Audio/MultiPartResult.cs b/Emby.Naming/Audio/MultiPartResult.cs index b1fa6e5639..00e4a9eb2e 100644 --- a/Emby.Naming/Audio/MultiPartResult.cs +++ b/Emby.Naming/Audio/MultiPartResult.cs @@ -7,11 +7,13 @@ namespace Emby.Naming.Audio /// /// The name. public string Name { get; set; } + /// /// Gets or sets the part. /// /// The part. public string Part { get; set; } + /// /// Gets or sets a value indicating whether this instance is multi part. /// diff --git a/Emby.Naming/AudioBook/AudioBookFileInfo.cs b/Emby.Naming/AudioBook/AudioBookFileInfo.cs index de66a54022..326ea05ef3 100644 --- a/Emby.Naming/AudioBook/AudioBookFileInfo.cs +++ b/Emby.Naming/AudioBook/AudioBookFileInfo.cs @@ -12,35 +12,56 @@ namespace Emby.Naming.AudioBook /// /// The path. public string Path { get; set; } + /// /// Gets or sets the container. /// /// The container. public string Container { get; set; } + /// /// Gets or sets the part number. /// /// The part number. public int? PartNumber { get; set; } + /// /// Gets or sets the chapter number. /// /// The chapter number. public int? ChapterNumber { get; set; } + /// /// Gets or sets the type. /// /// The type. public bool IsDirectory { get; set; } + /// public int CompareTo(AudioBookFileInfo other) { - if (ReferenceEquals(this, other)) return 0; - if (ReferenceEquals(null, other)) return 1; + if (ReferenceEquals(this, other)) + { + return 0; + } + + if (ReferenceEquals(null, other)) + { + return 1; + } + var chapterNumberComparison = Nullable.Compare(ChapterNumber, other.ChapterNumber); - if (chapterNumberComparison != 0) return chapterNumberComparison; + if (chapterNumberComparison != 0) + { + return chapterNumberComparison; + } + var partNumberComparison = Nullable.Compare(PartNumber, other.PartNumber); - if (partNumberComparison != 0) return partNumberComparison; + if (partNumberComparison != 0) + { + return partNumberComparison; + } + return string.Compare(Path, other.Path, StringComparison.Ordinal); } } diff --git a/Emby.Naming/AudioBook/AudioBookFilePathParser.cs b/Emby.Naming/AudioBook/AudioBookFilePathParser.cs index 5909797947..ea7f06c8cb 100644 --- a/Emby.Naming/AudioBook/AudioBookFilePathParser.cs +++ b/Emby.Naming/AudioBook/AudioBookFilePathParser.cs @@ -1,3 +1,4 @@ +using System; using System.Globalization; using System.IO; using System.Text.RegularExpressions; @@ -14,14 +15,13 @@ namespace Emby.Naming.AudioBook _options = options; } - public AudioBookFilePathParserResult Parse(string path, bool IsDirectory) + public AudioBookFilePathParserResult Parse(string path) { - var result = Parse(path); - return !result.Success ? new AudioBookFilePathParserResult() : result; - } + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } - private AudioBookFilePathParserResult Parse(string path) - { var result = new AudioBookFilePathParserResult(); var fileName = Path.GetFileNameWithoutExtension(path); foreach (var expression in _options.AudioBookPartsExpressions) @@ -40,6 +40,7 @@ namespace Emby.Naming.AudioBook } } } + if (!result.PartNumber.HasValue) { var value = match.Groups["part"]; diff --git a/Emby.Naming/AudioBook/AudioBookFilePathParserResult.cs b/Emby.Naming/AudioBook/AudioBookFilePathParserResult.cs index 3a8e3c31f2..f845e82435 100644 --- a/Emby.Naming/AudioBook/AudioBookFilePathParserResult.cs +++ b/Emby.Naming/AudioBook/AudioBookFilePathParserResult.cs @@ -3,7 +3,9 @@ namespace Emby.Naming.AudioBook public class AudioBookFilePathParserResult { public int? PartNumber { get; set; } + public int? ChapterNumber { get; set; } + public bool Success { get; set; } } } diff --git a/Emby.Naming/AudioBook/AudioBookInfo.cs b/Emby.Naming/AudioBook/AudioBookInfo.cs index f6e1d5be43..600d3f05da 100644 --- a/Emby.Naming/AudioBook/AudioBookInfo.cs +++ b/Emby.Naming/AudioBook/AudioBookInfo.cs @@ -7,33 +7,40 @@ namespace Emby.Naming.AudioBook /// public class AudioBookInfo { + public AudioBookInfo() + { + Files = new List(); + Extras = new List(); + AlternateVersions = new List(); + } + /// /// Gets or sets the name. /// /// The name. public string Name { get; set; } + + /// + /// Gets or sets the year. + /// public int? Year { get; set; } + /// /// Gets or sets the files. /// /// The files. public List Files { get; set; } + /// /// Gets or sets the extras. /// /// The extras. public List Extras { get; set; } + /// /// Gets or sets the alternate versions. /// /// The alternate versions. public List AlternateVersions { get; set; } - - public AudioBookInfo() - { - Files = new List(); - Extras = new List(); - AlternateVersions = new List(); - } } } diff --git a/Emby.Naming/AudioBook/AudioBookListResolver.cs b/Emby.Naming/AudioBook/AudioBookListResolver.cs index 4e3ad7cac8..414ef11830 100644 --- a/Emby.Naming/AudioBook/AudioBookListResolver.cs +++ b/Emby.Naming/AudioBook/AudioBookListResolver.cs @@ -15,7 +15,7 @@ namespace Emby.Naming.AudioBook _options = options; } - public IEnumerable Resolve(List files) + public IEnumerable Resolve(IEnumerable files) { var audioBookResolver = new AudioBookResolver(_options); diff --git a/Emby.Naming/AudioBook/AudioBookResolver.cs b/Emby.Naming/AudioBook/AudioBookResolver.cs index 67ab62e801..4a2b516d0e 100644 --- a/Emby.Naming/AudioBook/AudioBookResolver.cs +++ b/Emby.Naming/AudioBook/AudioBookResolver.cs @@ -24,19 +24,21 @@ namespace Emby.Naming.AudioBook return Resolve(path, true); } - public AudioBookFileInfo Resolve(string path, bool IsDirectory = false) + public AudioBookFileInfo Resolve(string path, bool isDirectory = false) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException(nameof(path)); } - if (IsDirectory) // TODO + // TODO + if (isDirectory) { return null; } var extension = Path.GetExtension(path); + // Check supported extensions if (!_options.AudioFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)) { @@ -45,8 +47,7 @@ namespace Emby.Naming.AudioBook var container = extension.TrimStart('.'); - var parsingResult = new AudioBookFilePathParser(_options) - .Parse(path, IsDirectory); + var parsingResult = new AudioBookFilePathParser(_options).Parse(path); return new AudioBookFileInfo { @@ -54,7 +55,7 @@ namespace Emby.Naming.AudioBook Container = container, PartNumber = parsingResult.PartNumber, ChapterNumber = parsingResult.ChapterNumber, - IsDirectory = IsDirectory + IsDirectory = isDirectory }; } } diff --git a/Emby.Naming/Common/EpisodeExpression.cs b/Emby.Naming/Common/EpisodeExpression.cs index fd85bf76ad..136d8189dd 100644 --- a/Emby.Naming/Common/EpisodeExpression.cs +++ b/Emby.Naming/Common/EpisodeExpression.cs @@ -6,17 +6,28 @@ namespace Emby.Naming.Common public class EpisodeExpression { private string _expression; - public string Expression { get => _expression; - set { _expression = value; _regex = null; } } + private Regex _regex; + + public string Expression + { + get => _expression; + set + { + _expression = value; + _regex = null; + } + } public bool IsByDate { get; set; } + public bool IsOptimistic { get; set; } + public bool IsNamed { get; set; } + public bool SupportsAbsoluteEpisodeNumbers { get; set; } public string[] DateTimeFormats { get; set; } - private Regex _regex; public Regex Regex => _regex ?? (_regex = new Regex(Expression, RegexOptions.IgnoreCase | RegexOptions.Compiled)); public EpisodeExpression(string expression, bool byDate) diff --git a/Emby.Naming/Common/MediaType.cs b/Emby.Naming/Common/MediaType.cs index 49cc9ee39b..a7b08bf793 100644 --- a/Emby.Naming/Common/MediaType.cs +++ b/Emby.Naming/Common/MediaType.cs @@ -6,10 +6,12 @@ namespace Emby.Naming.Common /// The audio /// Audio = 0, + /// /// The photo /// Photo = 1, + /// /// The video /// diff --git a/Emby.Naming/Common/NamingOptions.cs b/Emby.Naming/Common/NamingOptions.cs index 2ef0208baf..88a9b46e63 100644 --- a/Emby.Naming/Common/NamingOptions.cs +++ b/Emby.Naming/Common/NamingOptions.cs @@ -8,19 +8,25 @@ namespace Emby.Naming.Common public class NamingOptions { public string[] AudioFileExtensions { get; set; } + public string[] AlbumStackingPrefixes { get; set; } public string[] SubtitleFileExtensions { get; set; } + public char[] SubtitleFlagDelimiters { get; set; } public string[] SubtitleForcedFlags { get; set; } + public string[] SubtitleDefaultFlags { get; set; } public EpisodeExpression[] EpisodeExpressions { get; set; } + public string[] EpisodeWithoutSeasonExpressions { get; set; } + public string[] EpisodeMultiPartExpressions { get; set; } public string[] VideoFileExtensions { get; set; } + public string[] StubFileExtensions { get; set; } public string[] AudioBookPartsExpressions { get; set; } @@ -28,12 +34,14 @@ namespace Emby.Naming.Common public StubTypeRule[] StubTypes { get; set; } public char[] VideoFlagDelimiters { get; set; } + public Format3DRule[] Format3DRules { get; set; } public string[] VideoFileStackingExpressions { get; set; } + public string[] CleanDateTimes { get; set; } - public string[] CleanStrings { get; set; } + public string[] CleanStrings { get; set; } public EpisodeExpression[] MultipleEpisodeExpressions { get; set; } @@ -41,7 +49,7 @@ namespace Emby.Naming.Common public NamingOptions() { - VideoFileExtensions = new string[] + VideoFileExtensions = new[] { ".m4v", ".3gp", @@ -106,53 +114,53 @@ namespace Emby.Naming.Common { new StubTypeRule { - StubType = "dvd", - Token = "dvd" + StubType = "dvd", + Token = "dvd" }, new StubTypeRule { - StubType = "hddvd", - Token = "hddvd" + StubType = "hddvd", + Token = "hddvd" }, new StubTypeRule { - StubType = "bluray", - Token = "bluray" + StubType = "bluray", + Token = "bluray" }, new StubTypeRule { - StubType = "bluray", - Token = "brrip" + StubType = "bluray", + Token = "brrip" }, new StubTypeRule { - StubType = "bluray", - Token = "bd25" + StubType = "bluray", + Token = "bd25" }, new StubTypeRule { - StubType = "bluray", - Token = "bd50" + StubType = "bluray", + Token = "bd50" }, new StubTypeRule { - StubType = "vhs", - Token = "vhs" + StubType = "vhs", + Token = "vhs" }, new StubTypeRule { - StubType = "tv", - Token = "HDTV" + StubType = "tv", + Token = "HDTV" }, new StubTypeRule { - StubType = "tv", - Token = "PDTV" + StubType = "tv", + Token = "PDTV" }, new StubTypeRule { - StubType = "tv", - Token = "DSR" + StubType = "tv", + Token = "DSR" } }; @@ -286,7 +294,7 @@ namespace Emby.Naming.Common new EpisodeExpression(@"[\._ -]()[Ee][Pp]_?([0-9]+)([^\\/]*)$"), new EpisodeExpression("([0-9]{4})[\\.-]([0-9]{2})[\\.-]([0-9]{2})", true) { - DateTimeFormats = new [] + DateTimeFormats = new[] { "yyyy.MM.dd", "yyyy-MM-dd", @@ -295,7 +303,7 @@ namespace Emby.Naming.Common }, new EpisodeExpression("([0-9]{2})[\\.-]([0-9]{2})[\\.-]([0-9]{4})", true) { - DateTimeFormats = new [] + DateTimeFormats = new[] { "dd.MM.yyyy", "dd-MM-yyyy", @@ -348,9 +356,7 @@ namespace Emby.Naming.Common }, // "1-12 episode title" - new EpisodeExpression(@"([0-9]+)-([0-9]+)") - { - }, + new EpisodeExpression(@"([0-9]+)-([0-9]+)"), // "01 - blah.avi", "01-blah.avi" new EpisodeExpression(@".*(\\|\/)(?\d{1,3})(-(?\d{2,3}))*\s?-\s?[^\\\/]*$") @@ -427,7 +433,7 @@ namespace Emby.Naming.Common Token = "_trailer", MediaType = MediaType.Video }, - new ExtraRule + new ExtraRule { ExtraType = "trailer", RuleType = ExtraRuleType.Suffix, @@ -462,7 +468,7 @@ namespace Emby.Naming.Common Token = "_sample", MediaType = MediaType.Video }, - new ExtraRule + new ExtraRule { ExtraType = "sample", RuleType = ExtraRuleType.Suffix, @@ -476,7 +482,6 @@ namespace Emby.Naming.Common Token = "theme", MediaType = MediaType.Audio }, - new ExtraRule { ExtraType = "scene", @@ -526,8 +531,8 @@ namespace Emby.Naming.Common Token = "-short", MediaType = MediaType.Video } - }; + Format3DRules = new[] { // Kodi rules: @@ -648,12 +653,10 @@ namespace Emby.Naming.Common @".*(\\|\/)(?((?![sS]?\d{1,4}[xX]\d{1,3})[^\\\/])*)?([sS]?(?\d{1,4})[xX](?\d{1,3}))(-[xX]?[eE]?(?\d{1,3}))+[^\\\/]*$", @".*(\\|\/)(?[^\\\/]*)[sS](?\d{1,4})[xX\.]?[eE](?\d{1,3})((-| - )?[xXeE](?\d{1,3}))+[^\\\/]*$", @".*(\\|\/)(?[^\\\/]*)[sS](?\d{1,4})[xX\.]?[eE](?\d{1,3})(-[xX]?[eE]?(?\d{1,3}))+[^\\\/]*$" - }.Select(i => new EpisodeExpression(i) - { - IsNamed = true - - }).ToArray(); + { + IsNamed = true + }).ToArray(); VideoFileExtensions = extensions .Distinct(StringComparer.OrdinalIgnoreCase) diff --git a/Emby.Naming/Emby.Naming.csproj b/Emby.Naming/Emby.Naming.csproj index c448ec0ce6..699d893256 100644 --- a/Emby.Naming/Emby.Naming.csproj +++ b/Emby.Naming/Emby.Naming.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 @@ -18,6 +18,22 @@ Jellyfin.Naming https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt https://github.com/jellyfin/jellyfin + true + + + + true + + + + + + + + + + + ../jellyfin.ruleset diff --git a/Emby.Naming/Extensions/StringExtensions.cs b/Emby.Naming/Extensions/StringExtensions.cs index 26c09aeb40..5512127a80 100644 --- a/Emby.Naming/Extensions/StringExtensions.cs +++ b/Emby.Naming/Extensions/StringExtensions.cs @@ -5,6 +5,7 @@ namespace Emby.Naming.Extensions { public static class StringExtensions { + // TODO: @bond remove this when moving to netstandard2.1 public static string Replace(this string str, string oldValue, string newValue, StringComparison comparison) { var sb = new StringBuilder(); diff --git a/Emby.Naming/StringExtensions.cs b/Emby.Naming/StringExtensions.cs deleted file mode 100644 index 7c61922af3..0000000000 --- a/Emby.Naming/StringExtensions.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Text; - -namespace Emby.Naming -{ - internal static class StringExtensions - { - public static string Replace(this string str, string oldValue, string newValue, StringComparison comparison) - { - var sb = new StringBuilder(); - - var previousIndex = 0; - var index = str.IndexOf(oldValue, comparison); - - while (index != -1) - { - sb.Append(str.Substring(previousIndex, index - previousIndex)); - sb.Append(newValue); - index += oldValue.Length; - - previousIndex = index; - index = str.IndexOf(oldValue, index, comparison); - } - - sb.Append(str.Substring(previousIndex)); - - return sb.ToString(); - } - } -} diff --git a/Emby.Naming/Subtitles/SubtitleInfo.cs b/Emby.Naming/Subtitles/SubtitleInfo.cs index e4709dfbb6..96fce04d76 100644 --- a/Emby.Naming/Subtitles/SubtitleInfo.cs +++ b/Emby.Naming/Subtitles/SubtitleInfo.cs @@ -7,16 +7,19 @@ namespace Emby.Naming.Subtitles /// /// The path. public string Path { get; set; } + /// /// Gets or sets the language. /// /// The language. public string Language { get; set; } + /// /// Gets or sets a value indicating whether this instance is default. /// /// true if this instance is default; otherwise, false. public bool IsDefault { get; set; } + /// /// Gets or sets a value indicating whether this instance is forced. /// diff --git a/Emby.Naming/TV/EpisodeInfo.cs b/Emby.Naming/TV/EpisodeInfo.cs index c8aca7a6f3..de79b8bbaf 100644 --- a/Emby.Naming/TV/EpisodeInfo.cs +++ b/Emby.Naming/TV/EpisodeInfo.cs @@ -7,31 +7,37 @@ namespace Emby.Naming.TV /// /// The path. public string Path { get; set; } + /// /// Gets or sets the container. /// /// The container. public string Container { get; set; } + /// /// Gets or sets the name of the series. /// /// The name of the series. public string SeriesName { get; set; } + /// /// Gets or sets the format3 d. /// /// The format3 d. public string Format3D { get; set; } + /// /// Gets or sets a value indicating whether [is3 d]. /// /// true if [is3 d]; otherwise, false. public bool Is3D { get; set; } + /// /// Gets or sets a value indicating whether this instance is stub. /// /// true if this instance is stub; otherwise, false. public bool IsStub { get; set; } + /// /// Gets or sets the type of the stub. /// @@ -39,12 +45,17 @@ namespace Emby.Naming.TV public string StubType { get; set; } public int? SeasonNumber { get; set; } + public int? EpisodeNumber { get; set; } + public int? EndingEpsiodeNumber { get; set; } public int? Year { get; set; } + public int? Month { get; set; } + public int? Day { get; set; } + public bool IsByDate { get; set; } } } diff --git a/Emby.Naming/TV/EpisodePathParser.cs b/Emby.Naming/TV/EpisodePathParser.cs index a8f81a3b85..812bc970ed 100644 --- a/Emby.Naming/TV/EpisodePathParser.cs +++ b/Emby.Naming/TV/EpisodePathParser.cs @@ -15,12 +15,12 @@ namespace Emby.Naming.TV _options = options; } - public EpisodePathParserResult Parse(string path, bool IsDirectory, bool? isNamed = null, bool? isOptimistic = null, bool? supportsAbsoluteNumbers = null, bool fillExtendedInfo = true) + public EpisodePathParserResult Parse(string path, bool isDirectory, bool? isNamed = null, bool? isOptimistic = null, bool? supportsAbsoluteNumbers = null, bool fillExtendedInfo = true) { // Added to be able to use regex patterns which require a file extension. // There were no failed tests without this block, but to be safe, we can keep it until // the regex which require file extensions are modified so that they don't need them. - if (IsDirectory) + if (isDirectory) { path += ".mp4"; } @@ -29,28 +29,20 @@ namespace Emby.Naming.TV foreach (var expression in _options.EpisodeExpressions) { - if (supportsAbsoluteNumbers.HasValue) + if (supportsAbsoluteNumbers.HasValue + && expression.SupportsAbsoluteEpisodeNumbers != supportsAbsoluteNumbers.Value) { - if (expression.SupportsAbsoluteEpisodeNumbers != supportsAbsoluteNumbers.Value) - { - continue; - } + continue; } - if (isNamed.HasValue) + if (isNamed.HasValue && expression.IsNamed != isNamed.Value) { - if (expression.IsNamed != isNamed.Value) - { - continue; - } + continue; } - if (isOptimistic.HasValue) + if (isOptimistic.HasValue && expression.IsOptimistic != isOptimistic.Value) { - if (expression.IsOptimistic != isOptimistic.Value) - { - continue; - } + continue; } var currentResult = Parse(path, expression); @@ -97,7 +89,8 @@ namespace Emby.Naming.TV DateTime date; if (expression.DateTimeFormats.Length > 0) { - if (DateTime.TryParseExact(match.Groups[0].Value, + if (DateTime.TryParseExact( + match.Groups[0].Value, expression.DateTimeFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, @@ -109,17 +102,15 @@ namespace Emby.Naming.TV result.Success = true; } } - else + else if (DateTime.TryParse(match.Groups[0].Value, out date)) { - if (DateTime.TryParse(match.Groups[0].Value, out date)) - { - result.Year = date.Year; - result.Month = date.Month; - result.Day = date.Day; - result.Success = true; - } + result.Year = date.Year; + result.Month = date.Month; + result.Day = date.Day; + result.Success = true; } + // TODO: Only consider success if date successfully parsed? result.Success = true; } @@ -142,7 +133,8 @@ namespace Emby.Naming.TV // or a 'p' or 'i' as what you would get with a pixel resolution specification. // It avoids erroneous parsing of something like "series-s09e14-1080p.mkv" as a multi-episode from E14 to E108 int nextIndex = endingNumberGroup.Index + endingNumberGroup.Length; - if (nextIndex >= name.Length || "0123456789iIpP".IndexOf(name[nextIndex]) == -1) + if (nextIndex >= name.Length + || "0123456789iIpP".IndexOf(name[nextIndex]) == -1) { if (int.TryParse(endingNumberGroup.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out num)) { @@ -160,6 +152,7 @@ namespace Emby.Naming.TV { result.SeasonNumber = num; } + if (int.TryParse(match.Groups[2].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out num)) { result.EpisodeNumber = num; @@ -171,8 +164,11 @@ namespace Emby.Naming.TV // Invalidate match when the season is 200 through 1927 or above 2500 // because it is an error unless the TV show is intentionally using false season numbers. // It avoids erroneous parsing of something like "Series Special (1920x1080).mkv" as being season 1920 episode 1080. - if (result.SeasonNumber >= 200 && result.SeasonNumber < 1928 || result.SeasonNumber > 2500) + if ((result.SeasonNumber >= 200 && result.SeasonNumber < 1928) + || result.SeasonNumber > 2500) + { result.Success = false; + } result.IsByDate = expression.IsByDate; } diff --git a/Emby.Naming/TV/EpisodePathParserResult.cs b/Emby.Naming/TV/EpisodePathParserResult.cs index e1a48bfbc9..996edfc506 100644 --- a/Emby.Naming/TV/EpisodePathParserResult.cs +++ b/Emby.Naming/TV/EpisodePathParserResult.cs @@ -3,14 +3,21 @@ namespace Emby.Naming.TV public class EpisodePathParserResult { public int? SeasonNumber { get; set; } + public int? EpisodeNumber { get; set; } + public int? EndingEpsiodeNumber { get; set; } + public string SeriesName { get; set; } + public bool Success { get; set; } public bool IsByDate { get; set; } + public int? Year { get; set; } + public int? Month { get; set; } + public int? Day { get; set; } } } diff --git a/Emby.Naming/TV/EpisodeResolver.cs b/Emby.Naming/TV/EpisodeResolver.cs index fccf9bdecb..2d7bcb6382 100644 --- a/Emby.Naming/TV/EpisodeResolver.cs +++ b/Emby.Naming/TV/EpisodeResolver.cs @@ -15,7 +15,13 @@ namespace Emby.Naming.TV _options = options; } - public EpisodeInfo Resolve(string path, bool IsDirectory, bool? isNamed = null, bool? isOptimistic = null, bool? supportsAbsoluteNumbers = null, bool fillExtendedInfo = true) + public EpisodeInfo Resolve( + string path, + bool isDirectory, + bool? isNamed = null, + bool? isOptimistic = null, + bool? supportsAbsoluteNumbers = null, + bool fillExtendedInfo = true) { if (string.IsNullOrEmpty(path)) { @@ -26,7 +32,7 @@ namespace Emby.Naming.TV string container = null; string stubType = null; - if (!IsDirectory) + if (!isDirectory) { var extension = Path.GetExtension(path); // Check supported extensions @@ -52,7 +58,7 @@ namespace Emby.Naming.TV var format3DResult = new Format3DParser(_options).Parse(flags); var parsingResult = new EpisodePathParser(_options) - .Parse(path, IsDirectory, isNamed, isOptimistic, supportsAbsoluteNumbers, fillExtendedInfo); + .Parse(path, isDirectory, isNamed, isOptimistic, supportsAbsoluteNumbers, fillExtendedInfo); return new EpisodeInfo { diff --git a/Emby.Naming/TV/SeasonPathParser.cs b/Emby.Naming/TV/SeasonPathParser.cs index f1dcc50b89..e81b2bb349 100644 --- a/Emby.Naming/TV/SeasonPathParser.cs +++ b/Emby.Naming/TV/SeasonPathParser.cs @@ -3,30 +3,24 @@ using System.Globalization; using System.IO; using System.Linq; using Emby.Naming.Common; +using Emby.Naming.Extensions; namespace Emby.Naming.TV { public class SeasonPathParser { - private readonly NamingOptions _options; - - public SeasonPathParser(NamingOptions options) - { - _options = options; - } - public SeasonPathParserResult Parse(string path, bool supportSpecialAliases, bool supportNumericSeasonFolders) { var result = new SeasonPathParserResult(); var seasonNumberInfo = GetSeasonNumberFromPath(path, supportSpecialAliases, supportNumericSeasonFolders); - result.SeasonNumber = seasonNumberInfo.Item1; + result.SeasonNumber = seasonNumberInfo.seasonNumber; if (result.SeasonNumber.HasValue) { result.Success = true; - result.IsSeasonFolder = seasonNumberInfo.Item2; + result.IsSeasonFolder = seasonNumberInfo.isSeasonFolder; } return result; @@ -35,7 +29,7 @@ namespace Emby.Naming.TV /// /// A season folder must contain one of these somewhere in the name /// - private static readonly string[] SeasonFolderNames = + private static readonly string[] _seasonFolderNames = { "season", "sæson", @@ -54,19 +48,23 @@ namespace Emby.Naming.TV /// if set to true [support special aliases]. /// if set to true [support numeric season folders]. /// System.Nullable{System.Int32}. - private Tuple GetSeasonNumberFromPath(string path, bool supportSpecialAliases, bool supportNumericSeasonFolders) + private static (int? seasonNumber, bool isSeasonFolder) GetSeasonNumberFromPath( + string path, + bool supportSpecialAliases, + bool supportNumericSeasonFolders) { - var filename = Path.GetFileName(path); + var filename = Path.GetFileName(path) ?? string.Empty; if (supportSpecialAliases) { if (string.Equals(filename, "specials", StringComparison.OrdinalIgnoreCase)) { - return new Tuple(0, true); + return (0, true); } + if (string.Equals(filename, "extras", StringComparison.OrdinalIgnoreCase)) { - return new Tuple(0, true); + return (0, true); } } @@ -74,7 +72,7 @@ namespace Emby.Naming.TV { if (int.TryParse(filename, NumberStyles.Integer, CultureInfo.InvariantCulture, out var val)) { - return new Tuple(val, true); + return (val, true); } } @@ -84,12 +82,12 @@ namespace Emby.Naming.TV if (int.TryParse(testFilename, NumberStyles.Integer, CultureInfo.InvariantCulture, out var val)) { - return new Tuple(val, true); + return (val, true); } } // Look for one of the season folder names - foreach (var name in SeasonFolderNames) + foreach (var name in _seasonFolderNames) { var index = filename.IndexOf(name, StringComparison.OrdinalIgnoreCase); @@ -107,10 +105,10 @@ namespace Emby.Naming.TV var parts = filename.Split(new[] { '.', '_', ' ', '-' }, StringSplitOptions.RemoveEmptyEntries); var resultNumber = parts.Select(GetSeasonNumberFromPart).FirstOrDefault(i => i.HasValue); - return new Tuple(resultNumber, true); + return (resultNumber, true); } - private int? GetSeasonNumberFromPart(string part) + private static int? GetSeasonNumberFromPart(string part) { if (part.Length < 2 || !part.StartsWith("s", StringComparison.OrdinalIgnoreCase)) { @@ -132,7 +130,7 @@ namespace Emby.Naming.TV /// /// The path. /// System.Nullable{System.Int32}. - private Tuple GetSeasonNumberFromPathSubstring(string path) + private static (int? seasonNumber, bool isSeasonFolder) GetSeasonNumberFromPathSubstring(string path) { var numericStart = -1; var length = 0; @@ -174,10 +172,10 @@ namespace Emby.Naming.TV if (numericStart == -1) { - return new Tuple(null, isSeasonFolder); + return (null, isSeasonFolder); } - return new Tuple(int.Parse(path.Substring(numericStart, length), CultureInfo.InvariantCulture), isSeasonFolder); + return (int.Parse(path.Substring(numericStart, length), CultureInfo.InvariantCulture), isSeasonFolder); } } } diff --git a/Emby.Naming/TV/SeasonPathParserResult.cs b/Emby.Naming/TV/SeasonPathParserResult.cs index eab27a4a5f..548dbd5d22 100644 --- a/Emby.Naming/TV/SeasonPathParserResult.cs +++ b/Emby.Naming/TV/SeasonPathParserResult.cs @@ -7,11 +7,13 @@ namespace Emby.Naming.TV /// /// The season number. public int? SeasonNumber { get; set; } + /// /// Gets or sets a value indicating whether this is success. /// /// true if success; otherwise, false. public bool Success { get; set; } + public bool IsSeasonFolder { get; set; } } } diff --git a/Emby.Naming/Video/CleanDateTimeParser.cs b/Emby.Naming/Video/CleanDateTimeParser.cs index 74807ef53f..25fa09c488 100644 --- a/Emby.Naming/Video/CleanDateTimeParser.cs +++ b/Emby.Naming/Video/CleanDateTimeParser.cs @@ -27,8 +27,8 @@ namespace Emby.Naming.Video { var extension = Path.GetExtension(name) ?? string.Empty; // Check supported extensions - if (!_options.VideoFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase) && - !_options.AudioFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)) + if (!_options.VideoFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase) + && !_options.AudioFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)) { // Dummy up a file extension because the expressions will fail without one // This is tricky because we can't just check Path.GetExtension for empty @@ -38,7 +38,6 @@ namespace Emby.Naming.Video } catch (ArgumentException) { - } var result = _options.CleanDateTimeRegexes.Select(i => Clean(name, i)) @@ -69,14 +68,15 @@ namespace Emby.Naming.Video var match = expression.Match(name); - if (match.Success && match.Groups.Count == 4) + if (match.Success + && match.Groups.Count == 4 + && match.Groups[1].Success + && match.Groups[2].Success + && int.TryParse(match.Groups[2].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var year)) { - if (match.Groups[1].Success && match.Groups[2].Success && int.TryParse(match.Groups[2].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var year)) - { - name = match.Groups[1].Value; - result.Year = year; - result.HasChanged = true; - } + name = match.Groups[1].Value; + result.Year = year; + result.HasChanged = true; } result.Name = name; diff --git a/Emby.Naming/Video/ExtraResolver.cs b/Emby.Naming/Video/ExtraResolver.cs index 3459b689ac..9f70494d01 100644 --- a/Emby.Naming/Video/ExtraResolver.cs +++ b/Emby.Naming/Video/ExtraResolver.cs @@ -56,7 +56,6 @@ namespace Emby.Naming.Video result.Rule = rule; } } - else if (rule.RuleType == ExtraRuleType.Suffix) { var filename = Path.GetFileNameWithoutExtension(path); @@ -67,7 +66,6 @@ namespace Emby.Naming.Video result.Rule = rule; } } - else if (rule.RuleType == ExtraRuleType.Regex) { var filename = Path.GetFileName(path); diff --git a/Emby.Naming/Video/FileStack.cs b/Emby.Naming/Video/FileStack.cs index 2df1e9aed1..584bdf2d2f 100644 --- a/Emby.Naming/Video/FileStack.cs +++ b/Emby.Naming/Video/FileStack.cs @@ -15,9 +15,9 @@ namespace Emby.Naming.Video Files = new List(); } - public bool ContainsFile(string file, bool IsDirectory) + public bool ContainsFile(string file, bool isDirectory) { - if (IsDirectoryStack == IsDirectory) + if (IsDirectoryStack == isDirectory) { return Files.Contains(file, StringComparer.OrdinalIgnoreCase); } diff --git a/Emby.Naming/Video/Format3DParser.cs b/Emby.Naming/Video/Format3DParser.cs index e6f830c583..333a48641e 100644 --- a/Emby.Naming/Video/Format3DParser.cs +++ b/Emby.Naming/Video/Format3DParser.cs @@ -15,10 +15,12 @@ namespace Emby.Naming.Video public Format3DResult Parse(string path) { - var delimeters = _options.VideoFlagDelimiters.ToList(); - delimeters.Add(' '); + int oldLen = _options.VideoFlagDelimiters.Length; + var delimeters = new char[oldLen + 1]; + _options.VideoFlagDelimiters.CopyTo(delimeters, 0); + delimeters[oldLen] = ' '; - return Parse(new FlagParser(_options).GetFlags(path, delimeters.ToArray())); + return Parse(new FlagParser(_options).GetFlags(path, delimeters)); } internal Format3DResult Parse(string[] videoFlags) @@ -66,8 +68,10 @@ namespace Emby.Naming.Video format = flag; result.Tokens.Add(rule.Token); } + break; } + foundPrefix = string.Equals(flag, rule.PreceedingToken, StringComparison.OrdinalIgnoreCase); } diff --git a/Emby.Naming/Video/Format3DResult.cs b/Emby.Naming/Video/Format3DResult.cs index e12494079c..40fc31e082 100644 --- a/Emby.Naming/Video/Format3DResult.cs +++ b/Emby.Naming/Video/Format3DResult.cs @@ -4,25 +4,27 @@ namespace Emby.Naming.Video { public class Format3DResult { + public Format3DResult() + { + Tokens = new List(); + } + /// /// Gets or sets a value indicating whether [is3 d]. /// /// true if [is3 d]; otherwise, false. public bool Is3D { get; set; } + /// /// Gets or sets the format3 d. /// /// The format3 d. public string Format3D { get; set; } + /// /// Gets or sets the tokens. /// /// The tokens. public List Tokens { get; set; } - - public Format3DResult() - { - Tokens = new List(); - } } } diff --git a/Emby.Naming/Video/StackResolver.cs b/Emby.Naming/Video/StackResolver.cs index 4893002c1b..b8ba42da4f 100644 --- a/Emby.Naming/Video/StackResolver.cs +++ b/Emby.Naming/Video/StackResolver.cs @@ -40,17 +40,24 @@ namespace Emby.Naming.Video var result = new StackResult(); foreach (var directory in files.GroupBy(file => file.IsDirectory ? file.FullName : Path.GetDirectoryName(file.FullName))) { - var stack = new FileStack(); - stack.Name = Path.GetFileName(directory.Key); - stack.IsDirectoryStack = false; + var stack = new FileStack() + { + Name = Path.GetFileName(directory.Key), + IsDirectoryStack = false + }; foreach (var file in directory) { if (file.IsDirectory) + { continue; + } + stack.Files.Add(file.FullName); } + result.Stacks.Add(stack); } + return result; } @@ -114,16 +121,16 @@ namespace Emby.Naming.Video { if (!string.Equals(volume1, volume2, StringComparison.OrdinalIgnoreCase)) { - if (string.Equals(ignore1, ignore2, StringComparison.OrdinalIgnoreCase) && - string.Equals(extension1, extension2, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(ignore1, ignore2, StringComparison.OrdinalIgnoreCase) + && string.Equals(extension1, extension2, StringComparison.OrdinalIgnoreCase)) { if (stack.Files.Count == 0) { stack.Name = title1 + ignore1; stack.IsDirectoryStack = file1.IsDirectory; - //stack.Name = title1 + ignore1 + extension1; stack.Files.Add(file1.FullName); } + stack.Files.Add(file2.FullName); } else diff --git a/Emby.Naming/Video/StubResolver.cs b/Emby.Naming/Video/StubResolver.cs index f86bcbdf04..b78244cb33 100644 --- a/Emby.Naming/Video/StubResolver.cs +++ b/Emby.Naming/Video/StubResolver.cs @@ -9,24 +9,32 @@ namespace Emby.Naming.Video { public static StubResult ResolveFile(string path, NamingOptions options) { - var result = new StubResult(); - var extension = Path.GetExtension(path) ?? string.Empty; + if (path == null) + { + return default(StubResult); + } + + var extension = Path.GetExtension(path); - if (options.StubFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)) + if (!options.StubFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)) { - result.IsStub = true; + return default(StubResult); + } - path = Path.GetFileNameWithoutExtension(path); + var result = new StubResult() + { + IsStub = true + }; - var token = (Path.GetExtension(path) ?? string.Empty).TrimStart('.'); + path = Path.GetFileNameWithoutExtension(path); + var token = Path.GetExtension(path).TrimStart('.'); - foreach (var rule in options.StubTypes) + foreach (var rule in options.StubTypes) + { + if (string.Equals(rule.Token, token, StringComparison.OrdinalIgnoreCase)) { - if (string.Equals(rule.Token, token, StringComparison.OrdinalIgnoreCase)) - { - result.StubType = rule.StubType; - break; - } + result.StubType = rule.StubType; + break; } } diff --git a/Emby.Naming/Video/StubResult.cs b/Emby.Naming/Video/StubResult.cs index 7f9509ca56..7a62e7b981 100644 --- a/Emby.Naming/Video/StubResult.cs +++ b/Emby.Naming/Video/StubResult.cs @@ -7,6 +7,7 @@ namespace Emby.Naming.Video /// /// true if this instance is stub; otherwise, false. public bool IsStub { get; set; } + /// /// Gets or sets the type of the stub. /// diff --git a/Emby.Naming/Video/StubTypeRule.cs b/Emby.Naming/Video/StubTypeRule.cs index b46050085d..d765321504 100644 --- a/Emby.Naming/Video/StubTypeRule.cs +++ b/Emby.Naming/Video/StubTypeRule.cs @@ -7,6 +7,7 @@ namespace Emby.Naming.Video /// /// The token. public string Token { get; set; } + /// /// Gets or sets the type of the stub. /// diff --git a/Emby.Naming/Video/VideoFileInfo.cs b/Emby.Naming/Video/VideoFileInfo.cs index 6a29ada7ea..78f688ca8a 100644 --- a/Emby.Naming/Video/VideoFileInfo.cs +++ b/Emby.Naming/Video/VideoFileInfo.cs @@ -1,4 +1,3 @@ - namespace Emby.Naming.Video { /// @@ -11,56 +10,67 @@ namespace Emby.Naming.Video /// /// The path. public string Path { get; set; } + /// /// Gets or sets the container. /// /// The container. public string Container { get; set; } + /// /// Gets or sets the name. /// /// The name. public string Name { get; set; } + /// /// Gets or sets the year. /// /// The year. public int? Year { get; set; } + /// /// Gets or sets the type of the extra, e.g. trailer, theme song, behing the scenes, etc. /// /// The type of the extra. public string ExtraType { get; set; } + /// /// Gets or sets the extra rule. /// /// The extra rule. public ExtraRule ExtraRule { get; set; } + /// /// Gets or sets the format3 d. /// /// The format3 d. public string Format3D { get; set; } + /// /// Gets or sets a value indicating whether [is3 d]. /// /// true if [is3 d]; otherwise, false. public bool Is3D { get; set; } + /// /// Gets or sets a value indicating whether this instance is stub. /// /// true if this instance is stub; otherwise, false. public bool IsStub { get; set; } + /// /// Gets or sets the type of the stub. /// /// The type of the stub. public string StubType { get; set; } + /// /// Gets or sets the type. /// /// The type. public bool IsDirectory { get; set; } + /// /// Gets the file name without extension. /// diff --git a/Emby.Naming/Video/VideoInfo.cs b/Emby.Naming/Video/VideoInfo.cs index d96d0e7571..2e456bda2b 100644 --- a/Emby.Naming/Video/VideoInfo.cs +++ b/Emby.Naming/Video/VideoInfo.cs @@ -12,21 +12,25 @@ namespace Emby.Naming.Video /// /// The name. public string Name { get; set; } + /// /// Gets or sets the year. /// /// The year. public int? Year { get; set; } + /// /// Gets or sets the files. /// /// The files. public List Files { get; set; } + /// /// Gets or sets the extras. /// /// The extras. public List Extras { get; set; } + /// /// Gets or sets the alternate versions. /// diff --git a/Emby.Naming/Video/VideoListResolver.cs b/Emby.Naming/Video/VideoListResolver.cs index afedc30ef2..5fa0041e07 100644 --- a/Emby.Naming/Video/VideoListResolver.cs +++ b/Emby.Naming/Video/VideoListResolver.cs @@ -53,7 +53,7 @@ namespace Emby.Naming.Video Name = stack.Name }; - info.Year = info.Files.First().Year; + info.Year = info.Files[0].Year; var extraBaseNames = new List { @@ -87,7 +87,7 @@ namespace Emby.Naming.Video Name = media.Name }; - info.Year = info.Files.First().Year; + info.Year = info.Files[0].Year; var extras = GetExtras(remainingFiles, new List { media.FileNameWithoutExtension }); @@ -115,7 +115,7 @@ namespace Emby.Naming.Video if (!string.IsNullOrEmpty(parentPath)) { - var folderName = Path.GetFileName(Path.GetDirectoryName(videoPath)); + var folderName = Path.GetFileName(parentPath); if (!string.IsNullOrEmpty(folderName)) { var extras = GetExtras(remainingFiles, new List { folderName }); @@ -163,9 +163,7 @@ namespace Emby.Naming.Video Year = i.Year })); - var orderedList = list.OrderBy(i => i.Name); - - return orderedList; + return list.OrderBy(i => i.Name); } private IEnumerable GetVideosGroupedByVersion(List videos) @@ -179,23 +177,21 @@ namespace Emby.Naming.Video var folderName = Path.GetFileName(Path.GetDirectoryName(videos[0].Files[0].Path)); - if (!string.IsNullOrEmpty(folderName) && folderName.Length > 1) + if (!string.IsNullOrEmpty(folderName) + && folderName.Length > 1 + && videos.All(i => i.Files.Count == 1 + && IsEligibleForMultiVersion(folderName, i.Files[0].Path)) + && HaveSameYear(videos)) { - if (videos.All(i => i.Files.Count == 1 && IsEligibleForMultiVersion(folderName, i.Files[0].Path))) - { - if (HaveSameYear(videos)) - { - var ordered = videos.OrderBy(i => i.Name).ToList(); + var ordered = videos.OrderBy(i => i.Name).ToList(); - list.Add(ordered[0]); + list.Add(ordered[0]); - list[0].AlternateVersions = ordered.Skip(1).Select(i => i.Files[0]).ToList(); - list[0].Name = folderName; - list[0].Extras.AddRange(ordered.Skip(1).SelectMany(i => i.Extras)); + list[0].AlternateVersions = ordered.Skip(1).Select(i => i.Files[0]).ToList(); + list[0].Name = folderName; + list[0].Extras.AddRange(ordered.Skip(1).SelectMany(i => i.Extras)); - return list; - } - } + return list; } return videos; @@ -213,9 +209,9 @@ namespace Emby.Naming.Video if (testFilename.StartsWith(folderName, StringComparison.OrdinalIgnoreCase)) { testFilename = testFilename.Substring(folderName.Length).Trim(); - return string.IsNullOrEmpty(testFilename) || - testFilename.StartsWith("-") || - string.IsNullOrWhiteSpace(Regex.Replace(testFilename, @"\[([^]]*)\]", string.Empty)) ; + return string.IsNullOrEmpty(testFilename) + || testFilename[0] == '-' + || string.IsNullOrWhiteSpace(Regex.Replace(testFilename, @"\[([^]]*)\]", string.Empty)); } return false; diff --git a/Emby.Naming/Video/VideoResolver.cs b/Emby.Naming/Video/VideoResolver.cs index a673156517..02a25c4b5b 100644 --- a/Emby.Naming/Video/VideoResolver.cs +++ b/Emby.Naming/Video/VideoResolver.cs @@ -38,10 +38,11 @@ namespace Emby.Naming.Video /// Resolves the specified path. /// /// The path. - /// if set to true [is folder]. + /// if set to true [is folder]. + /// Whether or not the name should be parsed for info /// VideoFileInfo. /// path - public VideoFileInfo Resolve(string path, bool IsDirectory, bool parseName = true) + public VideoFileInfo Resolve(string path, bool isDirectory, bool parseName = true) { if (string.IsNullOrEmpty(path)) { @@ -52,9 +53,10 @@ namespace Emby.Naming.Video string container = null; string stubType = null; - if (!IsDirectory) + if (!isDirectory) { var extension = Path.GetExtension(path); + // Check supported extensions if (!_options.VideoFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)) { @@ -79,7 +81,7 @@ namespace Emby.Naming.Video var extraResult = new ExtraResolver(_options).GetExtraInfo(path); - var name = IsDirectory + var name = isDirectory ? Path.GetFileName(path) : Path.GetFileNameWithoutExtension(path); @@ -108,7 +110,7 @@ namespace Emby.Naming.Video Is3D = format3DResult.Is3D, Format3D = format3DResult.Format3D, ExtraType = extraResult.ExtraType, - IsDirectory = IsDirectory, + IsDirectory = isDirectory, ExtraRule = extraResult.Rule }; } diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 2c79624524..d4e17c42ae 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -52,8 +52,8 @@ - - + + diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 1673e37776..4b5063ada6 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -2368,7 +2368,7 @@ namespace Emby.Server.Implementations.Library public int? GetSeasonNumberFromPath(string path) { - return new SeasonPathParser(GetNamingOptions()).Parse(path, true, true).SeasonNumber; + return new SeasonPathParser().Parse(path, true, true).SeasonNumber; } public bool FillMissingEpisodeNumbersFromPath(Episode episode, bool forceRefresh) diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs index ce1386e91a..3b9e48d978 100644 --- a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs @@ -52,7 +52,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV var path = args.Path; - var seasonParserResult = new SeasonPathParser(namingOptions).Parse(path, true, true); + var seasonParserResult = new SeasonPathParser().Parse(path, true, true); var season = new Season { diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs index 5c95534ec1..1f873d7c6d 100644 --- a/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs @@ -194,9 +194,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV /// true if [is season folder] [the specified path]; otherwise, false. private static bool IsSeasonFolder(string path, bool isTvContentType, ILibraryManager libraryManager) { - var namingOptions = ((LibraryManager)libraryManager).GetNamingOptions(); - - var seasonNumber = new SeasonPathParser(namingOptions).Parse(path, isTvContentType, isTvContentType).SeasonNumber; + var seasonNumber = new SeasonPathParser().Parse(path, isTvContentType, isTvContentType).SeasonNumber; return seasonNumber.HasValue; } diff --git a/Jellyfin.Server/Jellyfin.Server.csproj b/Jellyfin.Server/Jellyfin.Server.csproj index 9346a2d254..81f145abff 100644 --- a/Jellyfin.Server/Jellyfin.Server.csproj +++ b/Jellyfin.Server/Jellyfin.Server.csproj @@ -12,7 +12,7 @@ latest - SA1600;SA1601;CS1591 + SA1600;SA1601;SA1629;CS1591 true @@ -26,8 +26,8 @@ - - + + diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index fab584befc..d8ca121176 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -122,8 +122,12 @@ namespace Jellyfin.Server // The default connection limit is 10 for ASP.NET hosted applications and 2 for all others. ServicePointManager.DefaultConnectionLimit = Math.Max(96, ServicePointManager.DefaultConnectionLimit); +// CA5359: Do Not Disable Certificate Validation +#pragma warning disable CA5359 + // Allow all https requests ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; }); +#pragma warning restore CA5359 var fileSystem = new ManagedFileSystem(_loggerFactory, appPaths); @@ -368,7 +372,7 @@ namespace Jellyfin.Server } catch (Exception ex) { - _logger.LogInformation(ex, "Skia not available. Will fallback to NullIMageEncoder. {0}"); + _logger.LogInformation(ex, "Skia not available. Will fallback to NullIMageEncoder."); } return new NullImageEncoder(); diff --git a/jellyfin.ruleset b/jellyfin.ruleset index 262121a325..0a60c8c7a2 100644 --- a/jellyfin.ruleset +++ b/jellyfin.ruleset @@ -14,12 +14,17 @@ + + + + +