repo creation with initial code after cloning public repo

This commit is contained in:
2026-02-19 07:36:25 -05:00
commit 460884fea3
2860 changed files with 650825 additions and 0 deletions
@@ -0,0 +1,133 @@
using System;
using System.IO;
using System.Linq;
using Emby.Naming.Common;
using Jellyfin.Extensions;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Globalization;
namespace Emby.Naming.ExternalFiles
{
/// <summary>
/// External media file parser class.
/// </summary>
public class ExternalPathParser
{
private readonly NamingOptions _namingOptions;
private readonly DlnaProfileType _type;
private readonly ILocalizationManager _localizationManager;
/// <summary>
/// Initializes a new instance of the <see cref="ExternalPathParser"/> class.
/// </summary>
/// <param name="localizationManager">The localization manager.</param>
/// <param name="namingOptions">The <see cref="NamingOptions"/> object containing FileExtensions, MediaDefaultFlags, MediaForcedFlags and MediaFlagDelimiters.</param>
/// <param name="type">The <see cref="DlnaProfileType"/> of the parsed file.</param>
public ExternalPathParser(NamingOptions namingOptions, ILocalizationManager localizationManager, DlnaProfileType type)
{
_localizationManager = localizationManager;
_namingOptions = namingOptions;
_type = type;
}
/// <summary>
/// Parse filename and extract information.
/// </summary>
/// <param name="path">Path to file.</param>
/// <param name="extraString">Part of the filename only containing the extra information.</param>
/// <returns>Returns null or an <see cref="ExternalPathParserResult"/> object if parsing is successful.</returns>
public ExternalPathParserResult? ParseFile(string path, string? extraString)
{
if (path.Length == 0)
{
return null;
}
var extension = Path.GetExtension(path.AsSpan());
if (!(_type == DlnaProfileType.Subtitle && _namingOptions.SubtitleFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase))
&& !(_type == DlnaProfileType.Audio && _namingOptions.AudioFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase))
&& !(_type == DlnaProfileType.Lyric && _namingOptions.LyricFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase)))
{
return null;
}
var pathInfo = new ExternalPathParserResult(path);
if (string.IsNullOrEmpty(extraString))
{
return pathInfo;
}
foreach (var separator in _namingOptions.MediaFlagDelimiters)
{
var languageString = extraString;
var titleString = string.Empty;
const int SeparatorLength = 1;
while (languageString.Length > 0)
{
int lastSeparator = languageString.LastIndexOf(separator);
if (lastSeparator == -1)
{
break;
}
string currentSlice = languageString[lastSeparator..];
string currentSliceWithoutSeparator = currentSlice[SeparatorLength..];
if (_namingOptions.MediaDefaultFlags.Any(s => currentSliceWithoutSeparator.Contains(s, StringComparison.OrdinalIgnoreCase)))
{
pathInfo.IsDefault = true;
extraString = extraString.Replace(currentSlice, string.Empty, StringComparison.OrdinalIgnoreCase);
languageString = languageString[..lastSeparator];
continue;
}
if (_namingOptions.MediaForcedFlags.Any(s => currentSliceWithoutSeparator.Contains(s, StringComparison.OrdinalIgnoreCase)))
{
pathInfo.IsForced = true;
extraString = extraString.Replace(currentSlice, string.Empty, StringComparison.OrdinalIgnoreCase);
languageString = languageString[..lastSeparator];
continue;
}
// Try to translate to three character code
var culture = _localizationManager.FindLanguageInfo(currentSliceWithoutSeparator);
if (culture is not null && pathInfo.Language is null)
{
pathInfo.Language = culture.Name.Contains('-', StringComparison.OrdinalIgnoreCase)
? culture.Name
: culture.ThreeLetterISOLanguageName;
extraString = extraString.Replace(currentSlice, string.Empty, StringComparison.OrdinalIgnoreCase);
}
else if (culture is not null && pathInfo.Language == "hin")
{
// Hindi language code "hi" collides with a hearing impaired flag - use as Hindi only if no other language is set
pathInfo.IsHearingImpaired = true;
pathInfo.Language = culture.Name.Contains('-', StringComparison.OrdinalIgnoreCase)
? culture.Name
: culture.ThreeLetterISOLanguageName;
extraString = extraString.Replace(currentSlice, string.Empty, StringComparison.OrdinalIgnoreCase);
}
else if (_namingOptions.MediaHearingImpairedFlags.Any(s => currentSliceWithoutSeparator.Equals(s, StringComparison.OrdinalIgnoreCase)))
{
pathInfo.IsHearingImpaired = true;
extraString = extraString.Replace(currentSlice, string.Empty, StringComparison.OrdinalIgnoreCase);
}
else
{
titleString = currentSlice + titleString;
}
languageString = languageString[..lastSeparator];
}
pathInfo.Title = titleString.Length >= SeparatorLength ? titleString[SeparatorLength..] : null;
}
return pathInfo;
}
}
}
@@ -0,0 +1,59 @@
namespace Emby.Naming.ExternalFiles
{
/// <summary>
/// Class holding information about external files.
/// </summary>
public class ExternalPathParserResult
{
/// <summary>
/// Initializes a new instance of the <see cref="ExternalPathParserResult"/> class.
/// </summary>
/// <param name="path">Path to file.</param>
/// <param name="isDefault">Is default.</param>
/// <param name="isForced">Is forced.</param>
/// <param name="isHearingImpaired">For the hearing impaired.</param>
public ExternalPathParserResult(string path, bool isDefault = false, bool isForced = false, bool isHearingImpaired = false)
{
Path = path;
IsDefault = isDefault;
IsForced = isForced;
IsHearingImpaired = isHearingImpaired;
}
/// <summary>
/// Gets or sets the path.
/// </summary>
/// <value>The path.</value>
public string Path { get; set; }
/// <summary>
/// Gets or sets the language.
/// </summary>
/// <value>The language.</value>
public string? Language { get; set; }
/// <summary>
/// Gets or sets the title.
/// </summary>
/// <value>The title.</value>
public string? Title { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is default.
/// </summary>
/// <value><c>true</c> if this instance is default; otherwise, <c>false</c>.</value>
public bool IsDefault { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is forced.
/// </summary>
/// <value><c>true</c> if this instance is forced; otherwise, <c>false</c>.</value>
public bool IsForced { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is for the hearing impaired.
/// </summary>
/// <value><c>true</c> if this instance is for the hearing impaired; otherwise, <c>false</c>.</value>
public bool IsHearingImpaired { get; set; }
}
}