Enable nullable in Emby.Naming

This commit is contained in:
Stepan 2020-11-01 10:47:31 +01:00
parent 4f320308f3
commit 59619b6ea7
27 changed files with 349 additions and 367 deletions

View File

@ -7,6 +7,23 @@ namespace Emby.Naming.AudioBook
/// </summary> /// </summary>
public class AudioBookFileInfo : IComparable<AudioBookFileInfo> 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> /// <summary>
/// Gets or sets the path. /// Gets or sets the path.
/// </summary> /// </summary>
@ -38,7 +55,7 @@ namespace Emby.Naming.AudioBook
public bool IsDirectory { get; set; } public bool IsDirectory { get; set; }
/// <inheritdoc /> /// <inheritdoc />
public int CompareTo(AudioBookFileInfo other) public int CompareTo(AudioBookFileInfo? other)
{ {
if (ReferenceEquals(this, other)) if (ReferenceEquals(this, other))
{ {

View File

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

View File

@ -1,5 +1,6 @@
#pragma warning disable CS1591 #pragma warning disable CS1591
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Emby.Naming.Common; using Emby.Naming.Common;
@ -23,7 +24,7 @@ namespace Emby.Naming.AudioBook
var audiobookFileInfos = files var audiobookFileInfos = files
.Select(i => audioBookResolver.Resolve(i.FullName, i.IsDirectory)) .Select(i => audioBookResolver.Resolve(i.FullName, i.IsDirectory))
.Where(i => i != null) .OfType<AudioBookFileInfo>()
.ToList(); .ToList();
// Filter out all extras, otherwise they could cause stacks to not be resolved // 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) 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(); 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; yield return info;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2470,9 +2470,10 @@ namespace Emby.Server.Implementations.Library
var isFolder = episode.VideoType == VideoType.BluRay || episode.VideoType == VideoType.Dvd; 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 var episodeInfo = episode.IsFileProtocol
? resolver.Resolve(episode.Path, isFolder, null, null, isAbsoluteNaming) ?? new Naming.TV.EpisodeInfo() ? resolver.Resolve(episode.Path, isFolder, null, null, isAbsoluteNaming) ?? new Naming.TV.EpisodeInfo(episode.Path)
: new Naming.TV.EpisodeInfo(); : new Naming.TV.EpisodeInfo(episode.Path);
try try
{ {

View File

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

View File

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

View File

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