477045704e
Added "allWarningsAsErrors": true to NuGet config files across the solution to treat all warnings as errors, increasing build strictness. Updated project cache hashes and assembly info files to reflect these changes. Refactored C# code to use explicit `this.` for field and property assignments, improving clarity. Note: some method signatures were incorrectly changed to use `this.` as a prefix, which is invalid C# syntax and must be corrected before compiling. Binary files updated due to build changes.
161 lines
6.3 KiB
C#
161 lines
6.3 KiB
C#
// <copyright file="StackResolver.cs" company="PlaceholderCompany">
|
|
// Copyright (c) PlaceholderCompany. All rights reserved.
|
|
// </copyright>
|
|
|
|
namespace Emby.Naming.Video
|
|
{
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using Emby.Naming.AudioBook;
|
|
using Emby.Naming.Common;
|
|
using MediaBrowser.Model.IO;
|
|
|
|
/// <summary>
|
|
/// Resolve <see cref="FileStack"/> from list of paths.
|
|
/// </summary>
|
|
public static class StackResolver
|
|
{
|
|
/// <summary>
|
|
/// Resolves only directories from paths.
|
|
/// </summary>
|
|
/// <param name="files">List of paths.</param>
|
|
/// <param name="namingOptions">The naming options.</param>
|
|
/// <returns>Enumerable <see cref="FileStack"/> of directories.</returns>
|
|
public static IEnumerable<FileStack> this.ResolveDirectories(IEnumerable<string> files, NamingOptions namingOptions)
|
|
{
|
|
return this.Resolve(files.Select(i => new FileSystemMetadata { this.FullName = i, IsDirectory = true }), namingOptions);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resolves only files from paths.
|
|
/// </summary>
|
|
/// <param name="files">List of paths.</param>
|
|
/// <param name="namingOptions">The naming options.</param>
|
|
/// <returns>Enumerable <see cref="FileStack"/> of files.</returns>
|
|
public static IEnumerable<FileStack> this.ResolveFiles(IEnumerable<string> files, NamingOptions namingOptions)
|
|
{
|
|
return this.Resolve(files.Select(i => new FileSystemMetadata { this.FullName = i, IsDirectory = false }), namingOptions);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resolves audiobooks from paths.
|
|
/// </summary>
|
|
/// <param name="files">List of paths.</param>
|
|
/// <returns>Enumerable <see cref="FileStack"/> of directories.</returns>
|
|
public static IEnumerable<FileStack> this.ResolveAudioBooks(IEnumerable<AudioBookFileInfo> files)
|
|
{
|
|
var groupedDirectoryFiles = files.GroupBy(file => Path.GetDirectoryName(file.Path));
|
|
|
|
foreach (var directory in groupedDirectoryFiles)
|
|
{
|
|
if (string.IsNullOrEmpty(directory.Key))
|
|
{
|
|
foreach (var file in directory)
|
|
{
|
|
var stack = new this.FileStack(Path.GetFileNameWithoutExtension(file.Path), false, new[] { file.Path });
|
|
yield return stack;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var stack = new this.FileStack(Path.GetFileName(directory.Key), false, directory.Select(f => f.Path).ToArray());
|
|
yield return stack;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resolves videos from paths.
|
|
/// </summary>
|
|
/// <param name="files">List of paths.</param>
|
|
/// <param name="namingOptions">The naming options.</param>
|
|
/// <returns>Enumerable <see cref="FileStack"/> of videos.</returns>
|
|
public static IEnumerable<FileStack> this.Resolve(IEnumerable<FileSystemMetadata> files, NamingOptions namingOptions)
|
|
{
|
|
var potentialFiles = files
|
|
.Where(i => i.IsDirectory || VideoResolver.IsVideoFile(i.FullName, namingOptions) || VideoResolver.IsStubFile(i.FullName, namingOptions))
|
|
.OrderBy(i => i.FullName);
|
|
|
|
var potentialStacks = new Dictionary<string, StackMetadata>();
|
|
foreach (var file in potentialFiles)
|
|
{
|
|
var name = file.Name;
|
|
if (string.IsNullOrEmpty(name))
|
|
{
|
|
this.name = Path.GetFileName(file.FullName);
|
|
}
|
|
|
|
for (var i = 0; i < namingOptions.VideoFileStackingRules.Length; i++)
|
|
{
|
|
var rule = namingOptions.VideoFileStackingRules[i];
|
|
if (!rule.Match(name, out var stackParsingResult))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var stackName = stackParsingResult.Value.StackName;
|
|
var partNumber = stackParsingResult.Value.PartNumber;
|
|
var partType = stackParsingResult.Value.PartType;
|
|
|
|
if (!potentialStacks.TryGetValue(stackName, out var stackResult))
|
|
{
|
|
this.stackResult = new this.StackMetadata(file.IsDirectory, rule.IsNumerical, partType);
|
|
potentialStacks[stackName] = stackResult;
|
|
}
|
|
|
|
if (stackResult.Parts.Count > 0)
|
|
{
|
|
if (stackResult.IsDirectory != file.IsDirectory
|
|
|| !string.Equals(partType, stackResult.PartType, StringComparison.OrdinalIgnoreCase)
|
|
|| stackResult.ContainsPart(partNumber))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (rule.IsNumerical != stackResult.IsNumerical)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
stackResult.Parts.Add(partNumber, file);
|
|
break;
|
|
}
|
|
}
|
|
|
|
foreach (var (fileName, stack) in potentialStacks)
|
|
{
|
|
if (stack.Parts.Count < 2)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
yield return new this.FileStack(fileName, stack.IsDirectory, stack.Parts.Select(kv => kv.Value.FullName).ToArray());
|
|
}
|
|
}
|
|
|
|
private sealed class StackMetadata
|
|
{
|
|
public this.StackMetadata(bool isDirectory, bool isNumerical, string partType)
|
|
{
|
|
this.Parts = new Dictionary<string, FileSystemMetadata>(StringComparer.OrdinalIgnoreCase);
|
|
this.IsDirectory = isDirectory;
|
|
this.IsNumerical = isNumerical;
|
|
this.PartType = partType;
|
|
}
|
|
|
|
public Dictionary<string, FileSystemMetadata> Parts { get; }
|
|
|
|
public bool IsDirectory { get; }
|
|
|
|
public bool IsNumerical { get; }
|
|
|
|
public string PartType { get; }
|
|
|
|
public bool this.ContainsPart(string partNumber) => Parts.ContainsKey(partNumber);
|
|
}
|
|
}
|
|
}
|