From b5ab7776f16196610f2b7d462e59c8851e5ebde2 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 16 Nov 2017 16:25:18 -0500 Subject: [PATCH] 3.2.36.11 --- .../Library/Resolvers/Audio/AudioResolver.cs | 243 +++++++++++++++--- .../Library/Resolvers/Movies/MovieResolver.cs | 37 +-- .../Library/Resolvers/VideoResolver.cs | 30 --- .../Localization/Core/es-MX.json | 2 +- .../Manager/MetadataService.cs | 2 +- .../ImageEncoderHelper.cs | 4 +- SharedVersion.cs | 2 +- 7 files changed, 240 insertions(+), 80 deletions(-) diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs index e2f2946db1..84b4492ccd 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs @@ -4,19 +4,26 @@ using MediaBrowser.Model.Entities; using System; using MediaBrowser.Controller.Entities; using System.IO; +using System.Linq; +using MediaBrowser.Controller.Providers; +using System.Collections.Generic; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Extensions; +using Emby.Naming.Video; +using Emby.Naming.AudioBook; namespace Emby.Server.Implementations.Library.Resolvers.Audio { /// /// Class AudioResolver /// - public class AudioResolver : ItemResolver + public class AudioResolver : ItemResolver, IMultiItemResolver { - private readonly ILibraryManager _libraryManager; + private readonly ILibraryManager LibraryManager; public AudioResolver(ILibraryManager libraryManager) { - _libraryManager = libraryManager; + LibraryManager = libraryManager; } /// @@ -28,6 +35,37 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio get { return ResolverPriority.Last; } } + public MultiItemResolverResult ResolveMultiple(Folder parent, + List files, + string collectionType, + IDirectoryService directoryService) + { + var result = ResolveMultipleInternal(parent, files, collectionType, directoryService); + + if (result != null) + { + foreach (var item in result.Items) + { + SetInitialItemValues((MediaBrowser.Controller.Entities.Audio.Audio)item, null); + } + } + + return result; + } + + private MultiItemResolverResult ResolveMultipleInternal(Folder parent, + List files, + string collectionType, + IDirectoryService directoryService) + { + if (string.Equals(collectionType, CollectionType.Books, StringComparison.OrdinalIgnoreCase)) + { + return ResolveMultipleAudio(parent, files, directoryService, false, collectionType, true); + } + + return null; + } + /// /// Resolves the specified args. /// @@ -37,46 +75,193 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio { // Return audio if the path is a file and has a matching extension - if (!args.IsDirectory) + var libraryOptions = args.GetLibraryOptions(); + var collectionType = args.GetCollectionType(); + + var isBooksCollectionType = string.Equals(collectionType, CollectionType.Books, StringComparison.OrdinalIgnoreCase); + + if (args.IsDirectory) { - var libraryOptions = args.GetLibraryOptions(); + if (!isBooksCollectionType) + { + return null; + } + + var files = args.FileSystemChildren + .Where(i => !LibraryManager.IgnoreFile(i, args.Parent)) + .ToList(); + + if (isBooksCollectionType) + { + return FindAudio(args, args.Path, args.Parent, files, args.DirectoryService, collectionType, false); + } + + return null; + } - if (_libraryManager.IsAudioFile(args.Path, libraryOptions)) + if (LibraryManager.IsAudioFile(args.Path, libraryOptions)) + { + if (string.Equals(Path.GetExtension(args.Path), ".cue", StringComparison.OrdinalIgnoreCase)) { - if (string.Equals(Path.GetExtension(args.Path), ".cue", StringComparison.OrdinalIgnoreCase)) - { - // if audio file exists of same name, return null + // if audio file exists of same name, return null + return null; + } - return null; - } + var isMixedCollectionType = string.IsNullOrWhiteSpace(collectionType); - var collectionType = args.GetCollectionType(); + // For conflicting extensions, give priority to videos + if (isMixedCollectionType && LibraryManager.IsVideoFile(args.Path, libraryOptions)) + { + return null; + } - var isMixed = string.IsNullOrWhiteSpace(collectionType); + MediaBrowser.Controller.Entities.Audio.Audio item = null; - // For conflicting extensions, give priority to videos - if (isMixed && _libraryManager.IsVideoFile(args.Path, libraryOptions)) - { - return null; - } + var isMusicCollectionType = string.Equals(collectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase); - var isStandalone = args.Parent == null; + // Use regular audio type for mixed libraries, owned items and music + if (isMixedCollectionType || + args.Parent == null || + isMusicCollectionType) + { + item = new MediaBrowser.Controller.Entities.Audio.Audio(); + } - if (isStandalone || - string.Equals(collectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase) || - isMixed) - { - return new MediaBrowser.Controller.Entities.Audio.Audio(); - } + else if (isBooksCollectionType) + { + item = new AudioBook(); + } - if (string.Equals(collectionType, CollectionType.Books, StringComparison.OrdinalIgnoreCase)) - { - return new AudioBook(); - } + if (item != null) + { + item.IsInMixedFolder = true; } + + return item; } return null; } + + private T FindAudio(ItemResolveArgs args, string path, Folder parent, List fileSystemEntries, IDirectoryService directoryService, string collectionType, bool parseName) + where T : MediaBrowser.Controller.Entities.Audio.Audio, new() + { + var multiDiscFolders = new List(); + + var libraryOptions = args.GetLibraryOptions(); + var filesFromOtherItems = new List(); + + // TODO: Allow GetMultiDiscMovie in here + var supportsMultiVersion = false; + + var result = ResolveMultipleAudio(parent, fileSystemEntries, directoryService, supportsMultiVersion, collectionType, parseName) ?? + new MultiItemResolverResult(); + + if (result.Items.Count == 1) + { + var videoPath = result.Items[0].Path; + + // If we were supporting this we'd be checking filesFromOtherItems + var hasOtherItems = false; + + if (!hasOtherItems) + { + var item = (T)result.Items[0]; + item.IsInMixedFolder = false; + item.Name = Path.GetFileName(item.ContainingFolderPath); + return item; + } + } + + if (result.Items.Count == 0 && multiDiscFolders.Count > 0) + { + //return GetMultiDiscAudio(multiDiscFolders, directoryService); + } + + return null; + } + + private MultiItemResolverResult ResolveMultipleAudio(Folder parent, IEnumerable fileSystemEntries, IDirectoryService directoryService, bool suppportMultiEditions, string collectionType, bool parseName) + where T : MediaBrowser.Controller.Entities.Audio.Audio, new() + { + var files = new List(); + var items = new List(); + var leftOver = new List(); + + // Loop through each child file/folder and see if we find a video + foreach (var child in fileSystemEntries) + { + if (child.IsDirectory) + { + leftOver.Add(child); + } + else if (IsIgnored(child.Name)) + { + + } + else + { + files.Add(child); + } + } + + var namingOptions = ((LibraryManager)LibraryManager).GetNamingOptions(); + + var resolver = new AudioBookListResolver(namingOptions); + var resolverResult = resolver.Resolve(files).ToList(); + + var result = new MultiItemResolverResult + { + ExtraFiles = leftOver, + Items = items + }; + + var isInMixedFolder = resolverResult.Count > 1 || (parent != null && parent.IsTopParent); + + foreach (var resolvedItem in resolverResult) + { + var firstMedia = resolvedItem.Files.First(); + + var libraryItem = new T + { + Path = firstMedia.Path, + IsInMixedFolder = isInMixedFolder, + //ProductionYear = resolvedItem.Year, + Name = parseName ? + resolvedItem.Name : + Path.GetFileNameWithoutExtension(firstMedia.Path), + //AdditionalParts = resolvedItem.Files.Skip(1).Select(i => i.Path).ToArray(), + //LocalAlternateVersions = resolvedItem.AlternateVersions.Select(i => i.Path).ToArray() + }; + + result.Items.Add(libraryItem); + } + + result.ExtraFiles.AddRange(files.Where(i => !ContainsFile(resolverResult, i))); + + return result; + } + + private bool ContainsFile(List result, FileSystemMetadata file) + { + return result.Any(i => ContainsFile(i, file)); + } + + private bool ContainsFile(AudioBookInfo result, FileSystemMetadata file) + { + return result.Files.Any(i => ContainsFile(i, file)) || + result.AlternateVersions.Any(i => ContainsFile(i, file)) || + result.Extras.Any(i => ContainsFile(i, file)); + } + + private bool ContainsFile(AudioBookFileInfo result, FileSystemMetadata file) + { + return string.Equals(result.Path, file.FullName, StringComparison.OrdinalIgnoreCase); + } + + private bool IsIgnored(string filename) + { + return false; + } } } diff --git a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs index d69a2b2404..6676164142 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs @@ -202,14 +202,14 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies { var collectionType = args.GetCollectionType(); - if (IsInvalid(args.Parent, collectionType)) - { - return null; - } - // Find movies with their own folders if (args.IsDirectory) { + if (IsInvalid(args.Parent, collectionType)) + { + return null; + } + var files = args.FileSystemChildren .Where(i => !LibraryManager.IgnoreFile(i, args.Parent)) .ToList(); @@ -251,8 +251,13 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies return null; } - // Owned items will be caught by the plain video resolver + // Handle owned items if (args.Parent == null) + { + return base.Resolve(args); + } + + if (IsInvalid(args.Parent, collectionType)) { return null; } @@ -528,6 +533,15 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies return returnVideo; } + private string[] ValidCollectionTypes = new[] + { + CollectionType.Movies, + CollectionType.HomeVideos, + CollectionType.MusicVideos, + CollectionType.Movies, + CollectionType.Photos + }; + private bool IsInvalid(Folder parent, string collectionType) { if (parent != null) @@ -538,21 +552,12 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies } } - var validCollectionTypes = new[] - { - CollectionType.Movies, - CollectionType.HomeVideos, - CollectionType.MusicVideos, - CollectionType.Movies, - CollectionType.Photos - }; - if (string.IsNullOrWhiteSpace(collectionType)) { return false; } - return !validCollectionTypes.Contains(collectionType, StringComparer.OrdinalIgnoreCase); + return !ValidCollectionTypes.Contains(collectionType, StringComparer.OrdinalIgnoreCase); } private IImageProcessor _imageProcessor; diff --git a/Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs index 5c7a528f54..030ff88f7d 100644 --- a/Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs @@ -5,36 +5,6 @@ using MediaBrowser.Model.IO; namespace Emby.Server.Implementations.Library.Resolvers { - /// - /// Resolves a Path into a Video - /// - public class VideoResolver : BaseVideoResolver