diff options
Diffstat (limited to 'Emby.Naming')
| -rw-r--r-- | Emby.Naming/Audio/ExternalAudioFilePathParser.cs | 59 | ||||
| -rw-r--r-- | Emby.Naming/Common/NamingOptions.cs | 274 | ||||
| -rw-r--r-- | Emby.Naming/ExternalFiles/ExternalPathParser.cs | 116 | ||||
| -rw-r--r-- | Emby.Naming/ExternalFiles/ExternalPathParserResult.cs (renamed from Emby.Naming/Audio/ExternalAudioFileInfo.cs) | 11 | ||||
| -rw-r--r-- | Emby.Naming/Subtitles/SubtitleFileInfo.cs | 51 | ||||
| -rw-r--r-- | Emby.Naming/Subtitles/SubtitleFilePathParser.cs | 59 |
6 files changed, 241 insertions, 329 deletions
diff --git a/Emby.Naming/Audio/ExternalAudioFilePathParser.cs b/Emby.Naming/Audio/ExternalAudioFilePathParser.cs deleted file mode 100644 index ab5af9fc6..000000000 --- a/Emby.Naming/Audio/ExternalAudioFilePathParser.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using Emby.Naming.Common; -using Jellyfin.Extensions; - -namespace Emby.Naming.Audio -{ - /// <summary> - /// External Audio Parser class. - /// </summary> - public class ExternalAudioFilePathParser - { - private readonly NamingOptions _options; - - /// <summary> - /// Initializes a new instance of the <see cref="ExternalAudioFilePathParser"/> class. - /// </summary> - /// <param name="options"><see cref="NamingOptions"/> object containing AudioFileExtensions, ExternalAudioDefaultFlags, ExternalAudioForcedFlags and ExternalAudioFlagDelimiters.</param> - public ExternalAudioFilePathParser(NamingOptions options) - { - _options = options; - } - - /// <summary> - /// Parse file to determine if it is a ExternalAudio and <see cref="ExternalAudioFileInfo"/>. - /// </summary> - /// <param name="path">Path to file.</param> - /// <returns>Returns null or <see cref="ExternalAudioFileInfo"/> object if parsing is successful.</returns> - public ExternalAudioFileInfo? ParseFile(string path) - { - if (path.Length == 0) - { - return null; - } - - var extension = Path.GetExtension(path); - if (!_options.AudioFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase)) - { - return null; - } - - var flags = GetFileFlags(path); - var info = new ExternalAudioFileInfo( - path, - _options.ExternalAudioDefaultFlags.Any(i => flags.Contains(i, StringComparison.OrdinalIgnoreCase)), - _options.ExternalAudioForcedFlags.Any(i => flags.Contains(i, StringComparison.OrdinalIgnoreCase))); - - return info; - } - - private string[] GetFileFlags(string path) - { - var file = Path.GetFileNameWithoutExtension(path); - - return file.Split(_options.ExternalAudioFlagDelimiters, StringSplitOptions.RemoveEmptyEntries); - } - } -} diff --git a/Emby.Naming/Common/NamingOptions.cs b/Emby.Naming/Common/NamingOptions.cs index 82a3ad2b7..a79153e86 100644 --- a/Emby.Naming/Common/NamingOptions.cs +++ b/Emby.Naming/Common/NamingOptions.cs @@ -23,47 +23,60 @@ namespace Emby.Naming.Common { VideoFileExtensions = new[] { - ".m4v", + ".001", + ".3g2", ".3gp", - ".nsv", - ".ts", - ".ty", - ".strm", - ".rm", - ".rmvb", - ".ifo", - ".mov", - ".qt", - ".divx", - ".xvid", - ".bivx", - ".vob", - ".nrg", - ".img", - ".iso", - ".pva", - ".wmv", + ".amv", ".asf", ".asx", - ".ogm", - ".m2v", ".avi", ".bin", + ".bivx", + ".divx", + ".dv", ".dvr-ms", - ".mpg", - ".mpeg", - ".mp4", + ".f4v", + ".fli", + ".flv", + ".ifo", + ".img", + ".iso", + ".m2t", + ".m2ts", + ".m2v", + ".m4v", ".mkv", - ".avc", - ".vp3", - ".svq3", + ".mk3d", + ".mov", + ".mp2", + ".mp4", + ".mpe", + ".mpeg", + ".mpg", + ".mts", + ".mxf", + ".nrg", + ".nsv", ".nuv", + ".ogg", + ".ogm", + ".ogv", + ".pva", + ".qt", + ".rec", + ".rm", + ".rmvb", + ".svq3", + ".tp", + ".ts", + ".ty", ".viv", - ".dv", - ".fli", - ".flv", - ".001", - ".tp" + ".vob", + ".vp3", + ".webm", + ".wmv", + ".wtv", + ".xvid" }; VideoFlagDelimiters = new[] @@ -150,35 +163,19 @@ namespace Emby.Naming.Common SubtitleFileExtensions = new[] { ".ass", - ".smi", + ".mks", ".sami", + ".smi", ".srt", ".ssa", ".sub", ".vtt", - ".mks" - }; - - SubtitleFlagDelimiters = new[] - { - '.' - }; - - SubtitleForcedFlags = new[] - { - "foreign", - "forced" - }; - - SubtitleDefaultFlags = new[] - { - "default" }; AlbumStackingPrefixes = new[] { - "disc", "cd", + "disc", "disk", "vol", "volume" @@ -186,82 +183,99 @@ namespace Emby.Naming.Common AudioFileExtensions = new[] { - ".nsv", - ".m4a", - ".flac", + ".669", + ".3gp", + ".aa", ".aac", - ".strm", - ".pls", - ".rm", - ".mpa", - ".wav", - ".wma", - ".ogg", - ".opus", - ".mp3", - ".mp2", - ".mod", + ".aax", + ".ac3", + ".act", + ".adp", + ".adplug", + ".adx", + ".afc", ".amf", - ".669", + ".aif", + ".aiff", + ".alac", + ".amr", + ".ape", + ".ast", + ".au", + ".awb", + ".cda", + ".cue", ".dmf", + ".dsf", ".dsm", + ".dsp", + ".dts", + ".dvf", ".far", + ".flac", ".gdm", + ".gsm", + ".gym", + ".hps", ".imf", ".it", ".m15", + ".m4a", + ".m4b", + ".mac", ".med", + ".mka", + ".mmf", + ".mod", + ".mogg", + ".mp2", + ".mp3", + ".mpa", + ".mpc", + ".mpp", + ".mp+", + ".msv", + ".nmf", + ".nsf", + ".nsv", + ".oga", + ".ogg", ".okt", + ".opus", + ".pls", + ".ra", + ".rf64", + ".rm", ".s3m", - ".stm", ".sfx", + ".shn", + ".sid", + ".spc", + ".stm", + ".strm", ".ult", ".uni", - ".xm", - ".sid", - ".ac3", - ".dts", - ".cue", - ".aif", - ".aiff", - ".ape", - ".mac", - ".mpc", - ".mp+", - ".mpp", - ".shn", + ".vox", + ".wav", + ".wma", ".wv", - ".nsf", - ".spc", - ".gym", - ".adplug", - ".adx", - ".dsp", - ".adp", - ".ymf", - ".ast", - ".afc", - ".hps", + ".xm", ".xsp", - ".acc", - ".m4b", - ".oga", - ".dsf", - ".mka" + ".ymf" }; - ExternalAudioFlagDelimiters = new[] + MediaFlagDelimiters = new[] { - '.' + "." }; - ExternalAudioForcedFlags = new[] + MediaForcedFlags = new[] { "foreign", "forced" }; - ExternalAudioDefaultFlags = new[] + MediaDefaultFlags = new[] { "default" }; @@ -668,39 +682,6 @@ namespace Emby.Naming.Common @"^\s*(?<name>[^ ].*?)\s*$" }; - VideoFileExtensions = new[] - { - ".mkv", - ".m2t", - ".m2ts", - ".img", - ".iso", - ".mk3d", - ".ts", - ".rmvb", - ".mov", - ".avi", - ".mpg", - ".mpeg", - ".wmv", - ".mp4", - ".divx", - ".dvr-ms", - ".wtv", - ".ogm", - ".ogv", - ".asf", - ".m4v", - ".flv", - ".f4v", - ".3gp", - ".webm", - ".mts", - ".m2v", - ".rec", - ".mxf" - }; - MultipleEpisodeExpressions = new[] { @".*(\\|\/)[sS]?(?<seasonnumber>[0-9]{1,4})[xX](?<epnumber>[0-9]{1,3})((-| - )[0-9]{1,4}[eExX](?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$", @@ -732,19 +713,19 @@ namespace Emby.Naming.Common public string[] AudioFileExtensions { get; set; } /// <summary> - /// Gets or sets list of external audio flag delimiters. + /// Gets or sets list of external media flag delimiters. /// </summary> - public char[] ExternalAudioFlagDelimiters { get; set; } + public string[] MediaFlagDelimiters { get; set; } /// <summary> - /// Gets or sets list of external audio forced flags. + /// Gets or sets list of external media forced flags. /// </summary> - public string[] ExternalAudioForcedFlags { get; set; } + public string[] MediaForcedFlags { get; set; } /// <summary> - /// Gets or sets list of external audio default flags. + /// Gets or sets list of external media default flags. /// </summary> - public string[] ExternalAudioDefaultFlags { get; set; } + public string[] MediaDefaultFlags { get; set; } /// <summary> /// Gets or sets list of album stacking prefixes. @@ -757,21 +738,6 @@ namespace Emby.Naming.Common public string[] SubtitleFileExtensions { get; set; } /// <summary> - /// Gets or sets list of subtitles flag delimiters. - /// </summary> - public char[] SubtitleFlagDelimiters { get; set; } - - /// <summary> - /// Gets or sets list of subtitle forced flags. - /// </summary> - public string[] SubtitleForcedFlags { get; set; } - - /// <summary> - /// Gets or sets list of subtitle default flags. - /// </summary> - public string[] SubtitleDefaultFlags { get; set; } - - /// <summary> /// Gets or sets list of episode regular expressions. /// </summary> public EpisodeExpression[] EpisodeExpressions { get; set; } diff --git a/Emby.Naming/ExternalFiles/ExternalPathParser.cs b/Emby.Naming/ExternalFiles/ExternalPathParser.cs new file mode 100644 index 000000000..7b5767b67 --- /dev/null +++ b/Emby.Naming/ExternalFiles/ExternalPathParser.cs @@ -0,0 +1,116 @@ +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 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); + if (!((_type == DlnaProfileType.Subtitle && _namingOptions.SubtitleFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase)) + || (_type == DlnaProfileType.Audio && _namingOptions.AudioFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase)) + || (_type == DlnaProfileType.Video && _namingOptions.VideoFileExtensions.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; + int separatorLength = separator.Length; + + while (languageString.Length > 0) + { + var lastSeparator = languageString.LastIndexOf(separator, StringComparison.OrdinalIgnoreCase); + + if (lastSeparator == -1) + { + break; + } + + string currentSlice = languageString[lastSeparator..]; + + if (_namingOptions.MediaDefaultFlags.Any(s => currentSlice[separatorLength..].Contains(s, StringComparison.OrdinalIgnoreCase))) + { + pathInfo.IsDefault = true; + extraString = extraString.Replace(currentSlice, string.Empty, StringComparison.OrdinalIgnoreCase); + languageString = languageString[..lastSeparator]; + continue; + } + + if (_namingOptions.MediaForcedFlags.Any(s => currentSlice[separatorLength..].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(currentSlice[separatorLength..]); + + if (culture != null && pathInfo.Language == null) + { + pathInfo.Language = culture.ThreeLetterISOLanguageName; + extraString = extraString.Replace(currentSlice, string.Empty, StringComparison.OrdinalIgnoreCase); + } + else + { + titleString = currentSlice + titleString; + } + + languageString = languageString[..lastSeparator]; + } + + pathInfo.Title = separatorLength <= titleString.Length ? titleString[separatorLength..] : null; + } + + return pathInfo; + } + } +} diff --git a/Emby.Naming/Audio/ExternalAudioFileInfo.cs b/Emby.Naming/ExternalFiles/ExternalPathParserResult.cs index 4d02939cb..1cc773a2e 100644 --- a/Emby.Naming/Audio/ExternalAudioFileInfo.cs +++ b/Emby.Naming/ExternalFiles/ExternalPathParserResult.cs @@ -1,17 +1,17 @@ -namespace Emby.Naming.Audio +namespace Emby.Naming.ExternalFiles { /// <summary> - /// Class holding information about external audio files. + /// Class holding information about external files. /// </summary> - public class ExternalAudioFileInfo + public class ExternalPathParserResult { /// <summary> - /// Initializes a new instance of the <see cref="ExternalAudioFileInfo"/> class. + /// 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> - public ExternalAudioFileInfo(string path, bool isDefault, bool isForced) + public ExternalPathParserResult(string path, bool isDefault = false, bool isForced = false) { Path = path; IsDefault = isDefault; @@ -42,7 +42,6 @@ namespace Emby.Naming.Audio /// <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> diff --git a/Emby.Naming/Subtitles/SubtitleFileInfo.cs b/Emby.Naming/Subtitles/SubtitleFileInfo.cs deleted file mode 100644 index ed9ab3ebd..000000000 --- a/Emby.Naming/Subtitles/SubtitleFileInfo.cs +++ /dev/null @@ -1,51 +0,0 @@ -namespace Emby.Naming.Subtitles -{ - /// <summary> - /// Class holding information about subtitle. - /// </summary> - public class SubtitleFileInfo - { - /// <summary> - /// Initializes a new instance of the <see cref="SubtitleFileInfo"/> class. - /// </summary> - /// <param name="path">Path to file.</param> - /// <param name="isDefault">Is subtitle default.</param> - /// <param name="isForced">Is subtitle forced.</param> - public SubtitleFileInfo(string path, bool isDefault, bool isForced) - { - Path = path; - IsDefault = isDefault; - IsForced = isForced; - } - - /// <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; } - } -} diff --git a/Emby.Naming/Subtitles/SubtitleFilePathParser.cs b/Emby.Naming/Subtitles/SubtitleFilePathParser.cs deleted file mode 100644 index 7b2adf3f5..000000000 --- a/Emby.Naming/Subtitles/SubtitleFilePathParser.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using Emby.Naming.Common; -using Jellyfin.Extensions; - -namespace Emby.Naming.Subtitles -{ - /// <summary> - /// Subtitle Parser class. - /// </summary> - public class SubtitleFilePathParser - { - private readonly NamingOptions _options; - - /// <summary> - /// Initializes a new instance of the <see cref="SubtitleFilePathParser"/> class. - /// </summary> - /// <param name="options"><see cref="NamingOptions"/> object containing SubtitleFileExtensions, SubtitleDefaultFlags, SubtitleForcedFlags and SubtitleFlagDelimiters.</param> - public SubtitleFilePathParser(NamingOptions options) - { - _options = options; - } - - /// <summary> - /// Parse file to determine if it is a subtitle and <see cref="SubtitleFileInfo"/>. - /// </summary> - /// <param name="path">Path to file.</param> - /// <returns>Returns null or <see cref="SubtitleFileInfo"/> object if parsing is successful.</returns> - public SubtitleFileInfo? ParseFile(string path) - { - if (path.Length == 0) - { - return null; - } - - var extension = Path.GetExtension(path); - if (!_options.SubtitleFileExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase)) - { - return null; - } - - var flags = GetFileFlags(path); - var info = new SubtitleFileInfo( - path, - _options.SubtitleDefaultFlags.Any(i => flags.Contains(i, StringComparison.OrdinalIgnoreCase)), - _options.SubtitleForcedFlags.Any(i => flags.Contains(i, StringComparison.OrdinalIgnoreCase))); - - return info; - } - - private string[] GetFileFlags(string path) - { - var file = Path.GetFileNameWithoutExtension(path); - - return file.Split(_options.SubtitleFlagDelimiters, StringSplitOptions.RemoveEmptyEntries); - } - } -} |
