2
0
Эх сурвалжийг харах

Enable nullable in Emby.Naming

Stepan 4 жил өмнө
parent
commit
59619b6ea7

+ 18 - 1
Emby.Naming/AudioBook/AudioBookFileInfo.cs

@@ -7,6 +7,23 @@ namespace Emby.Naming.AudioBook
     /// </summary>
     public class AudioBookFileInfo : IComparable<AudioBookFileInfo>
     {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="AudioBookFileInfo"/> class.
+        /// </summary>
+        /// <param name="path">Path to audiobook file.</param>
+        /// <param name="container">File type.</param>
+        /// <param name="partNumber">Number of part this file represents.</param>
+        /// <param name="chapterNumber">Number of chapter this file represents.</param>
+        /// <param name="isDirectory">Indication if we are looking at file or directory.</param>
+        public AudioBookFileInfo(string path, string container, int? partNumber = default, int? chapterNumber = default, bool isDirectory = default)
+        {
+            Path = path;
+            Container = container;
+            PartNumber = partNumber;
+            ChapterNumber = chapterNumber;
+            IsDirectory = isDirectory;
+        }
+
         /// <summary>
         /// Gets or sets the path.
         /// </summary>
@@ -38,7 +55,7 @@ namespace Emby.Naming.AudioBook
         public bool IsDirectory { get; set; }
 
         /// <inheritdoc />
-        public int CompareTo(AudioBookFileInfo other)
+        public int CompareTo(AudioBookFileInfo? other)
         {
             if (ReferenceEquals(this, other))
             {

+ 3 - 1
Emby.Naming/AudioBook/AudioBookInfo.cs

@@ -10,11 +10,13 @@ namespace Emby.Naming.AudioBook
         /// <summary>
         /// Initializes a new instance of the <see cref="AudioBookInfo" /> class.
         /// </summary>
-        public AudioBookInfo()
+        /// <param name="name">Name of audiobook.</param>
+        public AudioBookInfo(string name)
         {
             Files = new List<AudioBookFileInfo>();
             Extras = new List<AudioBookFileInfo>();
             AlternateVersions = new List<AudioBookFileInfo>();
+            Name = name;
         }
 
         /// <summary>

+ 5 - 3
Emby.Naming/AudioBook/AudioBookListResolver.cs

@@ -1,5 +1,6 @@
 #pragma warning disable CS1591
 
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using Emby.Naming.Common;
@@ -23,7 +24,7 @@ namespace Emby.Naming.AudioBook
 
             var audiobookFileInfos = files
                 .Select(i => audioBookResolver.Resolve(i.FullName, i.IsDirectory))
-                .Where(i => i != null)
+                .OfType<AudioBookFileInfo>()
                 .ToList();
 
             // Filter out all extras, otherwise they could cause stacks to not be resolved
@@ -36,9 +37,10 @@ namespace Emby.Naming.AudioBook
 
             foreach (var stack in stackResult)
             {
-                var stackFiles = stack.Files.Select(i => audioBookResolver.Resolve(i, stack.IsDirectoryStack)).ToList();
+                var stackFiles = stack.Files.Select(i => audioBookResolver.Resolve(i, stack.IsDirectoryStack)).OfType<AudioBookFileInfo>().ToList();
                 stackFiles.Sort();
-                var info = new AudioBookInfo { Files = stackFiles, Name = stack.Name };
+                // TODO nullable discover if name can be empty
+                var info = new AudioBookInfo(stack.Name ?? string.Empty) { Files = stackFiles };
 
                 yield return info;
             }

+ 6 - 8
Emby.Naming/AudioBook/AudioBookResolver.cs

@@ -42,14 +42,12 @@ namespace Emby.Naming.AudioBook
 
             var parsingResult = new AudioBookFilePathParser(_options).Parse(path);
 
-            return new AudioBookFileInfo
-            {
-                Path = path,
-                Container = container,
-                ChapterNumber = parsingResult.ChapterNumber,
-                PartNumber = parsingResult.PartNumber,
-                IsDirectory = isDirectory
-            };
+            return new AudioBookFileInfo(
+                path,
+                container,
+                chapterNumber: parsingResult.ChapterNumber,
+                partNumber: parsingResult.PartNumber,
+                isDirectory: isDirectory );
         }
     }
 }

+ 2 - 2
Emby.Naming/Common/EpisodeExpression.cs

@@ -8,11 +8,11 @@ namespace Emby.Naming.Common
     public class EpisodeExpression
     {
         private string _expression;
-        private Regex _regex;
+        private Regex? _regex;
 
         public EpisodeExpression(string expression, bool byDate)
         {
-            Expression = expression;
+            _expression = expression;
             IsByDate = byDate;
             DateTimeFormats = Array.Empty<string>();
             SupportsAbsoluteEpisodeNumbers = true;

+ 225 - 290
Emby.Naming/Common/NamingOptions.cs

@@ -75,56 +75,45 @@ namespace Emby.Naming.Common
 
             StubTypes = new[]
             {
-                new StubTypeRule
-                {
-                    StubType = "dvd",
-                    Token = "dvd"
-                },
-                new StubTypeRule
-                {
-                    StubType = "hddvd",
-                    Token = "hddvd"
-                },
-                new StubTypeRule
-                {
-                    StubType = "bluray",
-                    Token = "bluray"
-                },
-                new StubTypeRule
-                {
-                    StubType = "bluray",
-                    Token = "brrip"
-                },
-                new StubTypeRule
-                {
-                    StubType = "bluray",
-                    Token = "bd25"
-                },
-                new StubTypeRule
-                {
-                    StubType = "bluray",
-                    Token = "bd50"
-                },
-                new StubTypeRule
-                {
-                    StubType = "vhs",
-                    Token = "vhs"
-                },
-                new StubTypeRule
-                {
-                    StubType = "tv",
-                    Token = "HDTV"
-                },
-                new StubTypeRule
-                {
-                    StubType = "tv",
-                    Token = "PDTV"
-                },
-                new StubTypeRule
-                {
-                    StubType = "tv",
-                    Token = "DSR"
-                }
+                new StubTypeRule(
+                    stubType: "dvd",
+                    token: "dvd"),
+
+                new StubTypeRule(
+                    stubType: "hddvd",
+                    token: "hddvd"),
+
+                new StubTypeRule(
+                    stubType: "bluray",
+                    token: "bluray"),
+
+                new StubTypeRule(
+                    stubType: "bluray",
+                    token: "brrip"),
+
+                new StubTypeRule(
+                    stubType: "bluray",
+                    token: "bd25"),
+
+                new StubTypeRule(
+                    stubType: "bluray",
+                    token: "bd50"),
+
+                new StubTypeRule(
+                    stubType: "vhs",
+                    token: "vhs"),
+
+                new StubTypeRule(
+                    stubType: "tv",
+                    token: "HDTV"),
+
+                new StubTypeRule(
+                    stubType: "tv",
+                    token: "PDTV"),
+
+                new StubTypeRule(
+                    stubType: "tv",
+                    token: "DSR")
             };
 
             VideoFileStackingExpressions = new[]
@@ -381,247 +370,193 @@ namespace Emby.Naming.Common
 
             VideoExtraRules = new[]
             {
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Trailer,
-                    RuleType = ExtraRuleType.Filename,
-                    Token = "trailer",
-                    MediaType = MediaType.Video
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Trailer,
-                    RuleType = ExtraRuleType.Suffix,
-                    Token = "-trailer",
-                    MediaType = MediaType.Video
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Trailer,
-                    RuleType = ExtraRuleType.Suffix,
-                    Token = ".trailer",
-                    MediaType = MediaType.Video
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Trailer,
-                    RuleType = ExtraRuleType.Suffix,
-                    Token = "_trailer",
-                    MediaType = MediaType.Video
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Trailer,
-                    RuleType = ExtraRuleType.Suffix,
-                    Token = " trailer",
-                    MediaType = MediaType.Video
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Sample,
-                    RuleType = ExtraRuleType.Filename,
-                    Token = "sample",
-                    MediaType = MediaType.Video
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Sample,
-                    RuleType = ExtraRuleType.Suffix,
-                    Token = "-sample",
-                    MediaType = MediaType.Video
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Sample,
-                    RuleType = ExtraRuleType.Suffix,
-                    Token = ".sample",
-                    MediaType = MediaType.Video
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Sample,
-                    RuleType = ExtraRuleType.Suffix,
-                    Token = "_sample",
-                    MediaType = MediaType.Video
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Sample,
-                    RuleType = ExtraRuleType.Suffix,
-                    Token = " sample",
-                    MediaType = MediaType.Video
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.ThemeSong,
-                    RuleType = ExtraRuleType.Filename,
-                    Token = "theme",
-                    MediaType = MediaType.Audio
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Scene,
-                    RuleType = ExtraRuleType.Suffix,
-                    Token = "-scene",
-                    MediaType = MediaType.Video
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Clip,
-                    RuleType = ExtraRuleType.Suffix,
-                    Token = "-clip",
-                    MediaType = MediaType.Video
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Interview,
-                    RuleType = ExtraRuleType.Suffix,
-                    Token = "-interview",
-                    MediaType = MediaType.Video
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.BehindTheScenes,
-                    RuleType = ExtraRuleType.Suffix,
-                    Token = "-behindthescenes",
-                    MediaType = MediaType.Video
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.DeletedScene,
-                    RuleType = ExtraRuleType.Suffix,
-                    Token = "-deleted",
-                    MediaType = MediaType.Video
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Clip,
-                    RuleType = ExtraRuleType.Suffix,
-                    Token = "-featurette",
-                    MediaType = MediaType.Video
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Clip,
-                    RuleType = ExtraRuleType.Suffix,
-                    Token = "-short",
-                    MediaType = MediaType.Video
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.BehindTheScenes,
-                    RuleType = ExtraRuleType.DirectoryName,
-                    Token = "behind the scenes",
-                    MediaType = MediaType.Video,
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.DeletedScene,
-                    RuleType = ExtraRuleType.DirectoryName,
-                    Token = "deleted scenes",
-                    MediaType = MediaType.Video,
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Interview,
-                    RuleType = ExtraRuleType.DirectoryName,
-                    Token = "interviews",
-                    MediaType = MediaType.Video,
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Scene,
-                    RuleType = ExtraRuleType.DirectoryName,
-                    Token = "scenes",
-                    MediaType = MediaType.Video,
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Sample,
-                    RuleType = ExtraRuleType.DirectoryName,
-                    Token = "samples",
-                    MediaType = MediaType.Video,
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Clip,
-                    RuleType = ExtraRuleType.DirectoryName,
-                    Token = "shorts",
-                    MediaType = MediaType.Video,
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Clip,
-                    RuleType = ExtraRuleType.DirectoryName,
-                    Token = "featurettes",
-                    MediaType = MediaType.Video,
-                },
-                new ExtraRule
-                {
-                    ExtraType = ExtraType.Unknown,
-                    RuleType = ExtraRuleType.DirectoryName,
-                    Token = "extras",
-                    MediaType = MediaType.Video,
-                },
+                new ExtraRule(
+                    ExtraType.Trailer,
+                    ExtraRuleType.Filename,
+                    "trailer",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.Trailer,
+                    ExtraRuleType.Suffix,
+                    "-trailer",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.Trailer,
+                    ExtraRuleType.Suffix,
+                    ".trailer",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.Trailer,
+                    ExtraRuleType.Suffix,
+                    "_trailer",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.Trailer,
+                    ExtraRuleType.Suffix,
+                    " trailer",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.Sample,
+                    ExtraRuleType.Filename,
+                    "sample",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.Sample,
+                    ExtraRuleType.Suffix,
+                    "-sample",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.Sample,
+                    ExtraRuleType.Suffix,
+                    ".sample",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.Sample,
+                    ExtraRuleType.Suffix,
+                    "_sample",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.Sample,
+                    ExtraRuleType.Suffix,
+                    " sample",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.ThemeSong,
+                    ExtraRuleType.Filename,
+                    "theme",
+                    MediaType.Audio),
+
+                new ExtraRule(
+                    ExtraType.Scene,
+                    ExtraRuleType.Suffix,
+                    "-scene",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.Clip,
+                    ExtraRuleType.Suffix,
+                    "-clip",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.Interview,
+                    ExtraRuleType.Suffix,
+                    "-interview",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.BehindTheScenes,
+                    ExtraRuleType.Suffix,
+                    "-behindthescenes",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.DeletedScene,
+                    ExtraRuleType.Suffix,
+                    "-deleted",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.Clip,
+                    ExtraRuleType.Suffix,
+                    "-featurette",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.Clip,
+                    ExtraRuleType.Suffix,
+                    "-short",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.BehindTheScenes,
+                    ExtraRuleType.DirectoryName,
+                    "behind the scenes",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.DeletedScene,
+                    ExtraRuleType.DirectoryName,
+                    "deleted scenes",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.Interview,
+                    ExtraRuleType.DirectoryName,
+                    "interviews",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.Scene,
+                    ExtraRuleType.DirectoryName,
+                    "scenes",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.Sample,
+                    ExtraRuleType.DirectoryName,
+                    "samples",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.Clip,
+                    ExtraRuleType.DirectoryName,
+                    "shorts",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.Clip,
+                    ExtraRuleType.DirectoryName,
+                    "featurettes",
+                    MediaType.Video),
+
+                new ExtraRule(
+                    ExtraType.Unknown,
+                    ExtraRuleType.DirectoryName,
+                    "extras",
+                    MediaType.Video),
             };
 
             Format3DRules = new[]
             {
                 // Kodi rules:
-                new Format3DRule
-                {
-                    PreceedingToken = "3d",
-                    Token = "hsbs"
-                },
-                new Format3DRule
-                {
-                    PreceedingToken = "3d",
-                    Token = "sbs"
-                },
-                new Format3DRule
-                {
-                    PreceedingToken = "3d",
-                    Token = "htab"
-                },
-                new Format3DRule
-                {
-                    PreceedingToken = "3d",
-                    Token = "tab"
-                },
-                                 // Media Browser rules:
-                new Format3DRule
-                {
-                    Token = "fsbs"
-                },
-                new Format3DRule
-                {
-                    Token = "hsbs"
-                },
-                new Format3DRule
-                {
-                    Token = "sbs"
-                },
-                new Format3DRule
-                {
-                    Token = "ftab"
-                },
-                new Format3DRule
-                {
-                    Token = "htab"
-                },
-                new Format3DRule
-                {
-                    Token = "tab"
-                },
-                new Format3DRule
-                {
-                    Token = "sbs3d"
-                },
-                new Format3DRule
-                {
-                    Token = "mvc"
-                }
+                new Format3DRule(
+                    preceedingToken: "3d",
+                    token: "hsbs"),
+
+                new Format3DRule(
+                    preceedingToken: "3d",
+                    token: "sbs"),
+
+                new Format3DRule(
+                    preceedingToken: "3d",
+                    token: "htab"),
+
+                new Format3DRule(
+                    preceedingToken: "3d",
+                    token: "tab"),
+
+                 // Media Browser rules:
+                new Format3DRule("fsbs"),
+                new Format3DRule("hsbs"),
+                new Format3DRule("sbs"),
+                new Format3DRule("ftab"),
+                new Format3DRule("htab"),
+                new Format3DRule("tab"),
+                new Format3DRule("sbs3d"),
+                new Format3DRule("mvc")
             };
+
             AudioBookPartsExpressions = new[]
             {
                 // Detect specified chapters, like CH 01
@@ -737,15 +672,15 @@ namespace Emby.Naming.Common
 
         public ExtraRule[] VideoExtraRules { get; set; }
 
-        public Regex[] VideoFileStackingRegexes { get; private set; }
+        public Regex[] VideoFileStackingRegexes { get; private set; } = Array.Empty<Regex>();
 
-        public Regex[] CleanDateTimeRegexes { get; private set; }
+        public Regex[] CleanDateTimeRegexes { get; private set; } = Array.Empty<Regex>();
 
-        public Regex[] CleanStringRegexes { get; private set; }
+        public Regex[] CleanStringRegexes { get; private set; } = Array.Empty<Regex>();
 
-        public Regex[] EpisodeWithoutSeasonRegexes { get; private set; }
+        public Regex[] EpisodeWithoutSeasonRegexes { get; private set; } = Array.Empty<Regex>();
 
-        public Regex[] EpisodeMultiPartRegexes { get; private set; }
+        public Regex[] EpisodeMultiPartRegexes { get; private set; } = Array.Empty<Regex>();
 
         public void Compile()
         {

+ 1 - 0
Emby.Naming/Emby.Naming.csproj

@@ -14,6 +14,7 @@
     <EmbedUntrackedSources>true</EmbedUntrackedSources>
     <IncludeSymbols>true</IncludeSymbols>
     <SymbolPackageFormat>snupkg</SymbolPackageFormat>
+    <Nullable>enable</Nullable>
   </PropertyGroup>
 
   <PropertyGroup Condition=" '$(Stability)'=='Unstable'">

+ 8 - 1
Emby.Naming/Subtitles/SubtitleInfo.cs

@@ -4,6 +4,13 @@ namespace Emby.Naming.Subtitles
 {
     public class SubtitleInfo
     {
+        public SubtitleInfo(string path, bool isDefault, bool isForced)
+        {
+            Path = path;
+            IsDefault = isDefault;
+            IsForced = isForced;
+        }
+
         /// <summary>
         /// Gets or sets the path.
         /// </summary>
@@ -14,7 +21,7 @@ namespace Emby.Naming.Subtitles
         /// Gets or sets the language.
         /// </summary>
         /// <value>The language.</value>
-        public string Language { get; set; }
+        public string? Language { get; set; }
 
         /// <summary>
         /// Gets or sets a value indicating whether this instance is default.

+ 4 - 6
Emby.Naming/Subtitles/SubtitleParser.cs

@@ -31,12 +31,10 @@ namespace Emby.Naming.Subtitles
             }
 
             var flags = GetFlags(path);
-            var info = new SubtitleInfo
-            {
-                Path = path,
-                IsDefault = _options.SubtitleDefaultFlags.Any(i => flags.Contains(i, StringComparer.OrdinalIgnoreCase)),
-                IsForced = _options.SubtitleForcedFlags.Any(i => flags.Contains(i, StringComparer.OrdinalIgnoreCase))
-            };
+            var info = new SubtitleInfo(
+                path,
+                _options.SubtitleDefaultFlags.Any(i => flags.Contains(i, StringComparer.OrdinalIgnoreCase)),
+                _options.SubtitleForcedFlags.Any(i => flags.Contains(i, StringComparer.OrdinalIgnoreCase)));
 
             var parts = flags.Where(i => !_options.SubtitleDefaultFlags.Contains(i, StringComparer.OrdinalIgnoreCase)
                 && !_options.SubtitleForcedFlags.Contains(i, StringComparer.OrdinalIgnoreCase))

+ 9 - 4
Emby.Naming/TV/EpisodeInfo.cs

@@ -4,6 +4,11 @@ namespace Emby.Naming.TV
 {
     public class EpisodeInfo
     {
+        public EpisodeInfo(string path)
+        {
+            Path = path;
+        }
+
         /// <summary>
         /// Gets or sets the path.
         /// </summary>
@@ -14,19 +19,19 @@ namespace Emby.Naming.TV
         /// Gets or sets the container.
         /// </summary>
         /// <value>The container.</value>
-        public string Container { get; set; }
+        public string? Container { get; set; }
 
         /// <summary>
         /// Gets or sets the name of the series.
         /// </summary>
         /// <value>The name of the series.</value>
-        public string SeriesName { get; set; }
+        public string? SeriesName { get; set; }
 
         /// <summary>
         /// Gets or sets the format3 d.
         /// </summary>
         /// <value>The format3 d.</value>
-        public string Format3D { get; set; }
+        public string? Format3D { get; set; }
 
         /// <summary>
         /// Gets or sets a value indicating whether [is3 d].
@@ -44,7 +49,7 @@ namespace Emby.Naming.TV
         /// Gets or sets the type of the stub.
         /// </summary>
         /// <value>The type of the stub.</value>
-        public string StubType { get; set; }
+        public string? StubType { get; set; }
 
         public int? SeasonNumber { get; set; }
 

+ 1 - 1
Emby.Naming/TV/EpisodePathParserResult.cs

@@ -10,7 +10,7 @@ namespace Emby.Naming.TV
 
         public int? EndingEpsiodeNumber { get; set; }
 
-        public string SeriesName { get; set; }
+        public string? SeriesName { get; set; }
 
         public bool Success { get; set; }
 

+ 1 - 2
Emby.Naming/TV/EpisodeResolver.cs

@@ -54,9 +54,8 @@ namespace Emby.Naming.TV
             var parsingResult = new EpisodePathParser(_options)
                 .Parse(path, isDirectory, isNamed, isOptimistic, supportsAbsoluteNumbers, fillExtendedInfo);
 
-            return new EpisodeInfo
+            return new EpisodeInfo(path)
             {
-                Path = path,
                 Container = container,
                 IsStub = isStub,
                 EndingEpsiodeNumber = parsingResult.EndingEpsiodeNumber,

+ 1 - 1
Emby.Naming/Video/ExtraResult.cs

@@ -16,6 +16,6 @@ namespace Emby.Naming.Video
         /// Gets or sets the rule.
         /// </summary>
         /// <value>The rule.</value>
-        public ExtraRule Rule { get; set; }
+        public ExtraRule? Rule { get; set; }
     }
 }

+ 8 - 0
Emby.Naming/Video/ExtraRule.cs

@@ -10,6 +10,14 @@ namespace Emby.Naming.Video
     /// </summary>
     public class ExtraRule
     {
+        public ExtraRule(ExtraType extraType, ExtraRuleType ruleType, string token, MediaType mediaType)
+        {
+            Token = token;
+            ExtraType = extraType;
+            RuleType = ruleType;
+            MediaType = mediaType;
+        }
+
         /// <summary>
         /// Gets or sets the token to use for matching against the file path.
         /// </summary>

+ 1 - 1
Emby.Naming/Video/FileStack.cs

@@ -13,7 +13,7 @@ namespace Emby.Naming.Video
             Files = new List<string>();
         }
 
-        public string Name { get; set; }
+        public string Name { get; set; } = string.Empty;
 
         public List<string> Files { get; set; }
 

+ 1 - 1
Emby.Naming/Video/Format3DParser.cs

@@ -57,7 +57,7 @@ namespace Emby.Naming.Video
             else
             {
                 var foundPrefix = false;
-                string format = null;
+                string? format = null;
 
                 foreach (var flag in videoFlags)
                 {

+ 1 - 1
Emby.Naming/Video/Format3DResult.cs

@@ -21,7 +21,7 @@ namespace Emby.Naming.Video
         /// Gets or sets the format3 d.
         /// </summary>
         /// <value>The format3 d.</value>
-        public string Format3D { get; set; }
+        public string? Format3D { get; set; }
 
         /// <summary>
         /// Gets or sets the tokens.

+ 7 - 1
Emby.Naming/Video/Format3DRule.cs

@@ -4,6 +4,12 @@ namespace Emby.Naming.Video
 {
     public class Format3DRule
     {
+        public Format3DRule(string token, string? preceedingToken = null)
+        {
+            Token = token;
+            PreceedingToken = preceedingToken;
+        }
+
         /// <summary>
         /// Gets or sets the token.
         /// </summary>
@@ -14,6 +20,6 @@ namespace Emby.Naming.Video
         /// Gets or sets the preceeding token.
         /// </summary>
         /// <value>The preceeding token.</value>
-        public string PreceedingToken { get; set; }
+        public string? PreceedingToken { get; set; }
     }
 }

+ 6 - 0
Emby.Naming/Video/StubTypeRule.cs

@@ -4,6 +4,12 @@ namespace Emby.Naming.Video
 {
     public class StubTypeRule
     {
+        public StubTypeRule(string token, string stubType)
+        {
+            Token = token;
+            StubType = stubType;
+        }
+
         /// <summary>
         /// Gets or sets the token.
         /// </summary>

+ 6 - 6
Emby.Naming/Video/VideoFileInfo.cs

@@ -11,19 +11,19 @@ namespace Emby.Naming.Video
         /// Gets or sets the path.
         /// </summary>
         /// <value>The path.</value>
-        public string Path { get; set; }
+        public string? Path { get; set; }
 
         /// <summary>
         /// Gets or sets the container.
         /// </summary>
         /// <value>The container.</value>
-        public string Container { get; set; }
+        public string? Container { get; set; }
 
         /// <summary>
         /// Gets or sets the name.
         /// </summary>
         /// <value>The name.</value>
-        public string Name { get; set; }
+        public string? Name { get; set; }
 
         /// <summary>
         /// Gets or sets the year.
@@ -41,13 +41,13 @@ namespace Emby.Naming.Video
         /// Gets or sets the extra rule.
         /// </summary>
         /// <value>The extra rule.</value>
-        public ExtraRule ExtraRule { get; set; }
+        public ExtraRule? ExtraRule { get; set; }
 
         /// <summary>
         /// Gets or sets the format3 d.
         /// </summary>
         /// <value>The format3 d.</value>
-        public string Format3D { get; set; }
+        public string? Format3D { get; set; }
 
         /// <summary>
         /// Gets or sets a value indicating whether [is3 d].
@@ -65,7 +65,7 @@ namespace Emby.Naming.Video
         /// Gets or sets the type of the stub.
         /// </summary>
         /// <value>The type of the stub.</value>
-        public string StubType { get; set; }
+        public string? StubType { get; set; }
 
         /// <summary>
         /// Gets or sets a value indicating whether this instance is a directory.

+ 2 - 2
Emby.Naming/Video/VideoInfo.cs

@@ -12,7 +12,7 @@ namespace Emby.Naming.Video
         /// Initializes a new instance of the <see cref="VideoInfo" /> class.
         /// </summary>
         /// <param name="name">The name.</param>
-        public VideoInfo(string name)
+        public VideoInfo(string? name)
         {
             Name = name;
 
@@ -25,7 +25,7 @@ namespace Emby.Naming.Video
         /// Gets or sets the name.
         /// </summary>
         /// <value>The name.</value>
-        public string Name { get; set; }
+        public string? Name { get; set; }
 
         /// <summary>
         /// Gets or sets the year.

+ 7 - 4
Emby.Naming/Video/VideoListResolver.cs

@@ -26,7 +26,8 @@ namespace Emby.Naming.Video
 
             var videoInfos = files
                 .Select(i => videoResolver.Resolve(i.FullName, i.IsDirectory))
-                .Where(i => i != null)
+                // .Where(i => i != null)
+                .OfType<VideoFileInfo>()
                 .ToList();
 
             // Filter out all extras, otherwise they could cause stacks to not be resolved
@@ -39,7 +40,7 @@ namespace Emby.Naming.Video
                 .Resolve(nonExtras).ToList();
 
             var remainingFiles = videoInfos
-                .Where(i => !stackResult.Any(s => s.ContainsFile(i.Path, i.IsDirectory)))
+                .Where(i => !stackResult.Any(s => i.Path != null && s.ContainsFile(i.Path, i.IsDirectory)))
                 .ToList();
 
             var list = new List<VideoInfo>();
@@ -48,7 +49,9 @@ namespace Emby.Naming.Video
             {
                 var info = new VideoInfo(stack.Name)
                 {
-                    Files = stack.Files.Select(i => videoResolver.Resolve(i, stack.IsDirectoryStack)).ToList()
+                    Files = stack.Files.Select(i => videoResolver.Resolve(i, stack.IsDirectoryStack))
+                        .OfType<VideoFileInfo>()
+                        .ToList()
                 };
 
                 info.Year = info.Files[0].Year;
@@ -203,7 +206,7 @@ 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? testFilename)
         {
             testFilename = Path.GetFileNameWithoutExtension(testFilename) ?? string.Empty;
 

+ 3 - 3
Emby.Naming/Video/VideoResolver.cs

@@ -22,7 +22,7 @@ namespace Emby.Naming.Video
         /// </summary>
         /// <param name="path">The path.</param>
         /// <returns>VideoFileInfo.</returns>
-        public VideoFileInfo? ResolveDirectory(string path)
+        public VideoFileInfo? ResolveDirectory(string? path)
         {
             return Resolve(path, true);
         }
@@ -32,7 +32,7 @@ namespace Emby.Naming.Video
         /// </summary>
         /// <param name="path">The path.</param>
         /// <returns>VideoFileInfo.</returns>
-        public VideoFileInfo? ResolveFile(string path)
+        public VideoFileInfo? ResolveFile(string? path)
         {
             return Resolve(path, false);
         }
@@ -45,7 +45,7 @@ namespace Emby.Naming.Video
         /// <param name="parseName">Whether or not the name should be parsed for info.</param>
         /// <returns>VideoFileInfo.</returns>
         /// <exception cref="ArgumentNullException"><c>path</c> is <c>null</c>.</exception>
-        public VideoFileInfo? Resolve(string path, bool isDirectory, bool parseName = true)
+        public VideoFileInfo? Resolve(string? path, bool isDirectory, bool parseName = true)
         {
             if (string.IsNullOrEmpty(path))
             {

+ 3 - 2
Emby.Server.Implementations/Library/LibraryManager.cs

@@ -2470,9 +2470,10 @@ namespace Emby.Server.Implementations.Library
 
             var isFolder = episode.VideoType == VideoType.BluRay || episode.VideoType == VideoType.Dvd;
 
+            // TODO nullable - what are we trying to do there with empty episodeInfo?
             var episodeInfo = episode.IsFileProtocol
-                ? resolver.Resolve(episode.Path, isFolder, null, null, isAbsoluteNaming) ?? new Naming.TV.EpisodeInfo()
-                : new Naming.TV.EpisodeInfo();
+                ? resolver.Resolve(episode.Path, isFolder, null, null, isAbsoluteNaming) ?? new Naming.TV.EpisodeInfo(episode.Path)
+                : new Naming.TV.EpisodeInfo(episode.Path);
 
             try
             {

+ 2 - 2
MediaBrowser.Common/MediaBrowser.Common.csproj

@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
 
   <!-- ProjectGuid is only included as a requirement for SonarQube analysis -->
   <PropertyGroup>
@@ -20,7 +20,7 @@
   <ItemGroup>
     <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.9" />
     <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.9" />
-    <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
+    <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
     <PackageReference Include="Microsoft.Net.Http.Headers" Version="2.2.8" />
   </ItemGroup>
 

+ 5 - 5
tests/Jellyfin.Naming.Tests/AudioBook/AudioBookFileInfoTests.cs

@@ -1,4 +1,4 @@
-using Emby.Naming.AudioBook;
+using Emby.Naming.AudioBook;
 using Xunit;
 
 namespace Jellyfin.Naming.Tests.AudioBook
@@ -8,22 +8,22 @@ namespace Jellyfin.Naming.Tests.AudioBook
         [Fact]
         public void CompareTo_Same_Success()
         {
-            var info = new AudioBookFileInfo();
+            var info = new AudioBookFileInfo(string.Empty, string.Empty);
             Assert.Equal(0, info.CompareTo(info));
         }
 
         [Fact]
         public void CompareTo_Null_Success()
         {
-            var info = new AudioBookFileInfo();
+            var info = new AudioBookFileInfo(string.Empty, string.Empty);
             Assert.Equal(1, info.CompareTo(null));
         }
 
         [Fact]
         public void CompareTo_Empty_Success()
         {
-            var info1 = new AudioBookFileInfo();
-            var info2 = new AudioBookFileInfo();
+            var info1 = new AudioBookFileInfo(string.Empty, string.Empty);
+            var info2 = new AudioBookFileInfo(string.Empty, string.Empty);
             Assert.Equal(0, info1.CompareTo(info2));
         }
     }

+ 13 - 19
tests/Jellyfin.Naming.Tests/AudioBook/AudioBookResolverTests.cs

@@ -1,4 +1,4 @@
-using System;
+using System;
 using System.Collections.Generic;
 using Emby.Naming.AudioBook;
 using Emby.Naming.Common;
@@ -14,30 +14,24 @@ namespace Jellyfin.Naming.Tests.AudioBook
         {
             yield return new object[]
             {
-                new AudioBookFileInfo()
-                {
-                    Path = @"/server/AudioBooks/Larry Potter/Larry Potter.mp3",
-                    Container = "mp3",
-                }
+                new AudioBookFileInfo(
+                    @"/server/AudioBooks/Larry Potter/Larry Potter.mp3",
+                    "mp3")
             };
             yield return new object[]
             {
-                new AudioBookFileInfo()
-                {
-                    Path = @"/server/AudioBooks/Berry Potter/Chapter 1 .ogg",
-                    Container = "ogg",
-                    ChapterNumber = 1
-                }
+                new AudioBookFileInfo(
+                    @"/server/AudioBooks/Berry Potter/Chapter 1 .ogg",
+                    "ogg",
+                    chapterNumber: 1)
             };
             yield return new object[]
             {
-                new AudioBookFileInfo()
-                {
-                    Path = @"/server/AudioBooks/Nerry Potter/Part 3 - Chapter 2.mp3",
-                    Container = "mp3",
-                    ChapterNumber = 2,
-                    PartNumber = 3
-                }
+                new AudioBookFileInfo(
+                    @"/server/AudioBooks/Nerry Potter/Part 3 - Chapter 2.mp3",
+                    "mp3",
+                    chapterNumber: 2,
+                    partNumber: 3)
             };
         }