aboutsummaryrefslogtreecommitdiff
path: root/Emby.Naming/Video/VideoResolver.cs
blob: b4aee614b0a217131d193d9b8721308f75c9265d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#pragma warning disable CS1591
#nullable enable

using System;
using System.IO;
using System.Linq;
using Emby.Naming.Common;

namespace Emby.Naming.Video
{
    public class VideoResolver
    {
        private readonly NamingOptions _options;

        public VideoResolver(NamingOptions options)
        {
            _options = options;
        }

        /// <summary>
        /// Resolves the directory.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <returns>VideoFileInfo.</returns>
        public VideoFileInfo? ResolveDirectory(string path)
        {
            return Resolve(path, true);
        }

        /// <summary>
        /// Resolves the file.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <returns>VideoFileInfo.</returns>
        public VideoFileInfo? ResolveFile(string path)
        {
            return Resolve(path, false);
        }

        /// <summary>
        /// Resolves the specified path.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <param name="isDirectory">if set to <c>true</c> [is folder].</param>
        /// <param name="parseName">Whether or not the name should be parsed for info.</param>
        /// <returns>VideoFileInfo.</returns>
        /// <exception cref="ArgumentNullException"><c>path</c> is <c>null</c>.</exception>
        public VideoFileInfo? Resolve(string path, bool isDirectory, bool parseName = true)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException(nameof(path));
            }

            bool isStub = false;
            string? container = null;
            string? stubType = null;

            if (!isDirectory)
            {
                var extension = Path.GetExtension(path);

                // Check supported extensions
                if (!_options.VideoFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
                {
                    // It's not supported. Check stub extensions
                    if (!StubResolver.TryResolveFile(path, _options, out stubType))
                    {
                        return null;
                    }

                    isStub = true;
                }

                container = extension.TrimStart('.');
            }

            var flags = new FlagParser(_options).GetFlags(path);
            var format3DResult = new Format3DParser(_options).Parse(flags);

            var extraResult = new ExtraResolver(_options).GetExtraInfo(path);

            var name = isDirectory
                ? Path.GetFileName(path)
                : Path.GetFileNameWithoutExtension(path);

            int? year = null;

            if (parseName)
            {
                var cleanDateTimeResult = CleanDateTime(name);
                name = cleanDateTimeResult.Name;
                year = cleanDateTimeResult.Year;

                if (extraResult.ExtraType == null
                    && TryCleanString(name, out ReadOnlySpan<char> newName))
                {
                    name = newName.ToString();
                }
            }

            return new VideoFileInfo
            {
                Path = path,
                Container = container,
                IsStub = isStub,
                Name = name,
                Year = year,
                StubType = stubType,
                Is3D = format3DResult.Is3D,
                Format3D = format3DResult.Format3D,
                ExtraType = extraResult.ExtraType,
                IsDirectory = isDirectory,
                ExtraRule = extraResult.Rule
            };
        }

        public bool IsVideoFile(string path)
        {
            var extension = Path.GetExtension(path) ?? string.Empty;
            return _options.VideoFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase);
        }

        public bool IsStubFile(string path)
        {
            var extension = Path.GetExtension(path) ?? string.Empty;
            return _options.StubFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase);
        }

        public bool TryCleanString(string name, out ReadOnlySpan<char> newName)
        {
            return CleanStringParser.TryClean(name, _options.CleanStringRegexes, out newName);
        }

        public CleanDateTimeResult CleanDateTime(string name)
        {
            return CleanDateTimeParser.Clean(name, _options.CleanDateTimeRegexes);
        }
    }
}