aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Emby.Naming/AudioBook/AudioBookFileInfo.cs19
-rw-r--r--Emby.Naming/AudioBook/AudioBookInfo.cs4
-rw-r--r--Emby.Naming/AudioBook/AudioBookListResolver.cs8
-rw-r--r--Emby.Naming/AudioBook/AudioBookResolver.cs14
-rw-r--r--Emby.Naming/Common/EpisodeExpression.cs4
-rw-r--r--Emby.Naming/Common/NamingOptions.cs515
-rw-r--r--Emby.Naming/Emby.Naming.csproj1
-rw-r--r--Emby.Naming/Subtitles/SubtitleInfo.cs9
-rw-r--r--Emby.Naming/Subtitles/SubtitleParser.cs10
-rw-r--r--Emby.Naming/TV/EpisodeInfo.cs13
-rw-r--r--Emby.Naming/TV/EpisodePathParserResult.cs2
-rw-r--r--Emby.Naming/TV/EpisodeResolver.cs3
-rw-r--r--Emby.Naming/Video/ExtraResult.cs2
-rw-r--r--Emby.Naming/Video/ExtraRule.cs8
-rw-r--r--Emby.Naming/Video/FileStack.cs2
-rw-r--r--Emby.Naming/Video/Format3DParser.cs2
-rw-r--r--Emby.Naming/Video/Format3DResult.cs2
-rw-r--r--Emby.Naming/Video/Format3DRule.cs8
-rw-r--r--Emby.Naming/Video/StubTypeRule.cs6
-rw-r--r--Emby.Naming/Video/VideoFileInfo.cs12
-rw-r--r--Emby.Naming/Video/VideoInfo.cs4
-rw-r--r--Emby.Naming/Video/VideoListResolver.cs11
-rw-r--r--Emby.Naming/Video/VideoResolver.cs6
-rw-r--r--Emby.Server.Implementations/Library/LibraryManager.cs5
-rw-r--r--MediaBrowser.Common/MediaBrowser.Common.csproj4
-rw-r--r--tests/Jellyfin.Naming.Tests/AudioBook/AudioBookFileInfoTests.cs10
-rw-r--r--tests/Jellyfin.Naming.Tests/AudioBook/AudioBookResolverTests.cs32
27 files changed, 349 insertions, 367 deletions
diff --git a/Emby.Naming/AudioBook/AudioBookFileInfo.cs b/Emby.Naming/AudioBook/AudioBookFileInfo.cs
index c4863b50a..e5200416e 100644
--- a/Emby.Naming/AudioBook/AudioBookFileInfo.cs
+++ b/Emby.Naming/AudioBook/AudioBookFileInfo.cs
@@ -8,6 +8,23 @@ namespace Emby.Naming.AudioBook
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>
/// <value>The path.</value>
@@ -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))
{
diff --git a/Emby.Naming/AudioBook/AudioBookInfo.cs b/Emby.Naming/AudioBook/AudioBookInfo.cs
index b0b5bd881..fba11ea72 100644
--- a/Emby.Naming/AudioBook/AudioBookInfo.cs
+++ b/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>
diff --git a/Emby.Naming/AudioBook/AudioBookListResolver.cs b/Emby.Naming/AudioBook/AudioBookListResolver.cs
index f4ba11a0d..f350e5a4a 100644
--- a/Emby.Naming/AudioBook/AudioBookListResolver.cs
+++ b/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;
}
diff --git a/Emby.Naming/AudioBook/AudioBookResolver.cs b/Emby.Naming/AudioBook/AudioBookResolver.cs
index 5807d4688..e76cfd744 100644
--- a/Emby.Naming/AudioBook/AudioBookResolver.cs
+++ b/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 );
}
}
}
diff --git a/Emby.Naming/Common/EpisodeExpression.cs b/Emby.Naming/Common/EpisodeExpression.cs
index ed6ba8881..00b27541a 100644
--- a/Emby.Naming/Common/EpisodeExpression.cs
+++ b/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;
diff --git a/Emby.Naming/Common/NamingOptions.cs b/Emby.Naming/Common/NamingOptions.cs
index fd4244f64..78bb6242d 100644
--- a/Emby.Naming/Common/NamingOptions.cs
+++ b/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()
{
diff --git a/Emby.Naming/Emby.Naming.csproj b/Emby.Naming/Emby.Naming.csproj
index 6857f9952..93770b156 100644
--- a/Emby.Naming/Emby.Naming.csproj
+++ b/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'">
diff --git a/Emby.Naming/Subtitles/SubtitleInfo.cs b/Emby.Naming/Subtitles/SubtitleInfo.cs
index f39c496b7..2f16fb2df 100644
--- a/Emby.Naming/Subtitles/SubtitleInfo.cs
+++ b/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.
diff --git a/Emby.Naming/Subtitles/SubtitleParser.cs b/Emby.Naming/Subtitles/SubtitleParser.cs
index 24e59f90a..c8659e1b2 100644
--- a/Emby.Naming/Subtitles/SubtitleParser.cs
+++ b/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))
diff --git a/Emby.Naming/TV/EpisodeInfo.cs b/Emby.Naming/TV/EpisodeInfo.cs
index 250df4e2d..a9ee82da3 100644
--- a/Emby.Naming/TV/EpisodeInfo.cs
+++ b/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; }
diff --git a/Emby.Naming/TV/EpisodePathParserResult.cs b/Emby.Naming/TV/EpisodePathParserResult.cs
index 05f921edc..9c48d07a3 100644
--- a/Emby.Naming/TV/EpisodePathParserResult.cs
+++ b/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; }
diff --git a/Emby.Naming/TV/EpisodeResolver.cs b/Emby.Naming/TV/EpisodeResolver.cs
index 6994f69fc..002de2117 100644
--- a/Emby.Naming/TV/EpisodeResolver.cs
+++ b/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,
diff --git a/Emby.Naming/Video/ExtraResult.cs b/Emby.Naming/Video/ExtraResult.cs
index 15db32e87..6be7e6052 100644
--- a/Emby.Naming/Video/ExtraResult.cs
+++ b/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; }
}
}
diff --git a/Emby.Naming/Video/ExtraRule.cs b/Emby.Naming/Video/ExtraRule.cs
index 7c9702e24..c018894fd 100644
--- a/Emby.Naming/Video/ExtraRule.cs
+++ b/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>
diff --git a/Emby.Naming/Video/FileStack.cs b/Emby.Naming/Video/FileStack.cs
index 3ef190b86..b0a22b18b 100644
--- a/Emby.Naming/Video/FileStack.cs
+++ b/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; }
diff --git a/Emby.Naming/Video/Format3DParser.cs b/Emby.Naming/Video/Format3DParser.cs
index 51c26af86..3a9eaa1a1 100644
--- a/Emby.Naming/Video/Format3DParser.cs
+++ b/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)
{
diff --git a/Emby.Naming/Video/Format3DResult.cs b/Emby.Naming/Video/Format3DResult.cs
index fa0e9d3b8..36dc1c12b 100644
--- a/Emby.Naming/Video/Format3DResult.cs
+++ b/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.
diff --git a/Emby.Naming/Video/Format3DRule.cs b/Emby.Naming/Video/Format3DRule.cs
index 310ec84e8..a35f0d9d9 100644
--- a/Emby.Naming/Video/Format3DRule.cs
+++ b/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; }
}
}
diff --git a/Emby.Naming/Video/StubTypeRule.cs b/Emby.Naming/Video/StubTypeRule.cs
index 8285cb51a..fa42af604 100644
--- a/Emby.Naming/Video/StubTypeRule.cs
+++ b/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>
diff --git a/Emby.Naming/Video/VideoFileInfo.cs b/Emby.Naming/Video/VideoFileInfo.cs
index 11e789b66..12bd8c436 100644
--- a/Emby.Naming/Video/VideoFileInfo.cs
+++ b/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.
diff --git a/Emby.Naming/Video/VideoInfo.cs b/Emby.Naming/Video/VideoInfo.cs
index ea74c40e2..930fdb33f 100644
--- a/Emby.Naming/Video/VideoInfo.cs
+++ b/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.
diff --git a/Emby.Naming/Video/VideoListResolver.cs b/Emby.Naming/Video/VideoListResolver.cs
index 948fe037b..601c6c0b6 100644
--- a/Emby.Naming/Video/VideoListResolver.cs
+++ b/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;
diff --git a/Emby.Naming/Video/VideoResolver.cs b/Emby.Naming/Video/VideoResolver.cs
index b4aee614b..b9ff90179 100644
--- a/Emby.Naming/Video/VideoResolver.cs
+++ b/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))
{
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index 00282b71a..e121e9eaf 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/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
{
diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj
index e716a6610..777136f8b 100644
--- a/MediaBrowser.Common/MediaBrowser.Common.csproj
+++ b/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>
diff --git a/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookFileInfoTests.cs b/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookFileInfoTests.cs
index a214bc57c..cf21f964e 100644
--- a/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookFileInfoTests.cs
+++ b/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));
}
}
diff --git a/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookResolverTests.cs b/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookResolverTests.cs
index 673289436..2708d80bb 100644
--- a/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookResolverTests.cs
+++ b/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)
};
}