< Summary - Jellyfin

Information
Class: Emby.Naming.ExternalFiles.ExternalPathParser
Assembly: Emby.Naming
File(s): /srv/git/jellyfin/Emby.Naming/ExternalFiles/ExternalPathParser.cs
Line coverage
100%
Covered lines: 47
Uncovered lines: 0
Coverable lines: 47
Total lines: 129
Line coverage: 100%
Branch coverage
97%
Covered branches: 37
Total branches: 38
Branch coverage: 97.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
ParseFile(...)97.36%3838100%

File(s)

/srv/git/jellyfin/Emby.Naming/ExternalFiles/ExternalPathParser.cs

#LineLine coverage
 1using System;
 2using System.IO;
 3using System.Linq;
 4using Emby.Naming.Common;
 5using Jellyfin.Extensions;
 6using MediaBrowser.Model.Dlna;
 7using MediaBrowser.Model.Globalization;
 8
 9namespace Emby.Naming.ExternalFiles
 10{
 11    /// <summary>
 12    /// External media file parser class.
 13    /// </summary>
 14    public class ExternalPathParser
 15    {
 16        private readonly NamingOptions _namingOptions;
 17        private readonly DlnaProfileType _type;
 18        private readonly ILocalizationManager _localizationManager;
 19
 20        /// <summary>
 21        /// Initializes a new instance of the <see cref="ExternalPathParser"/> class.
 22        /// </summary>
 23        /// <param name="localizationManager">The localization manager.</param>
 24        /// <param name="namingOptions">The <see cref="NamingOptions"/> object containing FileExtensions, MediaDefaultFl
 25        /// <param name="type">The <see cref="DlnaProfileType"/> of the parsed file.</param>
 26        public ExternalPathParser(NamingOptions namingOptions, ILocalizationManager localizationManager, DlnaProfileType
 27        {
 21828            _localizationManager = localizationManager;
 21829            _namingOptions = namingOptions;
 21830            _type = type;
 21831        }
 32
 33        /// <summary>
 34        /// Parse filename and extract information.
 35        /// </summary>
 36        /// <param name="path">Path to file.</param>
 37        /// <param name="extraString">Part of the filename only containing the extra information.</param>
 38        /// <returns>Returns null or an <see cref="ExternalPathParserResult"/> object if parsing is successful.</returns
 39        public ExternalPathParserResult? ParseFile(string path, string? extraString)
 40        {
 7241            if (path.Length == 0)
 42            {
 243                return null;
 44            }
 45
 7046            var extension = Path.GetExtension(path.AsSpan());
 7047            if (!(_type == DlnaProfileType.Subtitle && _namingOptions.SubtitleFileExtensions.Contains(extension, StringC
 7048                && !(_type == DlnaProfileType.Audio && _namingOptions.AudioFileExtensions.Contains(extension, StringComp
 7049                && !(_type == DlnaProfileType.Lyric && _namingOptions.LyricFileExtensions.Contains(extension, StringComp
 50            {
 1751                return null;
 52            }
 53
 5354            var pathInfo = new ExternalPathParserResult(path);
 55
 5356            if (string.IsNullOrEmpty(extraString))
 57            {
 1958                return pathInfo;
 59            }
 60
 13661            foreach (var separator in _namingOptions.MediaFlagDelimiters)
 62            {
 3463                var languageString = extraString;
 3464                var titleString = string.Empty;
 65                const int SeparatorLength = 1;
 66
 10367                while (languageString.Length > 0)
 68                {
 6969                    int lastSeparator = languageString.LastIndexOf(separator);
 70
 6971                    if (lastSeparator == -1)
 72                    {
 73                          break;
 74                    }
 75
 6976                    string currentSlice = languageString[lastSeparator..];
 6977                    string currentSliceWithoutSeparator = currentSlice[SeparatorLength..];
 78
 6979                    if (_namingOptions.MediaDefaultFlags.Any(s => currentSliceWithoutSeparator.Contains(s, StringCompari
 80                    {
 981                        pathInfo.IsDefault = true;
 982                        extraString = extraString.Replace(currentSlice, string.Empty, StringComparison.OrdinalIgnoreCase
 983                        languageString = languageString[..lastSeparator];
 984                        continue;
 85                    }
 86
 6087                    if (_namingOptions.MediaForcedFlags.Any(s => currentSliceWithoutSeparator.Contains(s, StringComparis
 88                    {
 1089                        pathInfo.IsForced = true;
 1090                        extraString = extraString.Replace(currentSlice, string.Empty, StringComparison.OrdinalIgnoreCase
 1091                        languageString = languageString[..lastSeparator];
 1092                        continue;
 93                    }
 94
 95                    // Try to translate to three character code
 5096                    var culture = _localizationManager.FindLanguageInfo(currentSliceWithoutSeparator);
 97
 5098                    if (culture is not null && pathInfo.Language is null)
 99                    {
 20100                        pathInfo.Language = culture.ThreeLetterISOLanguageName;
 20101                        extraString = extraString.Replace(currentSlice, string.Empty, StringComparison.OrdinalIgnoreCase
 102                    }
 30103                    else if (culture is not null && pathInfo.Language == "hin")
 104                    {
 105                        // Hindi language code "hi" collides with a hearing impaired flag - use as Hindi only if no othe
 1106                        pathInfo.IsHearingImpaired = true;
 1107                        pathInfo.Language = culture.ThreeLetterISOLanguageName;
 1108                        extraString = extraString.Replace(currentSlice, string.Empty, StringComparison.OrdinalIgnoreCase
 109                    }
 29110                    else if (_namingOptions.MediaHearingImpairedFlags.Any(s => currentSliceWithoutSeparator.Equals(s, St
 111                    {
 5112                        pathInfo.IsHearingImpaired = true;
 5113                        extraString = extraString.Replace(currentSlice, string.Empty, StringComparison.OrdinalIgnoreCase
 114                    }
 115                    else
 116                    {
 24117                        titleString = currentSlice + titleString;
 118                    }
 119
 50120                    languageString = languageString[..lastSeparator];
 121                }
 122
 34123                pathInfo.Title = titleString.Length >= SeparatorLength ? titleString[SeparatorLength..] : null;
 124            }
 125
 34126            return pathInfo;
 127        }
 128    }
 129}