Fix extras folders

pull/7028/head
cvium 2 years ago
parent cd760943a9
commit 83a94aa612

@ -1,6 +1,7 @@
#pragma warning disable CA1819
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Emby.Naming.Video;
@ -475,6 +476,12 @@ namespace Emby.Naming.Common
"theme",
MediaType.Audio),
new ExtraRule(
ExtraType.ThemeSong,
ExtraRuleType.DirectoryName,
"theme-music",
MediaType.Audio),
new ExtraRule(
ExtraType.Scene,
ExtraRuleType.Suffix,
@ -569,7 +576,7 @@ namespace Emby.Naming.Common
ExtraType.Unknown,
ExtraRuleType.DirectoryName,
"extras",
MediaType.Video),
MediaType.Video)
};
Format3DRules = new[]
@ -681,9 +688,29 @@ namespace Emby.Naming.Common
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToArray();
AllExtrasTypesFolderNames = new Dictionary<string, ExtraType>(StringComparer.OrdinalIgnoreCase)
{
["trailers"] = ExtraType.Trailer,
["theme-music"] = ExtraType.ThemeSong,
["backdrops"] = ExtraType.ThemeVideo,
["extras"] = ExtraType.Unknown,
["behind the scenes"] = ExtraType.BehindTheScenes,
["deleted scenes"] = ExtraType.DeletedScene,
["interviews"] = ExtraType.Interview,
["scenes"] = ExtraType.Scene,
["samples"] = ExtraType.Sample,
["shorts"] = ExtraType.Clip,
["featurettes"] = ExtraType.Clip
};
Compile();
}
/// <summary>
/// Gets or sets the folder name to extra types mapping.
/// </summary>
public Dictionary<string, ExtraType> AllExtrasTypesFolderNames { get; set; }
/// <summary>
/// Gets or sets list of audio file extensions.
/// </summary>

@ -21,13 +21,8 @@ namespace Emby.Naming.Video
/// <param name="supportMultiVersion">Indication we should consider multi-versions of content.</param>
/// <param name="parseName">Whether to parse the name or use the filename.</param>
/// <returns>Returns enumerable of <see cref="VideoInfo"/> which groups files together when related.</returns>
public static IReadOnlyList<VideoInfo> Resolve(IEnumerable<FileSystemMetadata> files, NamingOptions namingOptions, bool supportMultiVersion = true, bool parseName = true)
public static IReadOnlyList<VideoInfo> Resolve(IReadOnlyList<VideoFileInfo> videoInfos, NamingOptions namingOptions, bool supportMultiVersion = true, bool parseName = true)
{
var videoInfos = files
.Select(i => VideoResolver.Resolve(i.FullName, i.IsDirectory, namingOptions, parseName))
.OfType<VideoFileInfo>()
.ToList();
// Filter out all extras, otherwise they could cause stacks to not be resolved
// See the unit test TestStackedWithTrailer
var nonExtras = videoInfos

@ -54,20 +54,10 @@ namespace Emby.Server.Implementations.Library
{
if (parent != null)
{
// Ignore trailer folders but allow it at the collection level
if (string.Equals(filename, BaseItem.TrailersFolderName, StringComparison.OrdinalIgnoreCase)
&& !(parent is AggregateFolder)
&& !(parent is UserRootFolder))
{
return true;
}
if (string.Equals(filename, BaseItem.ThemeVideosFolderName, StringComparison.OrdinalIgnoreCase))
{
return true;
}
if (string.Equals(filename, BaseItem.ThemeSongsFolderName, StringComparison.OrdinalIgnoreCase))
// Ignore extras folders but allow it at the collection level
if (_namingOptions.AllExtrasTypesFolderNames.ContainsKey(filename)
&& parent is not AggregateFolder
&& parent is not UserRootFolder)
{
return true;
}

@ -531,8 +531,8 @@ namespace Emby.Server.Implementations.Library
return key.GetMD5();
}
public BaseItem ResolvePath(FileSystemMetadata fileInfo, Folder parent = null)
=> ResolvePath(fileInfo, new DirectoryService(_fileSystem), null, parent);
public BaseItem ResolvePath(FileSystemMetadata fileInfo, Folder parent = null, IDirectoryService directoryService = null)
=> ResolvePath(fileInfo, directoryService ?? new DirectoryService(_fileSystem), null, parent);
private BaseItem ResolvePath(
FileSystemMetadata fileInfo,
@ -652,7 +652,7 @@ namespace Emby.Server.Implementations.Library
return !args.ContainsFileSystemEntryByName(".ignore");
}
public IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemMetadata> files, IDirectoryService directoryService, Folder parent, LibraryOptions libraryOptions, string collectionType)
public IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemMetadata> files, IDirectoryService directoryService, Folder parent, LibraryOptions libraryOptions, string collectionType = null)
{
return ResolvePaths(files, directoryService, parent, libraryOptions, collectionType, EntityResolvers);
}
@ -2683,7 +2683,7 @@ namespace Emby.Server.Implementations.Library
};
}
public IEnumerable<Video> FindExtras(BaseItem owner, List<FileSystemMetadata> fileSystemChildren)
public IEnumerable<BaseItem> FindExtras(BaseItem owner, List<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService)
{
var ownerVideoInfo = VideoResolver.Resolve(owner.Path, owner.IsFolder, _namingOptions);
if (ownerVideoInfo == null)
@ -2692,17 +2692,36 @@ namespace Emby.Server.Implementations.Library
}
var count = fileSystemChildren.Count;
var files = new List<FileSystemMetadata>();
var files = new List<VideoFileInfo>();
var nonVideoFiles = new List<FileSystemMetadata>();
for (var i = 0; i < count; i++)
{
var current = fileSystemChildren[i];
if (current.IsDirectory && BaseItem.AllExtrasTypesFolderNames.ContainsKey(current.Name))
if (current.IsDirectory && _namingOptions.AllExtrasTypesFolderNames.ContainsKey(current.Name))
{
files.AddRange(_fileSystem.GetFiles(current.FullName, _namingOptions.VideoFileExtensions, false, false));
var filesInSubFolder = _fileSystem.GetFiles(current.FullName, _namingOptions.VideoFileExtensions, false, false);
foreach (var file in filesInSubFolder)
{
var videoInfo = VideoResolver.Resolve(file.FullName, file.IsDirectory, _namingOptions);
if (videoInfo == null)
{
nonVideoFiles.Add(file);
continue;
}
files.Add(videoInfo);
}
}
else if (!current.IsDirectory)
{
files.Add(current);
var videoInfo = VideoResolver.Resolve(current.FullName, current.IsDirectory, _namingOptions);
if (videoInfo == null)
{
nonVideoFiles.Add(current);
continue;
}
files.Add(videoInfo);
}
}
@ -2714,11 +2733,10 @@ namespace Emby.Server.Implementations.Library
var videos = VideoListResolver.Resolve(files, _namingOptions);
// owner video info cannot be null as that implies it has no path
var extras = ExtraResolver.GetExtras(videos, ownerVideoInfo, _namingOptions.VideoFlagDelimiters);
for (var i = 0; i < extras.Count; i++)
{
var currentExtra = extras[i];
var resolved = ResolvePath(_fileSystem.GetFileInfo(currentExtra.Path));
var resolved = ResolvePath(_fileSystem.GetFileInfo(currentExtra.Path), null, directoryService);
if (resolved is not Video video)
{
continue;
@ -2735,6 +2753,35 @@ namespace Emby.Server.Implementations.Library
video.OwnerId = owner.Id;
yield return video;
}
// TODO: theme songs must be handled "manually" (but should we?) since they aren't video files
for (var i = 0; i < nonVideoFiles.Count; i++)
{
var current = nonVideoFiles[i];
var extraInfo = ExtraResolver.GetExtraInfo(current.FullName, _namingOptions);
if (extraInfo.ExtraType != ExtraType.ThemeSong)
{
continue;
}
var resolved = ResolvePath(current, null, directoryService);
if (resolved is not Audio themeSong)
{
continue;
}
// Try to retrieve it from the db. If we don't find it, use the resolved version
if (GetItemById(themeSong.Id) is Audio dbItem)
{
themeSong = dbItem;
}
themeSong.ExtraType = ExtraType.ThemeSong;
themeSong.OwnerId = owner.Id;
themeSong.ParentId = Guid.Empty;
yield return themeSong;
}
}
public string GetPathAfterNetworkSubstitution(string path, BaseItem ownerItem)

@ -261,7 +261,12 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
}
}
var resolverResult = VideoListResolver.Resolve(files, NamingOptions, supportMultiEditions, parseName);
var videoInfos = files
.Select(i => VideoResolver.Resolve(i.FullName, i.IsDirectory, NamingOptions, parseName))
.Where(f => f != null)
.ToList();
var resolverResult = VideoListResolver.Resolve(videoInfos, NamingOptions, supportMultiEditions, parseName);
var result = new MultiItemResolverResult
{

@ -13,7 +13,6 @@ using System.Threading.Tasks;
using Diacritics.Extensions;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Configuration;
@ -22,7 +21,6 @@ using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Globalization;
@ -42,11 +40,7 @@ namespace MediaBrowser.Controller.Entities
{
private BaseItemKind? _baseItemKind;
public const string TrailerFileName = "trailer";
public const string TrailersFolderName = "trailers";
public const string ThemeSongsFolderName = "theme-music";
public const string ThemeSongFileName = "theme";
public const string ThemeVideosFolderName = "backdrops";
/// <summary>
/// The supported image extensions.
@ -83,21 +77,6 @@ namespace MediaBrowser.Controller.Entities
Model.Entities.ExtraType.Scene
};
/// <summary>
/// The supported extra folder names and types. See <see cref="Emby.Naming.Common.NamingOptions" />.
/// </summary>
public static readonly Dictionary<string, ExtraType> AllExtrasTypesFolderNames = new Dictionary<string, ExtraType>(StringComparer.OrdinalIgnoreCase)
{
["extras"] = MediaBrowser.Model.Entities.ExtraType.Unknown,
["behind the scenes"] = MediaBrowser.Model.Entities.ExtraType.BehindTheScenes,
["deleted scenes"] = MediaBrowser.Model.Entities.ExtraType.DeletedScene,
["interviews"] = MediaBrowser.Model.Entities.ExtraType.Interview,
["scenes"] = MediaBrowser.Model.Entities.ExtraType.Scene,
["samples"] = MediaBrowser.Model.Entities.ExtraType.Sample,
["shorts"] = MediaBrowser.Model.Entities.ExtraType.Clip,
["featurettes"] = MediaBrowser.Model.Entities.ExtraType.Clip
};
private string _sortName;
private string _forcedSortName;
@ -1275,74 +1254,6 @@ namespace MediaBrowser.Controller.Entities
return string.Join('/', terms);
}
/// <summary>
/// Loads the theme songs.
/// </summary>
/// <returns>List{Audio.Audio}.</returns>
private static Audio.Audio[] LoadThemeSongs(List<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService)
{
var files = fileSystemChildren.Where(i => i.IsDirectory)
.Where(i => string.Equals(i.Name, ThemeSongsFolderName, StringComparison.OrdinalIgnoreCase))
.SelectMany(i => FileSystem.GetFiles(i.FullName))
.ToList();
// Support plex/xbmc convention
files.AddRange(fileSystemChildren
.Where(i => !i.IsDirectory && System.IO.Path.GetFileNameWithoutExtension(i.FullName.AsSpan()).Equals(ThemeSongFileName, StringComparison.OrdinalIgnoreCase)));
return LibraryManager.ResolvePaths(files, directoryService, null, new LibraryOptions())
.OfType<Audio.Audio>()
.Select(audio =>
{
// Try to retrieve it from the db. If we don't find it, use the resolved version
if (LibraryManager.GetItemById(audio.Id) is Audio.Audio dbItem)
{
audio = dbItem;
}
else
{
// item is new
audio.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeSong;
}
return audio;
// Sort them so that the list can be easily compared for changes
}).OrderBy(i => i.Path).ToArray();
}
/// <summary>
/// Loads the video backdrops.
/// </summary>
/// <returns>List{Video}.</returns>
private static Video[] LoadThemeVideos(IEnumerable<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService)
{
var files = fileSystemChildren.Where(i => i.IsDirectory)
.Where(i => string.Equals(i.Name, ThemeVideosFolderName, StringComparison.OrdinalIgnoreCase))
.SelectMany(i => FileSystem.GetFiles(i.FullName));
return LibraryManager.ResolvePaths(files, directoryService, null, new LibraryOptions())
.OfType<Video>()
.Select(item =>
{
// Try to retrieve it from the db. If we don't find it, use the resolved version
if (LibraryManager.GetItemById(item.Id) is Video dbItem)
{
item = dbItem;
}
else
{
// item is new
item.ExtraType = Model.Entities.ExtraType.ThemeVideo;
}
return item;
// Sort them so that the list can be easily compared for changes
}).OrderBy(i => i.Path).ToArray();
}
public Task RefreshMetadata(CancellationToken cancellationToken)
{
return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(FileSystem)), cancellationToken);
@ -1453,7 +1364,7 @@ namespace MediaBrowser.Controller.Entities
/// <returns><c>true</c> if any items have changed, else <c>false</c>.</returns>
protected virtual async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
if (!IsFileProtocol || !SupportsOwnedItems || IsInMixedFolder || this is ICollectionFolder || this.GetType() == typeof(Folder))
if (!IsFileProtocol || !SupportsOwnedItems || IsInMixedFolder || this is ICollectionFolder or UserRootFolder or AggregateFolder || this.GetType() == typeof(Folder))
{
return false;
}
@ -1470,7 +1381,7 @@ namespace MediaBrowser.Controller.Entities
private async Task<bool> RefreshExtras(BaseItem item, MetadataRefreshOptions options, List<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
var extras = LibraryManager.FindExtras(item, fileSystemChildren).ToArray();
var extras = LibraryManager.FindExtras(item, fileSystemChildren, options.DirectoryService).ToArray();
var newExtraIds = extras.Select(i => i.Id).ToArray();
var extrasChanged = !item.ExtraIds.SequenceEqual(newExtraIds);

@ -58,10 +58,12 @@ namespace MediaBrowser.Controller.Library
/// </summary>
/// <param name="fileInfo">The file information.</param>
/// <param name="parent">The parent.</param>
/// <param name="directoryService">An instance of <see cref="IDirectoryService"/>.</param>
/// <returns>BaseItem.</returns>
BaseItem ResolvePath(
FileSystemMetadata fileInfo,
Folder parent = null);
Folder parent = null,
IDirectoryService directoryService = null);
/// <summary>
/// Resolves a set of files into a list of BaseItem.
@ -430,10 +432,9 @@ namespace MediaBrowser.Controller.Library
/// </summary>
/// <param name="owner">The owner.</param>
/// <param name="fileSystemChildren">The file system children.</param>
/// <returns>IEnumerable&lt;Video&gt;.</returns>
IEnumerable<Video> FindExtras(
BaseItem owner,
List<FileSystemMetadata> fileSystemChildren);
/// <param name="directoryService">An instance of <see cref="IDirectoryService"/>.</param>
/// <returns>IEnumerable&lt;BaseItem&gt;.</returns>
IEnumerable<BaseItem> FindExtras(BaseItem owner, List<FileSystemMetadata> fileSystemChildren, IDirectoryService directoryService);
/// <summary>
/// Gets the collection folders.

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
@ -120,7 +121,7 @@ namespace MediaBrowser.LocalMetadata.Images
return directoryService.GetFileSystemEntries(path)
.Where(i =>
(includeDirectories && i.IsDirectory)
|| Array.FindIndex(BaseItem.SupportedImageExtensions, ext => string.Equals(ext, i.Extension, StringComparison.OrdinalIgnoreCase)) != -1)
|| BaseItem.SupportedImageExtensions.Contains(i.Extension, StringComparison.OrdinalIgnoreCase))
.OrderBy(i => Array.IndexOf(BaseItem.SupportedImageExtensions, i.Extension ?? string.Empty));
}

@ -23,11 +23,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Single(result.Where(v => v.ExtraType == null));
@ -46,11 +42,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Single(result.Where(v => v.ExtraType == null));
@ -68,11 +60,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Single(result);
@ -94,11 +82,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(7, result.Count);
@ -121,11 +105,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Single(result);
@ -149,11 +129,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(9, result.Count);
@ -173,11 +149,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(5, result.Count);
@ -199,11 +171,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(5, result.Count);
@ -226,11 +194,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Single(result);
@ -256,11 +220,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Single(result);
@ -280,11 +240,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(2, result.Count);
@ -305,11 +261,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(7, result.Count);
@ -331,11 +283,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(5, result.Count);
@ -352,11 +300,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Single(result);
@ -373,11 +317,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Single(result);
@ -394,11 +334,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Single(result);
@ -415,11 +351,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(2, result.Count);
@ -428,7 +360,7 @@ namespace Jellyfin.Naming.Tests.Video
[Fact]
public void TestEmptyList()
{
var result = VideoListResolver.Resolve(new List<FileSystemMetadata>(), _namingOptions).ToList();
var result = VideoListResolver.Resolve(new List<VideoFileInfo>(), _namingOptions).ToList();
Assert.Empty(result);
}

@ -42,11 +42,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(11, result.Count);
@ -80,11 +76,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Single(result);
@ -100,11 +92,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(2, result.Count);
@ -122,11 +110,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(2, result.Count);
@ -145,11 +129,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(3, result.Count);
@ -169,11 +149,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(3, result.Count);
@ -192,11 +168,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(2, result.Count);
@ -218,11 +190,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(5, result.Count);
@ -238,11 +206,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = true,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, true, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Single(result);
@ -259,11 +223,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = true,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, true, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(2, result.Count);
@ -281,11 +241,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(3, result.Count);
@ -306,11 +262,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(4, result.Count);
@ -332,11 +284,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(2, result.Count);
@ -351,11 +299,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Single(result);
@ -370,11 +314,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Single(result);
@ -390,11 +330,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Single(result);
@ -410,11 +346,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(2, result.Count);
@ -430,11 +362,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(2, result.Count);
@ -452,11 +380,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(2, result.Count);
@ -474,11 +398,7 @@ namespace Jellyfin.Naming.Tests.Video
};
var result = VideoListResolver.Resolve(
files.Select(i => new FileSystemMetadata
{
IsDirectory = false,
FullName = i
}).ToList(),
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
Assert.Equal(2, result.Count);

@ -5,11 +5,13 @@ using AutoFixture;
using AutoFixture.AutoMoq;
using Emby.Naming.Common;
using Emby.Server.Implementations.Library.Resolvers;
using Emby.Server.Implementations.Library.Resolvers.Audio;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Controller.Sorting;
using MediaBrowser.Model.Entities;
@ -22,6 +24,7 @@ namespace Jellyfin.Server.Implementations.Tests.Library.LibraryManager;
public class FindExtrasTests
{
private readonly Emby.Server.Implementations.Library.LibraryManager _libraryManager;
private readonly Mock<IFileSystem> _fileSystemMock;
public FindExtrasTests()
{
@ -29,11 +32,11 @@ public class FindExtrasTests
fixture.Register(() => new NamingOptions());
var configMock = fixture.Freeze<Mock<IServerConfigurationManager>>();
configMock.Setup(c => c.ApplicationPaths.ProgramDataPath).Returns("/data");
var fileSystemMock = fixture.Freeze<Mock<IFileSystem>>();
fileSystemMock.Setup(f => f.GetFileInfo(It.IsAny<string>())).Returns<string>(path => new FileSystemMetadata { FullName = path });
_fileSystemMock = fixture.Freeze<Mock<IFileSystem>>();
_fileSystemMock.Setup(f => f.GetFileInfo(It.IsAny<string>())).Returns<string>(path => new FileSystemMetadata { FullName = path });
_libraryManager = fixture.Build<Emby.Server.Implementations.Library.LibraryManager>().Do(s => s.AddParts(
fixture.Create<IEnumerable<IResolverIgnoreRule>>(),
new List<IItemResolver> { new GenericVideoResolver<Video>(fixture.Create<NamingOptions>()) },
new List<IItemResolver> { new GenericVideoResolver<Video>(fixture.Create<NamingOptions>()), new AudioResolver(fixture.Create<NamingOptions>()) },
fixture.Create<IEnumerable<IIntroProvider>>(),
fixture.Create<IEnumerable<IBaseItemComparer>>(),
fixture.Create<IEnumerable<ILibraryPostScanTask>>()))
@ -62,7 +65,7 @@ public class FindExtrasTests
IsDirectory = false
}).ToList();
var extras = _libraryManager.FindExtras(owner, files).OrderBy(e => e.ExtraType).ToList();
var extras = _libraryManager.FindExtras(owner, files, new DirectoryService(_fileSystemMock.Object)).OrderBy(e => e.ExtraType).ToList();
Assert.Equal(2, extras.Count);
Assert.Equal(ExtraType.Trailer, extras[0].ExtraType);
@ -77,26 +80,77 @@ public class FindExtrasTests
{
"/movies/Up/Up.mkv",
"/movies/Up/Up - trailer.mkv",
"/movies/Up/trailers/some trailer.mkv",
"/movies/Up/behind the scenes/the making of Up.mkv",
"/movies/Up/trailers",
"/movies/Up/theme-music",
"/movies/Up/theme.mp3",
"/movies/Up/not a theme.mp3",
"/movies/Up/behind the scenes",
"/movies/Up/behind the scenes.mkv",
"/movies/Up/Up - sample.mkv",
"/movies/Up/Up something else.mkv"
};
_fileSystemMock.Setup(f => f.GetFiles(
"/movies/Up/trailers",
It.IsAny<string[]>(),
false,
false))
.Returns(new List<FileSystemMetadata>
{
new ()
{
FullName = "/movies/Up/trailers/some trailer.mkv",
Name = "some trailer.mkv",
IsDirectory = false
}
});
_fileSystemMock.Setup(f => f.GetFiles(
"/movies/Up/behind the scenes",
It.IsAny<string[]>(),
false,
false))
.Returns(new List<FileSystemMetadata>
{
new ()
{
FullName = "/movies/Up/behind the scenes/the making of Up.mkv",
Name = "the making of Up.mkv",
IsDirectory = false
}
});
_fileSystemMock.Setup(f => f.GetFiles(
"/movies/Up/theme-music",
It.IsAny<string[]>(),
false,
false))
.Returns(new List<FileSystemMetadata>
{
new ()
{
FullName = "/movies/Up/theme-music/theme2.mp3",
Name = "theme2.mp3",
IsDirectory = false
}
});
var files = paths.Select(p => new FileSystemMetadata
{
FullName = p,
IsDirectory = false
Name = Path.GetFileName(p),
IsDirectory = string.IsNullOrEmpty(Path.GetExtension(p))
}).ToList();
var extras = _libraryManager.FindExtras(owner, files).OrderBy(e => e.ExtraType).ToList();
var extras = _libraryManager.FindExtras(owner, files, new DirectoryService(_fileSystemMock.Object)).OrderBy(e => e.ExtraType).ToList();
Assert.Equal(4, extras.Count);
Assert.Equal(6, extras.Count);
Assert.Equal(ExtraType.Trailer, extras[0].ExtraType);
Assert.Equal(ExtraType.Trailer, extras[1].ExtraType);
Assert.Equal(ExtraType.BehindTheScenes, extras[2].ExtraType);
Assert.Equal(ExtraType.Sample, extras[3].ExtraType);
Assert.Equal(ExtraType.ThemeSong, extras[4].ExtraType);
Assert.Equal(ExtraType.ThemeSong, extras[5].ExtraType);
}
[Fact]
@ -116,7 +170,7 @@ public class FindExtrasTests
IsDirectory = false
}).ToList();
var extras = _libraryManager.FindExtras(owner, files).OrderBy(e => e.ExtraType).ToList();
var extras = _libraryManager.FindExtras(owner, files, new DirectoryService(_fileSystemMock.Object)).OrderBy(e => e.ExtraType).ToList();
Assert.Single(extras);
Assert.Equal(ExtraType.Trailer, extras[0].ExtraType);
@ -142,7 +196,7 @@ public class FindExtrasTests
IsDirectory = false
}).ToList();
var extras = _libraryManager.FindExtras(owner, files).OrderBy(e => e.ExtraType).ToList();
var extras = _libraryManager.FindExtras(owner, files, new DirectoryService(_fileSystemMock.Object)).OrderBy(e => e.ExtraType).ToList();
Assert.Single(extras);
Assert.Equal(ExtraType.Trailer, extras[0].ExtraType);
@ -167,7 +221,7 @@ public class FindExtrasTests
IsDirectory = string.IsNullOrEmpty(Path.GetExtension(p))
}).ToList();
var extras = _libraryManager.FindExtras(owner, files).OrderBy(e => e.ExtraType).ToList();
var extras = _libraryManager.FindExtras(owner, files, new DirectoryService(_fileSystemMock.Object)).OrderBy(e => e.ExtraType).ToList();
Assert.Equal(2, extras.Count);
Assert.Equal(ExtraType.Trailer, extras[0].ExtraType);

Loading…
Cancel
Save