diff options
| author | Bond-009 <bond.009@outlook.com> | 2022-01-02 12:31:20 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-01-02 12:31:20 +0100 |
| commit | 11d0c6827f1e0148e72dadbba0039b2c248bacbe (patch) | |
| tree | 03289bb5a648023ce4553fc77cbc1e60006d7031 /Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs | |
| parent | 1725b2ee69a3eae988239e02381ea51da93364bd (diff) | |
| parent | 28c2ac9cc0c2c7d9ed6e38b8de83755899e210f5 (diff) | |
Merge pull request #7058 from cvium/the_most_important_feature
Diffstat (limited to 'Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs')
| -rw-r--r-- | Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs b/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs new file mode 100644 index 000000000..3d06ceb5e --- /dev/null +++ b/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs @@ -0,0 +1,93 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using Emby.Naming.Common; +using Emby.Naming.Video; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Resolvers; +using MediaBrowser.Model.Entities; +using static Emby.Naming.Video.ExtraRuleResolver; + +namespace Emby.Server.Implementations.Library.Resolvers +{ + /// <summary> + /// Resolves a Path into a Video or Video subclass. + /// </summary> + internal class ExtraResolver + { + private readonly NamingOptions _namingOptions; + private readonly IItemResolver[] _trailerResolvers; + private readonly IItemResolver[] _videoResolvers; + + /// <summary> + /// Initializes an new instance of the <see cref="ExtraResolver"/> class. + /// </summary> + /// <param name="namingOptions">An instance of <see cref="NamingOptions"/>.</param> + public ExtraResolver(NamingOptions namingOptions) + { + _namingOptions = namingOptions; + _trailerResolvers = new IItemResolver[] { new GenericVideoResolver<Trailer>(namingOptions) }; + _videoResolvers = new IItemResolver[] { new GenericVideoResolver<Video>(namingOptions) }; + } + + /// <summary> + /// Gets the resolvers for the extra type. + /// </summary> + /// <param name="extraType">The extra type.</param> + /// <returns>The resolvers for the extra type.</returns> + public IItemResolver[]? GetResolversForExtraType(ExtraType extraType) => extraType switch + { + ExtraType.Trailer => _trailerResolvers, + // For audio we'll have to rely on the AudioResolver, which is a "built-in" + ExtraType.ThemeSong => null, + _ => _videoResolvers + }; + + public bool TryGetExtraTypeForOwner(string path, VideoFileInfo ownerVideoFileInfo, [NotNullWhen(true)] out ExtraType? extraType) + { + var extraResult = GetExtraInfo(path, _namingOptions); + if (extraResult.ExtraType == null) + { + extraType = null; + return false; + } + + var cleanDateTimeResult = CleanDateTimeParser.Clean(Path.GetFileNameWithoutExtension(path), _namingOptions.CleanDateTimeRegexes); + var name = cleanDateTimeResult.Name; + var year = cleanDateTimeResult.Year; + + var parentDir = ownerVideoFileInfo.IsDirectory ? ownerVideoFileInfo.Path : Path.GetDirectoryName(ownerVideoFileInfo.Path.AsSpan()); + + var trimmedFileNameWithoutExtension = TrimFilenameDelimiters(ownerVideoFileInfo.FileNameWithoutExtension, _namingOptions.VideoFlagDelimiters); + var trimmedVideoInfoName = TrimFilenameDelimiters(ownerVideoFileInfo.Name, _namingOptions.VideoFlagDelimiters); + var trimmedExtraFileName = TrimFilenameDelimiters(name, _namingOptions.VideoFlagDelimiters); + + // first check filenames + bool isValid = StartsWith(trimmedExtraFileName, trimmedFileNameWithoutExtension) + || (StartsWith(trimmedExtraFileName, trimmedVideoInfoName) && year == ownerVideoFileInfo.Year); + + if (!isValid) + { + // When the extra rule type is DirectoryName we must go one level higher to get the "real" dir name + var currentParentDir = extraResult.Rule?.RuleType == ExtraRuleType.DirectoryName + ? Path.GetDirectoryName(Path.GetDirectoryName(path.AsSpan())) + : Path.GetDirectoryName(path.AsSpan()); + + isValid = !currentParentDir.IsEmpty && !parentDir.IsEmpty && currentParentDir.Equals(parentDir, StringComparison.OrdinalIgnoreCase); + } + + extraType = extraResult.ExtraType; + return isValid; + } + + private static ReadOnlySpan<char> TrimFilenameDelimiters(ReadOnlySpan<char> name, ReadOnlySpan<char> videoFlagDelimiters) + { + return name.IsEmpty ? name : name.TrimEnd().TrimEnd(videoFlagDelimiters).TrimEnd(); + } + + private static bool StartsWith(ReadOnlySpan<char> fileName, ReadOnlySpan<char> baseName) + { + return !baseName.IsEmpty && fileName.StartsWith(baseName, StringComparison.OrdinalIgnoreCase); + } + } +} |
