aboutsummaryrefslogtreecommitdiff
path: root/Emby.Naming/AudioBook
diff options
context:
space:
mode:
authorstefan <stefan@hegedues.at>2018-09-12 19:26:21 +0200
committerstefan <stefan@hegedues.at>2018-09-12 19:26:21 +0200
commit48facb797ed912e4ea6b04b17d1ff190ac2daac4 (patch)
tree8dae77a31670a888d733484cb17dd4077d5444e8 /Emby.Naming/AudioBook
parentc32d8656382a0eacb301692e0084377fc433ae9b (diff)
Update to 3.5.2 and .net core 2.1
Diffstat (limited to 'Emby.Naming/AudioBook')
-rw-r--r--Emby.Naming/AudioBook/AudioBookFileInfo.cs49
-rw-r--r--Emby.Naming/AudioBook/AudioBookFilePathParser.cs81
-rw-r--r--Emby.Naming/AudioBook/AudioBookFilePathParserResult.cs13
-rw-r--r--Emby.Naming/AudioBook/AudioBookInfo.cs40
-rw-r--r--Emby.Naming/AudioBook/AudioBookListResolver.cs68
-rw-r--r--Emby.Naming/AudioBook/AudioBookResolver.cs60
6 files changed, 311 insertions, 0 deletions
diff --git a/Emby.Naming/AudioBook/AudioBookFileInfo.cs b/Emby.Naming/AudioBook/AudioBookFileInfo.cs
new file mode 100644
index 000000000..88a98d0f1
--- /dev/null
+++ b/Emby.Naming/AudioBook/AudioBookFileInfo.cs
@@ -0,0 +1,49 @@
+
+using System;
+using Emby.Naming.Video;
+
+namespace Emby.Naming.AudioBook
+{
+ /// <summary>
+ /// Represents a single video file
+ /// </summary>
+ public class AudioBookFileInfo : IComparable<AudioBookFileInfo>
+ {
+ /// <summary>
+ /// Gets or sets the path.
+ /// </summary>
+ /// <value>The path.</value>
+ public string Path { get; set; }
+ /// <summary>
+ /// Gets or sets the container.
+ /// </summary>
+ /// <value>The container.</value>
+ public string Container { get; set; }
+ /// <summary>
+ /// Gets or sets the part number.
+ /// </summary>
+ /// <value>The part number.</value>
+ public int? PartNumber { get; set; }
+ /// <summary>
+ /// Gets or sets the chapter number.
+ /// </summary>
+ /// <value>The chapter number.</value>
+ public int? ChapterNumber { get; set; }
+ /// <summary>
+ /// Gets or sets the type.
+ /// </summary>
+ /// <value>The type.</value>
+ public bool IsDirectory { get; set; }
+
+ public int CompareTo(AudioBookFileInfo other)
+ {
+ if (ReferenceEquals(this, other)) return 0;
+ if (ReferenceEquals(null, other)) return 1;
+ var chapterNumberComparison = Nullable.Compare(ChapterNumber, other.ChapterNumber);
+ if (chapterNumberComparison != 0) return chapterNumberComparison;
+ var partNumberComparison = Nullable.Compare(PartNumber, other.PartNumber);
+ if (partNumberComparison != 0) return partNumberComparison;
+ return string.Compare(Path, other.Path, StringComparison.Ordinal);
+ }
+ }
+}
diff --git a/Emby.Naming/AudioBook/AudioBookFilePathParser.cs b/Emby.Naming/AudioBook/AudioBookFilePathParser.cs
new file mode 100644
index 000000000..b4805edd2
--- /dev/null
+++ b/Emby.Naming/AudioBook/AudioBookFilePathParser.cs
@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using Emby.Naming.Common;
+using Emby.Naming.TV;
+
+namespace Emby.Naming.AudioBook
+{
+ public class AudioBookFilePathParser
+ {
+ private readonly NamingOptions _options;
+
+ public AudioBookFilePathParser(NamingOptions options)
+ {
+ _options = options;
+ }
+
+ public AudioBookFilePathParserResult Parse(string path, bool IsDirectory)
+ {
+ AudioBookFilePathParserResult result = Parse(path);
+ return !result.Success ? new AudioBookFilePathParserResult() : result;
+ }
+
+ private AudioBookFilePathParserResult Parse(string path)
+ {
+ var result = new AudioBookFilePathParserResult();
+ var fileName = Path.GetFileNameWithoutExtension(path);
+ foreach (var expression in _options.AudioBookPartsExpressions)
+ {
+ var match = new Regex(expression, RegexOptions.IgnoreCase).Match(fileName);
+ if (match.Success)
+ {
+ if (!result.ChapterNumber.HasValue)
+ {
+ var value = match.Groups["chapter"];
+ if (value.Success)
+ {
+ int intValue;
+ if (int.TryParse(value.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out intValue))
+ {
+ result.ChapterNumber = intValue;
+ }
+ }
+ }
+ if (!result.PartNumber.HasValue)
+ {
+ var value = match.Groups["part"];
+ if (value.Success)
+ {
+ int intValue;
+ if (int.TryParse(value.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out intValue))
+ {
+ result.ChapterNumber = intValue;
+ }
+ }
+ }
+ }
+ }
+
+ /*var matches = _iRegexProvider.GetRegex("\\d+", RegexOptions.IgnoreCase).Matches(fileName);
+ if (matches.Count > 0)
+ {
+ if (!result.ChapterNumber.HasValue)
+ {
+ result.ChapterNumber = int.Parse(matches[0].Groups[0].Value);
+ }
+ if (matches.Count > 1)
+ {
+ result.PartNumber = int.Parse(matches[matches.Count - 1].Groups[0].Value);
+ }
+ }*/
+ result.Success = result.PartNumber.HasValue || result.ChapterNumber.HasValue;
+
+ return result;
+ }
+ }
+}
diff --git a/Emby.Naming/AudioBook/AudioBookFilePathParserResult.cs b/Emby.Naming/AudioBook/AudioBookFilePathParserResult.cs
new file mode 100644
index 000000000..759e7b8ad
--- /dev/null
+++ b/Emby.Naming/AudioBook/AudioBookFilePathParserResult.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Emby.Naming.AudioBook
+{
+ public class AudioBookFilePathParserResult
+ {
+ public int? PartNumber { get; set; }
+ public int? ChapterNumber { get; set; }
+ public bool Success { get; set; }
+ }
+}
diff --git a/Emby.Naming/AudioBook/AudioBookInfo.cs b/Emby.Naming/AudioBook/AudioBookInfo.cs
new file mode 100644
index 000000000..e039e5359
--- /dev/null
+++ b/Emby.Naming/AudioBook/AudioBookInfo.cs
@@ -0,0 +1,40 @@
+using System.Collections.Generic;
+using Emby.Naming.Video;
+
+namespace Emby.Naming.AudioBook
+{
+ /// <summary>
+ /// Represents a complete video, including all parts and subtitles
+ /// </summary>
+ public class AudioBookInfo
+ {
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <value>The name.</value>
+ public string Name { get; set; }
+ public int? Year { get; set; }
+ /// <summary>
+ /// Gets or sets the files.
+ /// </summary>
+ /// <value>The files.</value>
+ public List<AudioBookFileInfo> Files { get; set; }
+ /// <summary>
+ /// Gets or sets the extras.
+ /// </summary>
+ /// <value>The extras.</value>
+ public List<AudioBookFileInfo> Extras { get; set; }
+ /// <summary>
+ /// Gets or sets the alternate versions.
+ /// </summary>
+ /// <value>The alternate versions.</value>
+ public List<AudioBookFileInfo> AlternateVersions { get; set; }
+
+ public AudioBookInfo()
+ {
+ Files = new List<AudioBookFileInfo>();
+ Extras = new List<AudioBookFileInfo>();
+ AlternateVersions = new List<AudioBookFileInfo>();
+ }
+ }
+}
diff --git a/Emby.Naming/AudioBook/AudioBookListResolver.cs b/Emby.Naming/AudioBook/AudioBookListResolver.cs
new file mode 100644
index 000000000..8cf6a03bd
--- /dev/null
+++ b/Emby.Naming/AudioBook/AudioBookListResolver.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Emby.Naming.Common;
+using Emby.Naming.Video;
+using MediaBrowser.Model.IO;
+
+namespace Emby.Naming.AudioBook
+{
+ public class AudioBookListResolver
+ {
+ private readonly NamingOptions _options;
+
+ public AudioBookListResolver(NamingOptions options)
+ {
+ _options = options;
+ }
+
+ public IEnumerable<AudioBookInfo> Resolve(List<FileSystemMetadata> files)
+ {
+ var audioBookResolver = new AudioBookResolver(_options);
+
+ var audiobookFileInfos = files
+ .Select(i => audioBookResolver.Resolve(i.FullName, i.IsDirectory))
+ .Where(i => i != null)
+ .ToList();
+
+ // Filter out all extras, otherwise they could cause stacks to not be resolved
+ // See the unit test TestStackedWithTrailer
+ var metadata = audiobookFileInfos
+ .Select(i => new FileSystemMetadata
+ {
+ FullName = i.Path,
+ IsDirectory = i.IsDirectory
+ });
+
+ var stackResult = new StackResolver(_options)
+ .ResolveAudioBooks(metadata);
+
+ var list = new List<AudioBookInfo>();
+
+ foreach (var stack in stackResult.Stacks)
+ {
+ var stackFiles = stack.Files.Select(i => audioBookResolver.Resolve(i, stack.IsDirectoryStack)).ToList();
+ stackFiles.Sort();
+ var info = new AudioBookInfo
+ {
+ Files = stackFiles,
+ Name = stack.Name
+ };
+ list.Add(info);
+ }
+
+ // Whatever files are left, just add them
+ /*list.AddRange(remainingFiles.Select(i => new AudioBookInfo
+ {
+ Files = new List<AudioBookFileInfo> { i },
+ Name = i.,
+ Year = i.Year
+ }));*/
+
+ var orderedList = list.OrderBy(i => i.Name);
+
+ return orderedList;
+ }
+ }
+}
diff --git a/Emby.Naming/AudioBook/AudioBookResolver.cs b/Emby.Naming/AudioBook/AudioBookResolver.cs
new file mode 100644
index 000000000..a206ee30b
--- /dev/null
+++ b/Emby.Naming/AudioBook/AudioBookResolver.cs
@@ -0,0 +1,60 @@
+using System;
+using System.IO;
+using System.Linq;
+using Emby.Naming.Common;
+using Emby.Naming.TV;
+using Emby.Naming.Video;
+
+namespace Emby.Naming.AudioBook
+{
+ public class AudioBookResolver
+ {
+ private readonly NamingOptions _options;
+
+ public AudioBookResolver(NamingOptions options)
+ {
+ _options = options;
+ }
+
+ public AudioBookFileInfo ParseFile(string path)
+ {
+ return Resolve(path, false);
+ }
+
+ public AudioBookFileInfo ParseDirectory(string path)
+ {
+ return Resolve(path, true);
+ }
+
+ public AudioBookFileInfo Resolve(string path, bool IsDirectory = false)
+ {
+ if (string.IsNullOrEmpty(path))
+ {
+ throw new ArgumentNullException("path");
+ }
+ if (IsDirectory)
+ return null;
+
+ var extension = Path.GetExtension(path) ?? string.Empty;
+ // Check supported extensions
+ if (!_options.AudioFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
+ {
+ return null;
+ }
+
+ var container = extension.TrimStart('.');
+
+ var parsingResult = new AudioBookFilePathParser(_options)
+ .Parse(path, IsDirectory);
+
+ return new AudioBookFileInfo
+ {
+ Path = path,
+ Container = container,
+ PartNumber = parsingResult.PartNumber,
+ ChapterNumber = parsingResult.ChapterNumber,
+ IsDirectory = IsDirectory
+ };
+ }
+ }
+}