Convert CollectionType, SpecialFolderType to enum (#9764)

* Convert CollectionType, SpecialFolderType to enum

* Hide internal enum CollectionType values

* Apply suggestions from code review

Co-authored-by: Shadowghost <Shadowghost@users.noreply.github.com>

* Fix recent change

* Update Jellyfin.Data/Attributes/OpenApiIgnoreEnumAttribute.cs

Co-authored-by: Patrick Barron <barronpm@gmail.com>

---------

Co-authored-by: Shadowghost <Shadowghost@users.noreply.github.com>
Co-authored-by: Patrick Barron <barronpm@gmail.com>
pull/10557/head
Cody Robibero 6 months ago committed by GitHub
parent c7a94d48ae
commit 906f701fa8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -565,30 +565,18 @@ namespace Emby.Dlna.ContentDirectory
if (stubType != StubType.Folder && item is IHasCollectionType collectionFolder) if (stubType != StubType.Folder && item is IHasCollectionType collectionFolder)
{ {
var collectionType = collectionFolder.CollectionType; switch (collectionFolder.CollectionType)
if (string.Equals(CollectionType.Music, collectionType, StringComparison.OrdinalIgnoreCase))
{ {
return GetMusicFolders(item, user, stubType, sort, startIndex, limit); case CollectionType.Music:
} return GetMusicFolders(item, user, stubType, sort, startIndex, limit);
case CollectionType.Movies:
if (string.Equals(CollectionType.Movies, collectionType, StringComparison.OrdinalIgnoreCase)) return GetMovieFolders(item, user, stubType, sort, startIndex, limit);
{ case CollectionType.TvShows:
return GetMovieFolders(item, user, stubType, sort, startIndex, limit); return GetTvFolders(item, user, stubType, sort, startIndex, limit);
} case CollectionType.Folders:
return GetFolders(user, startIndex, limit);
if (string.Equals(CollectionType.TvShows, collectionType, StringComparison.OrdinalIgnoreCase)) case CollectionType.LiveTv:
{ return GetLiveTvChannels(user, sort, startIndex, limit);
return GetTvFolders(item, user, stubType, sort, startIndex, limit);
}
if (string.Equals(CollectionType.Folders, collectionType, StringComparison.OrdinalIgnoreCase))
{
return GetFolders(user, startIndex, limit);
}
if (string.Equals(CollectionType.LiveTv, collectionType, StringComparison.OrdinalIgnoreCase))
{
return GetLiveTvChannels(user, sort, startIndex, limit);
} }
} }

@ -30,47 +30,43 @@ namespace Emby.Server.Implementations.Images
BaseItemKind[] includeItemTypes; BaseItemKind[] includeItemTypes;
if (string.Equals(viewType, CollectionType.Movies, StringComparison.Ordinal)) switch (viewType)
{ {
includeItemTypes = new[] { BaseItemKind.Movie }; case CollectionType.Movies:
} includeItemTypes = new[] { BaseItemKind.Movie };
else if (string.Equals(viewType, CollectionType.TvShows, StringComparison.Ordinal)) break;
{ case CollectionType.TvShows:
includeItemTypes = new[] { BaseItemKind.Series }; includeItemTypes = new[] { BaseItemKind.Series };
} break;
else if (string.Equals(viewType, CollectionType.Music, StringComparison.Ordinal)) case CollectionType.Music:
{ includeItemTypes = new[] { BaseItemKind.MusicAlbum };
includeItemTypes = new[] { BaseItemKind.MusicAlbum }; break;
} case CollectionType.MusicVideos:
else if (string.Equals(viewType, CollectionType.MusicVideos, StringComparison.Ordinal)) includeItemTypes = new[] { BaseItemKind.MusicVideo };
{ break;
includeItemTypes = new[] { BaseItemKind.MusicVideo }; case CollectionType.Books:
} includeItemTypes = new[] { BaseItemKind.Book, BaseItemKind.AudioBook };
else if (string.Equals(viewType, CollectionType.Books, StringComparison.Ordinal)) break;
{ case CollectionType.BoxSets:
includeItemTypes = new[] { BaseItemKind.Book, BaseItemKind.AudioBook }; includeItemTypes = new[] { BaseItemKind.BoxSet };
} break;
else if (string.Equals(viewType, CollectionType.BoxSets, StringComparison.Ordinal)) case CollectionType.HomeVideos:
{ case CollectionType.Photos:
includeItemTypes = new[] { BaseItemKind.BoxSet }; includeItemTypes = new[] { BaseItemKind.Video, BaseItemKind.Photo };
} break;
else if (string.Equals(viewType, CollectionType.HomeVideos, StringComparison.Ordinal) || string.Equals(viewType, CollectionType.Photos, StringComparison.Ordinal)) default:
{ includeItemTypes = new[] { BaseItemKind.Video, BaseItemKind.Audio, BaseItemKind.Photo, BaseItemKind.Movie, BaseItemKind.Series };
includeItemTypes = new[] { BaseItemKind.Video, BaseItemKind.Photo }; break;
}
else
{
includeItemTypes = new[] { BaseItemKind.Video, BaseItemKind.Audio, BaseItemKind.Photo, BaseItemKind.Movie, BaseItemKind.Series };
} }
var recursive = !string.Equals(CollectionType.Playlists, viewType, StringComparison.OrdinalIgnoreCase); var recursive = viewType != CollectionType.Playlists;
return view.GetItemList(new InternalItemsQuery return view.GetItemList(new InternalItemsQuery
{ {
CollapseBoxSetItems = false, CollapseBoxSetItems = false,
Recursive = recursive, Recursive = recursive,
DtoOptions = new DtoOptions(false), DtoOptions = new DtoOptions(false),
ImageTypes = new ImageType[] { ImageType.Primary }, ImageTypes = new[] { ImageType.Primary },
Limit = 8, Limit = 8,
OrderBy = new[] OrderBy = new[]
{ {

@ -36,7 +36,7 @@ namespace Emby.Server.Implementations.Images
var view = (UserView)item; var view = (UserView)item;
var isUsingCollectionStrip = IsUsingCollectionStrip(view); var isUsingCollectionStrip = IsUsingCollectionStrip(view);
var recursive = isUsingCollectionStrip && !new[] { CollectionType.BoxSets, CollectionType.Playlists }.Contains(view.ViewType ?? string.Empty, StringComparison.OrdinalIgnoreCase); var recursive = isUsingCollectionStrip && view?.ViewType is not null && view.ViewType != CollectionType.BoxSets && view.ViewType != CollectionType.Playlists;
var result = view.GetItemList(new InternalItemsQuery var result = view.GetItemList(new InternalItemsQuery
{ {
@ -112,14 +112,14 @@ namespace Emby.Server.Implementations.Images
private static bool IsUsingCollectionStrip(UserView view) private static bool IsUsingCollectionStrip(UserView view)
{ {
string[] collectionStripViewTypes = CollectionType[] collectionStripViewTypes =
{ {
CollectionType.Movies, CollectionType.Movies,
CollectionType.TvShows, CollectionType.TvShows,
CollectionType.Playlists CollectionType.Playlists
}; };
return collectionStripViewTypes.Contains(view.ViewType ?? string.Empty); return view?.ViewType is not null && collectionStripViewTypes.Contains(view.ViewType.Value);
} }
protected override string CreateImage(BaseItem item, IReadOnlyCollection<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) protected override string CreateImage(BaseItem item, IReadOnlyCollection<BaseItem> itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex)

@ -525,14 +525,14 @@ namespace Emby.Server.Implementations.Library
IDirectoryService directoryService, IDirectoryService directoryService,
IItemResolver[] resolvers, IItemResolver[] resolvers,
Folder parent = null, Folder parent = null,
string collectionType = null, CollectionType? collectionType = null,
LibraryOptions libraryOptions = null) LibraryOptions libraryOptions = null)
{ {
ArgumentNullException.ThrowIfNull(fileInfo); ArgumentNullException.ThrowIfNull(fileInfo);
var fullPath = fileInfo.FullName; var fullPath = fileInfo.FullName;
if (string.IsNullOrEmpty(collectionType) && parent is not null) if (collectionType is null && parent is not null)
{ {
collectionType = GetContentTypeOverride(fullPath, true); collectionType = GetContentTypeOverride(fullPath, true);
} }
@ -635,7 +635,7 @@ namespace Emby.Server.Implementations.Library
return !args.ContainsFileSystemEntryByName(".ignore"); return !args.ContainsFileSystemEntryByName(".ignore");
} }
public IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemMetadata> files, IDirectoryService directoryService, Folder parent, LibraryOptions libraryOptions, string collectionType = null) public IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemMetadata> files, IDirectoryService directoryService, Folder parent, LibraryOptions libraryOptions, CollectionType? collectionType = null)
{ {
return ResolvePaths(files, directoryService, parent, libraryOptions, collectionType, EntityResolvers); return ResolvePaths(files, directoryService, parent, libraryOptions, collectionType, EntityResolvers);
} }
@ -645,7 +645,7 @@ namespace Emby.Server.Implementations.Library
IDirectoryService directoryService, IDirectoryService directoryService,
Folder parent, Folder parent,
LibraryOptions libraryOptions, LibraryOptions libraryOptions,
string collectionType, CollectionType? collectionType,
IItemResolver[] resolvers) IItemResolver[] resolvers)
{ {
var fileList = files.Where(i => !IgnoreFile(i, parent)).ToList(); var fileList = files.Where(i => !IgnoreFile(i, parent)).ToList();
@ -675,7 +675,7 @@ namespace Emby.Server.Implementations.Library
IReadOnlyList<FileSystemMetadata> fileList, IReadOnlyList<FileSystemMetadata> fileList,
IDirectoryService directoryService, IDirectoryService directoryService,
Folder parent, Folder parent,
string collectionType, CollectionType? collectionType,
IItemResolver[] resolvers, IItemResolver[] resolvers,
LibraryOptions libraryOptions) LibraryOptions libraryOptions)
{ {
@ -1514,7 +1514,7 @@ namespace Emby.Server.Implementations.Library
{ {
if (item is UserView view) if (item is UserView view)
{ {
if (string.Equals(view.ViewType, CollectionType.LiveTv, StringComparison.Ordinal)) if (view.ViewType == CollectionType.LiveTv)
{ {
return new[] { view.Id }; return new[] { view.Id };
} }
@ -1543,13 +1543,13 @@ namespace Emby.Server.Implementations.Library
} }
// Handle grouping // Handle grouping
if (user is not null && !string.IsNullOrEmpty(view.ViewType) && UserView.IsEligibleForGrouping(view.ViewType) if (user is not null && view.ViewType != CollectionType.Unknown && UserView.IsEligibleForGrouping(view.ViewType)
&& user.GetPreference(PreferenceKind.GroupedFolders).Length > 0) && user.GetPreference(PreferenceKind.GroupedFolders).Length > 0)
{ {
return GetUserRootFolder() return GetUserRootFolder()
.GetChildren(user, true) .GetChildren(user, true)
.OfType<CollectionFolder>() .OfType<CollectionFolder>()
.Where(i => string.IsNullOrEmpty(i.CollectionType) || string.Equals(i.CollectionType, view.ViewType, StringComparison.OrdinalIgnoreCase)) .Where(i => i.CollectionType is null || i.CollectionType == view.ViewType)
.Where(i => user.IsFolderGrouped(i.Id)) .Where(i => user.IsFolderGrouped(i.Id))
.SelectMany(i => GetTopParentIdsForQuery(i, user)); .SelectMany(i => GetTopParentIdsForQuery(i, user));
} }
@ -2065,16 +2065,16 @@ namespace Emby.Server.Implementations.Library
: collectionFolder.GetLibraryOptions(); : collectionFolder.GetLibraryOptions();
} }
public string GetContentType(BaseItem item) public CollectionType? GetContentType(BaseItem item)
{ {
string configuredContentType = GetConfiguredContentType(item, false); var configuredContentType = GetConfiguredContentType(item, false);
if (!string.IsNullOrEmpty(configuredContentType)) if (configuredContentType is not null)
{ {
return configuredContentType; return configuredContentType;
} }
configuredContentType = GetConfiguredContentType(item, true); configuredContentType = GetConfiguredContentType(item, true);
if (!string.IsNullOrEmpty(configuredContentType)) if (configuredContentType is not null)
{ {
return configuredContentType; return configuredContentType;
} }
@ -2082,31 +2082,31 @@ namespace Emby.Server.Implementations.Library
return GetInheritedContentType(item); return GetInheritedContentType(item);
} }
public string GetInheritedContentType(BaseItem item) public CollectionType? GetInheritedContentType(BaseItem item)
{ {
var type = GetTopFolderContentType(item); var type = GetTopFolderContentType(item);
if (!string.IsNullOrEmpty(type)) if (type is not null)
{ {
return type; return type;
} }
return item.GetParents() return item.GetParents()
.Select(GetConfiguredContentType) .Select(GetConfiguredContentType)
.LastOrDefault(i => !string.IsNullOrEmpty(i)); .LastOrDefault(i => i is not null);
} }
public string GetConfiguredContentType(BaseItem item) public CollectionType? GetConfiguredContentType(BaseItem item)
{ {
return GetConfiguredContentType(item, false); return GetConfiguredContentType(item, false);
} }
public string GetConfiguredContentType(string path) public CollectionType? GetConfiguredContentType(string path)
{ {
return GetContentTypeOverride(path, false); return GetContentTypeOverride(path, false);
} }
public string GetConfiguredContentType(BaseItem item, bool inheritConfiguredPath) public CollectionType? GetConfiguredContentType(BaseItem item, bool inheritConfiguredPath)
{ {
if (item is ICollectionFolder collectionFolder) if (item is ICollectionFolder collectionFolder)
{ {
@ -2116,16 +2116,21 @@ namespace Emby.Server.Implementations.Library
return GetContentTypeOverride(item.ContainingFolderPath, inheritConfiguredPath); return GetContentTypeOverride(item.ContainingFolderPath, inheritConfiguredPath);
} }
private string GetContentTypeOverride(string path, bool inherit) private CollectionType? GetContentTypeOverride(string path, bool inherit)
{ {
var nameValuePair = _configurationManager.Configuration.ContentTypes var nameValuePair = _configurationManager.Configuration.ContentTypes
.FirstOrDefault(i => _fileSystem.AreEqual(i.Name, path) .FirstOrDefault(i => _fileSystem.AreEqual(i.Name, path)
|| (inherit && !string.IsNullOrEmpty(i.Name) || (inherit && !string.IsNullOrEmpty(i.Name)
&& _fileSystem.ContainsSubPath(i.Name, path))); && _fileSystem.ContainsSubPath(i.Name, path)));
return nameValuePair?.Value; if (Enum.TryParse<CollectionType>(nameValuePair?.Value, out var collectionType))
{
return collectionType;
}
return null;
} }
private string GetTopFolderContentType(BaseItem item) private CollectionType? GetTopFolderContentType(BaseItem item)
{ {
if (item is null) if (item is null)
{ {
@ -2147,13 +2152,13 @@ namespace Emby.Server.Implementations.Library
.OfType<ICollectionFolder>() .OfType<ICollectionFolder>()
.Where(i => string.Equals(i.Path, item.Path, StringComparison.OrdinalIgnoreCase) || i.PhysicalLocations.Contains(item.Path)) .Where(i => string.Equals(i.Path, item.Path, StringComparison.OrdinalIgnoreCase) || i.PhysicalLocations.Contains(item.Path))
.Select(i => i.CollectionType) .Select(i => i.CollectionType)
.FirstOrDefault(i => !string.IsNullOrEmpty(i)); .FirstOrDefault(i => i is not null);
} }
public UserView GetNamedView( public UserView GetNamedView(
User user, User user,
string name, string name,
string viewType, CollectionType? viewType,
string sortName) string sortName)
{ {
return GetNamedView(user, name, Guid.Empty, viewType, sortName); return GetNamedView(user, name, Guid.Empty, viewType, sortName);
@ -2161,13 +2166,13 @@ namespace Emby.Server.Implementations.Library
public UserView GetNamedView( public UserView GetNamedView(
string name, string name,
string viewType, CollectionType viewType,
string sortName) string sortName)
{ {
var path = Path.Combine( var path = Path.Combine(
_configurationManager.ApplicationPaths.InternalMetadataPath, _configurationManager.ApplicationPaths.InternalMetadataPath,
"views", "views",
_fileSystem.GetValidFilename(viewType)); _fileSystem.GetValidFilename(viewType.ToString()));
var id = GetNewItemId(path + "_namedview_" + name, typeof(UserView)); var id = GetNewItemId(path + "_namedview_" + name, typeof(UserView));
@ -2207,13 +2212,13 @@ namespace Emby.Server.Implementations.Library
User user, User user,
string name, string name,
Guid parentId, Guid parentId,
string viewType, CollectionType? viewType,
string sortName) string sortName)
{ {
var parentIdString = parentId.Equals(default) var parentIdString = parentId.Equals(default)
? null ? null
: parentId.ToString("N", CultureInfo.InvariantCulture); : parentId.ToString("N", CultureInfo.InvariantCulture);
var idValues = "38_namedview_" + name + user.Id.ToString("N", CultureInfo.InvariantCulture) + (parentIdString ?? string.Empty) + (viewType ?? string.Empty); var idValues = "38_namedview_" + name + user.Id.ToString("N", CultureInfo.InvariantCulture) + (parentIdString ?? string.Empty) + (viewType?.ToString() ?? string.Empty);
var id = GetNewItemId(idValues, typeof(UserView)); var id = GetNewItemId(idValues, typeof(UserView));
@ -2269,7 +2274,7 @@ namespace Emby.Server.Implementations.Library
public UserView GetShadowView( public UserView GetShadowView(
BaseItem parent, BaseItem parent,
string viewType, CollectionType? viewType,
string sortName) string sortName)
{ {
ArgumentNullException.ThrowIfNull(parent); ArgumentNullException.ThrowIfNull(parent);
@ -2277,7 +2282,7 @@ namespace Emby.Server.Implementations.Library
var name = parent.Name; var name = parent.Name;
var parentId = parent.Id; var parentId = parent.Id;
var idValues = "38_namedview_" + name + parentId + (viewType ?? string.Empty); var idValues = "38_namedview_" + name + parentId + (viewType?.ToString() ?? string.Empty);
var id = GetNewItemId(idValues, typeof(UserView)); var id = GetNewItemId(idValues, typeof(UserView));
@ -2334,7 +2339,7 @@ namespace Emby.Server.Implementations.Library
public UserView GetNamedView( public UserView GetNamedView(
string name, string name,
Guid parentId, Guid parentId,
string viewType, CollectionType? viewType,
string sortName, string sortName,
string uniqueId) string uniqueId)
{ {
@ -2343,7 +2348,7 @@ namespace Emby.Server.Implementations.Library
var parentIdString = parentId.Equals(default) var parentIdString = parentId.Equals(default)
? null ? null
: parentId.ToString("N", CultureInfo.InvariantCulture); : parentId.ToString("N", CultureInfo.InvariantCulture);
var idValues = "37_namedview_" + name + (parentIdString ?? string.Empty) + (viewType ?? string.Empty); var idValues = "37_namedview_" + name + (parentIdString ?? string.Empty) + (viewType?.ToString() ?? string.Empty);
if (!string.IsNullOrEmpty(uniqueId)) if (!string.IsNullOrEmpty(uniqueId))
{ {
idValues += uniqueId; idValues += uniqueId;
@ -2378,7 +2383,7 @@ namespace Emby.Server.Implementations.Library
isNew = true; isNew = true;
} }
if (!string.Equals(viewType, item.ViewType, StringComparison.OrdinalIgnoreCase)) if (viewType != item.ViewType)
{ {
item.ViewType = viewType; item.ViewType = viewType;
item.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).GetAwaiter().GetResult(); item.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).GetAwaiter().GetResult();

@ -10,11 +10,11 @@ using Emby.Naming.Audio;
using Emby.Naming.AudioBook; using Emby.Naming.AudioBook;
using Emby.Naming.Common; using Emby.Naming.Common;
using Emby.Naming.Video; using Emby.Naming.Video;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers; using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
namespace Emby.Server.Implementations.Library.Resolvers.Audio namespace Emby.Server.Implementations.Library.Resolvers.Audio
@ -40,7 +40,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
public MultiItemResolverResult ResolveMultiple( public MultiItemResolverResult ResolveMultiple(
Folder parent, Folder parent,
List<FileSystemMetadata> files, List<FileSystemMetadata> files,
string collectionType, CollectionType? collectionType,
IDirectoryService directoryService) IDirectoryService directoryService)
{ {
var result = ResolveMultipleInternal(parent, files, collectionType); var result = ResolveMultipleInternal(parent, files, collectionType);
@ -59,9 +59,9 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
private MultiItemResolverResult ResolveMultipleInternal( private MultiItemResolverResult ResolveMultipleInternal(
Folder parent, Folder parent,
List<FileSystemMetadata> files, List<FileSystemMetadata> files,
string collectionType) CollectionType? collectionType)
{ {
if (string.Equals(collectionType, CollectionType.Books, StringComparison.OrdinalIgnoreCase)) if (collectionType == CollectionType.Books)
{ {
return ResolveMultipleAudio(parent, files, true); return ResolveMultipleAudio(parent, files, true);
} }
@ -80,7 +80,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
var collectionType = args.GetCollectionType(); var collectionType = args.GetCollectionType();
var isBooksCollectionType = string.Equals(collectionType, CollectionType.Books, StringComparison.OrdinalIgnoreCase); var isBooksCollectionType = collectionType == CollectionType.Books;
if (args.IsDirectory) if (args.IsDirectory)
{ {
@ -102,7 +102,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
return null; return null;
} }
var isMixedCollectionType = string.IsNullOrEmpty(collectionType); var isMixedCollectionType = collectionType is null;
// For conflicting extensions, give priority to videos // For conflicting extensions, give priority to videos
if (isMixedCollectionType && VideoResolver.IsVideoFile(args.Path, _namingOptions)) if (isMixedCollectionType && VideoResolver.IsVideoFile(args.Path, _namingOptions))
@ -112,7 +112,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
MediaBrowser.Controller.Entities.Audio.Audio item = null; MediaBrowser.Controller.Entities.Audio.Audio item = null;
var isMusicCollectionType = string.Equals(collectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase); var isMusicCollectionType = collectionType == CollectionType.Music;
// Use regular audio type for mixed libraries, owned items and music // Use regular audio type for mixed libraries, owned items and music
if (isMixedCollectionType || if (isMixedCollectionType ||

@ -8,6 +8,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Emby.Naming.Audio; using Emby.Naming.Audio;
using Emby.Naming.Common; using Emby.Naming.Common;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Providers;
@ -54,7 +55,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
protected override MusicAlbum Resolve(ItemResolveArgs args) protected override MusicAlbum Resolve(ItemResolveArgs args)
{ {
var collectionType = args.GetCollectionType(); var collectionType = args.GetCollectionType();
var isMusicMediaFolder = string.Equals(collectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase); var isMusicMediaFolder = collectionType == CollectionType.Music;
// If there's a collection type and it's not music, don't allow it. // If there's a collection type and it's not music, don't allow it.
if (!isMusicMediaFolder) if (!isMusicMediaFolder)

@ -4,6 +4,7 @@ using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Emby.Naming.Common; using Emby.Naming.Common;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Providers;
@ -64,7 +65,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
var collectionType = args.GetCollectionType(); var collectionType = args.GetCollectionType();
var isMusicMediaFolder = string.Equals(collectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase); var isMusicMediaFolder = collectionType == CollectionType.Music;
// If there's a collection type and it's not music, it can't be a music artist // If there's a collection type and it's not music, it can't be a music artist
if (!isMusicMediaFolder) if (!isMusicMediaFolder)

@ -5,6 +5,7 @@
using System; using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Jellyfin.Data.Enums;
using Jellyfin.Extensions; using Jellyfin.Extensions;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
@ -22,7 +23,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Books
var collectionType = args.GetCollectionType(); var collectionType = args.GetCollectionType();
// Only process items that are in a collection folder containing books // Only process items that are in a collection folder containing books
if (!string.Equals(collectionType, CollectionType.Books, StringComparison.OrdinalIgnoreCase)) if (collectionType != CollectionType.Books)
{ {
return null; return null;
} }

@ -7,6 +7,7 @@ using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Emby.Naming.Common; using Emby.Naming.Common;
using Emby.Naming.Video; using Emby.Naming.Video;
using Jellyfin.Data.Enums;
using Jellyfin.Extensions; using Jellyfin.Extensions;
using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
@ -28,13 +29,13 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
{ {
private readonly IImageProcessor _imageProcessor; private readonly IImageProcessor _imageProcessor;
private string[] _validCollectionTypes = new[] private static readonly CollectionType[] _validCollectionTypes = new[]
{ {
CollectionType.Movies, CollectionType.Movies,
CollectionType.HomeVideos, CollectionType.HomeVideos,
CollectionType.MusicVideos, CollectionType.MusicVideos,
CollectionType.TvShows, CollectionType.TvShows,
CollectionType.Photos CollectionType.Photos
}; };
/// <summary> /// <summary>
@ -63,7 +64,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
public MultiItemResolverResult ResolveMultiple( public MultiItemResolverResult ResolveMultiple(
Folder parent, Folder parent,
List<FileSystemMetadata> files, List<FileSystemMetadata> files,
string collectionType, CollectionType? collectionType,
IDirectoryService directoryService) IDirectoryService directoryService)
{ {
var result = ResolveMultipleInternal(parent, files, collectionType); var result = ResolveMultipleInternal(parent, files, collectionType);
@ -99,17 +100,17 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
Video movie = null; Video movie = null;
var files = args.GetActualFileSystemChildren().ToList(); var files = args.GetActualFileSystemChildren().ToList();
if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase)) if (collectionType == CollectionType.MusicVideos)
{ {
movie = FindMovie<MusicVideo>(args, args.Path, args.Parent, files, DirectoryService, collectionType, false); movie = FindMovie<MusicVideo>(args, args.Path, args.Parent, files, DirectoryService, collectionType, false);
} }
if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase)) if (collectionType == CollectionType.HomeVideos)
{ {
movie = FindMovie<Video>(args, args.Path, args.Parent, files, DirectoryService, collectionType, false); movie = FindMovie<Video>(args, args.Path, args.Parent, files, DirectoryService, collectionType, false);
} }
if (string.IsNullOrEmpty(collectionType)) if (collectionType is null)
{ {
// Owned items will be caught by the video extra resolver // Owned items will be caught by the video extra resolver
if (args.Parent is null) if (args.Parent is null)
@ -125,7 +126,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
movie = FindMovie<Movie>(args, args.Path, args.Parent, files, DirectoryService, collectionType, true); movie = FindMovie<Movie>(args, args.Path, args.Parent, files, DirectoryService, collectionType, true);
} }
if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase)) if (collectionType == CollectionType.Movies)
{ {
movie = FindMovie<Movie>(args, args.Path, args.Parent, files, DirectoryService, collectionType, true); movie = FindMovie<Movie>(args, args.Path, args.Parent, files, DirectoryService, collectionType, true);
} }
@ -146,22 +147,21 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
Video item = null; Video item = null;
if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase)) if (collectionType == CollectionType.MusicVideos)
{ {
item = ResolveVideo<MusicVideo>(args, false); item = ResolveVideo<MusicVideo>(args, false);
} }
// To find a movie file, the collection type must be movies or boxsets // To find a movie file, the collection type must be movies or boxsets
else if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase)) else if (collectionType == CollectionType.Movies)
{ {
item = ResolveVideo<Movie>(args, true); item = ResolveVideo<Movie>(args, true);
} }
else if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase) || else if (collectionType == CollectionType.HomeVideos || collectionType == CollectionType.Photos)
string.Equals(collectionType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase))
{ {
item = ResolveVideo<Video>(args, false); item = ResolveVideo<Video>(args, false);
} }
else if (string.IsNullOrEmpty(collectionType)) else if (collectionType is null)
{ {
if (args.HasParent<Series>()) if (args.HasParent<Series>())
{ {
@ -188,25 +188,24 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
private MultiItemResolverResult ResolveMultipleInternal( private MultiItemResolverResult ResolveMultipleInternal(
Folder parent, Folder parent,
List<FileSystemMetadata> files, List<FileSystemMetadata> files,
string collectionType) CollectionType? collectionType)
{ {
if (IsInvalid(parent, collectionType)) if (IsInvalid(parent, collectionType))
{ {
return null; return null;
} }
if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase)) if (collectionType is CollectionType.MusicVideos)
{ {
return ResolveVideos<MusicVideo>(parent, files, true, collectionType, false); return ResolveVideos<MusicVideo>(parent, files, true, collectionType, false);
} }
if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase) || if (collectionType == CollectionType.HomeVideos || collectionType == CollectionType.Photos)
string.Equals(collectionType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase))
{ {
return ResolveVideos<Video>(parent, files, false, collectionType, false); return ResolveVideos<Video>(parent, files, false, collectionType, false);
} }
if (string.IsNullOrEmpty(collectionType)) if (collectionType is null)
{ {
// Owned items should just use the plain video type // Owned items should just use the plain video type
if (parent is null) if (parent is null)
@ -222,12 +221,12 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
return ResolveVideos<Movie>(parent, files, false, collectionType, true); return ResolveVideos<Movie>(parent, files, false, collectionType, true);
} }
if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase)) if (collectionType == CollectionType.Movies)
{ {
return ResolveVideos<Movie>(parent, files, true, collectionType, true); return ResolveVideos<Movie>(parent, files, true, collectionType, true);
} }
if (string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase)) if (collectionType == CollectionType.TvShows)
{ {
return ResolveVideos<Episode>(parent, files, false, collectionType, true); return ResolveVideos<Episode>(parent, files, false, collectionType, true);
} }
@ -239,13 +238,13 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
Folder parent, Folder parent,
IEnumerable<FileSystemMetadata> fileSystemEntries, IEnumerable<FileSystemMetadata> fileSystemEntries,
bool supportMultiEditions, bool supportMultiEditions,
string collectionType, CollectionType? collectionType,
bool parseName) bool parseName)
where T : Video, new() where T : Video, new()
{ {
var files = new List<FileSystemMetadata>(); var files = new List<FileSystemMetadata>();
var leftOver = new List<FileSystemMetadata>(); var leftOver = new List<FileSystemMetadata>();
var hasCollectionType = !string.IsNullOrEmpty(collectionType); var hasCollectionType = collectionType is not null;
// Loop through each child file/folder and see if we find a video // Loop through each child file/folder and see if we find a video
foreach (var child in fileSystemEntries) foreach (var child in fileSystemEntries)
@ -398,13 +397,13 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
/// Finds a movie based on a child file system entries. /// Finds a movie based on a child file system entries.
/// </summary> /// </summary>
/// <returns>Movie.</returns> /// <returns>Movie.</returns>
private T FindMovie<T>(ItemResolveArgs args, string path, Folder parent, List<FileSystemMetadata> fileSystemEntries, IDirectoryService directoryService, string collectionType, bool parseName) private T FindMovie<T>(ItemResolveArgs args, string path, Folder parent, List<FileSystemMetadata> fileSystemEntries, IDirectoryService directoryService, CollectionType? collectionType, bool parseName)
where T : Video, new() where T : Video, new()
{ {
var multiDiscFolders = new List<FileSystemMetadata>(); var multiDiscFolders = new List<FileSystemMetadata>();
var libraryOptions = args.LibraryOptions; var libraryOptions = args.LibraryOptions;
var supportPhotos = string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase) && libraryOptions.EnablePhotos; var supportPhotos = collectionType == CollectionType.HomeVideos && libraryOptions.EnablePhotos;
var photos = new List<FileSystemMetadata>(); var photos = new List<FileSystemMetadata>();
// Search for a folder rip // Search for a folder rip
@ -460,8 +459,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
var result = ResolveVideos<T>(parent, fileSystemEntries, SupportsMultiVersion, collectionType, parseName) ?? var result = ResolveVideos<T>(parent, fileSystemEntries, SupportsMultiVersion, collectionType, parseName) ??
new MultiItemResolverResult(); new MultiItemResolverResult();
var isPhotosCollection = string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase) var isPhotosCollection = collectionType == CollectionType.HomeVideos || collectionType == CollectionType.Photos;
|| string.Equals(collectionType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase);
if (!isPhotosCollection && result.Items.Count == 1) if (!isPhotosCollection && result.Items.Count == 1)
{ {
var videoPath = result.Items[0].Path; var videoPath = result.Items[0].Path;
@ -562,7 +560,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
return returnVideo; return returnVideo;
} }
private bool IsInvalid(Folder parent, ReadOnlySpan<char> collectionType) private bool IsInvalid(Folder parent, CollectionType? collectionType)
{ {
if (parent is not null) if (parent is not null)
{ {
@ -572,12 +570,12 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
} }
} }
if (collectionType.IsEmpty) if (collectionType is null)
{ {
return false; return false;
} }
return !_validCollectionTypes.Contains(collectionType, StringComparison.OrdinalIgnoreCase); return !_validCollectionTypes.Contains(collectionType.Value);
} }
} }
} }

@ -2,6 +2,7 @@
using System; using System;
using Emby.Naming.Common; using Emby.Naming.Common;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
@ -45,8 +46,8 @@ namespace Emby.Server.Implementations.Library.Resolvers
// Must be an image file within a photo collection // Must be an image file within a photo collection
var collectionType = args.GetCollectionType(); var collectionType = args.GetCollectionType();
if (string.Equals(collectionType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase) if (collectionType == CollectionType.Photos
|| (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase) && args.LibraryOptions.EnablePhotos)) || (collectionType == CollectionType.HomeVideos && args.LibraryOptions.EnablePhotos))
{ {
if (HasPhotos(args)) if (HasPhotos(args))
{ {

@ -3,6 +3,7 @@ using System.IO;
using System.Linq; using System.Linq;
using Emby.Naming.Common; using Emby.Naming.Common;
using Emby.Naming.Video; using Emby.Naming.Video;
using Jellyfin.Data.Enums;
using Jellyfin.Extensions; using Jellyfin.Extensions;
using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
@ -60,8 +61,8 @@ namespace Emby.Server.Implementations.Library.Resolvers
// Must be an image file within a photo collection // Must be an image file within a photo collection
var collectionType = args.CollectionType; var collectionType = args.CollectionType;
if (string.Equals(collectionType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase) if (collectionType == CollectionType.Photos
|| (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase) && args.LibraryOptions.EnablePhotos)) || (collectionType == CollectionType.HomeVideos && args.LibraryOptions.EnablePhotos))
{ {
if (IsImageFile(args.Path, _imageProcessor)) if (IsImageFile(args.Path, _imageProcessor))
{ {

@ -5,6 +5,7 @@
using System; using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Jellyfin.Data.Enums;
using Jellyfin.Extensions; using Jellyfin.Extensions;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Playlists; using MediaBrowser.Controller.Playlists;
@ -19,9 +20,9 @@ namespace Emby.Server.Implementations.Library.Resolvers
/// </summary> /// </summary>
public class PlaylistResolver : GenericFolderResolver<Playlist> public class PlaylistResolver : GenericFolderResolver<Playlist>
{ {
private string[] _musicPlaylistCollectionTypes = private CollectionType?[] _musicPlaylistCollectionTypes =
{ {
string.Empty, null,
CollectionType.Music CollectionType.Music
}; };
@ -62,7 +63,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
// Check if this is a music playlist file // Check if this is a music playlist file
// It should have the correct collection type and a supported file extension // It should have the correct collection type and a supported file extension
else if (_musicPlaylistCollectionTypes.Contains(args.CollectionType ?? string.Empty, StringComparison.OrdinalIgnoreCase)) else if (_musicPlaylistCollectionTypes.Contains(args.CollectionType))
{ {
var extension = Path.GetExtension(args.Path.AsSpan()); var extension = Path.GetExtension(args.Path.AsSpan());
if (Playlist.SupportedExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase)) if (Playlist.SupportedExtensions.Contains(extension, StringComparison.OrdinalIgnoreCase))

@ -5,6 +5,7 @@
using System; using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller; using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
@ -62,7 +63,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
return null; return null;
} }
private string GetCollectionType(ItemResolveArgs args) private CollectionType? GetCollectionType(ItemResolveArgs args)
{ {
return args.FileSystemChildren return args.FileSystemChildren
.Where(i => .Where(i =>
@ -78,7 +79,8 @@ namespace Emby.Server.Implementations.Library.Resolvers
} }
}) })
.Select(i => _fileSystem.GetFileNameWithoutExtension(i)) .Select(i => _fileSystem.GetFileNameWithoutExtension(i))
.FirstOrDefault(); .Select(i => Enum.TryParse<CollectionType>(i, out var collectionType) ? collectionType : (CollectionType?)null)
.FirstOrDefault(i => i is not null);
} }
} }
} }

@ -3,6 +3,7 @@
using System; using System;
using System.Linq; using System.Linq;
using Emby.Naming.Common; using Emby.Naming.Common;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Providers;
@ -48,9 +49,9 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
// If the parent is a Season or Series and the parent is not an extras folder, then this is an Episode if the VideoResolver returns something // If the parent is a Season or Series and the parent is not an extras folder, then this is an Episode if the VideoResolver returns something
// Also handle flat tv folders // Also handle flat tv folders
if (season is not null || if (season is not null
string.Equals(args.GetCollectionType(), CollectionType.TvShows, StringComparison.OrdinalIgnoreCase) || || args.GetCollectionType() == CollectionType.TvShows
args.HasParent<Series>()) || args.HasParent<Series>())
{ {
var episode = ResolveVideo<Episode>(args, false); var episode = ResolveVideo<Episode>(args, false);

@ -8,6 +8,7 @@ using System.IO;
using Emby.Naming.Common; using Emby.Naming.Common;
using Emby.Naming.TV; using Emby.Naming.TV;
using Emby.Naming.Video; using Emby.Naming.Video;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Resolvers; using MediaBrowser.Controller.Resolvers;
@ -59,11 +60,11 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
var seriesInfo = Naming.TV.SeriesResolver.Resolve(_namingOptions, args.Path); var seriesInfo = Naming.TV.SeriesResolver.Resolve(_namingOptions, args.Path);
var collectionType = args.GetCollectionType(); var collectionType = args.GetCollectionType();
if (string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase)) if (collectionType == CollectionType.TvShows)
{ {
// TODO refactor into separate class or something, this is copied from LibraryManager.GetConfiguredContentType // TODO refactor into separate class or something, this is copied from LibraryManager.GetConfiguredContentType
var configuredContentType = args.GetConfiguredContentType(); var configuredContentType = args.GetConfiguredContentType();
if (!string.Equals(configuredContentType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase)) if (configuredContentType != CollectionType.TvShows)
{ {
return new Series return new Series
{ {
@ -72,7 +73,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
}; };
} }
} }
else if (string.IsNullOrEmpty(collectionType)) else if (collectionType is null)
{ {
if (args.ContainsFileSystemEntryByName("tvshow.nfo")) if (args.ContainsFileSystemEntryByName("tvshow.nfo"))
{ {

@ -8,7 +8,6 @@ using System.Linq;
using System.Threading; using System.Threading;
using Jellyfin.Data.Entities; using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums; using Jellyfin.Data.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Dto;
@ -64,8 +63,8 @@ namespace Emby.Server.Implementations.Library
var collectionFolder = folder as ICollectionFolder; var collectionFolder = folder as ICollectionFolder;
var folderViewType = collectionFolder?.CollectionType; var folderViewType = collectionFolder?.CollectionType;
// Playlist library requires special handling because the folder only refrences user playlists // Playlist library requires special handling because the folder only references user playlists
if (string.Equals(folderViewType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase)) if (folderViewType == CollectionType.Playlists)
{ {
var items = folder.GetItemList(new InternalItemsQuery(user) var items = folder.GetItemList(new InternalItemsQuery(user)
{ {
@ -90,7 +89,7 @@ namespace Emby.Server.Implementations.Library
continue; continue;
} }
if (query.PresetViews.Contains(folderViewType ?? string.Empty, StringComparison.OrdinalIgnoreCase)) if (query.PresetViews.Contains(folderViewType))
{ {
list.Add(GetUserView(folder, folderViewType, string.Empty)); list.Add(GetUserView(folder, folderViewType, string.Empty));
} }
@ -102,14 +101,14 @@ namespace Emby.Server.Implementations.Library
foreach (var viewType in new[] { CollectionType.Movies, CollectionType.TvShows }) foreach (var viewType in new[] { CollectionType.Movies, CollectionType.TvShows })
{ {
var parents = groupedFolders.Where(i => string.Equals(i.CollectionType, viewType, StringComparison.OrdinalIgnoreCase) || string.IsNullOrEmpty(i.CollectionType)) var parents = groupedFolders.Where(i => i.CollectionType == viewType || i.CollectionType is null)
.ToList(); .ToList();
if (parents.Count > 0) if (parents.Count > 0)
{ {
var localizationKey = string.Equals(viewType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase) ? var localizationKey = viewType == CollectionType.TvShows
"TvShows" : ? "TvShows"
"Movies"; : "Movies";
list.Add(GetUserView(parents, viewType, localizationKey, string.Empty, user, query.PresetViews)); list.Add(GetUserView(parents, viewType, localizationKey, string.Empty, user, query.PresetViews));
} }
@ -164,14 +163,14 @@ namespace Emby.Server.Implementations.Library
.ToArray(); .ToArray();
} }
public UserView GetUserSubViewWithName(string name, Guid parentId, string type, string sortName) public UserView GetUserSubViewWithName(string name, Guid parentId, CollectionType? type, string sortName)
{ {
var uniqueId = parentId + "subview" + type; var uniqueId = parentId + "subview" + type;
return _libraryManager.GetNamedView(name, parentId, type, sortName, uniqueId); return _libraryManager.GetNamedView(name, parentId, type, sortName, uniqueId);
} }
public UserView GetUserSubView(Guid parentId, string type, string localizationKey, string sortName) public UserView GetUserSubView(Guid parentId, CollectionType? type, string localizationKey, string sortName)
{ {
var name = _localizationManager.GetLocalizedString(localizationKey); var name = _localizationManager.GetLocalizedString(localizationKey);
@ -180,15 +179,15 @@ namespace Emby.Server.Implementations.Library
private Folder GetUserView( private Folder GetUserView(
List<ICollectionFolder> parents, List<ICollectionFolder> parents,
string viewType, CollectionType? viewType,
string localizationKey, string localizationKey,
string sortName, string sortName,
User user, User user,
string[] presetViews) CollectionType?[] presetViews)
{ {
if (parents.Count == 1 && parents.All(i => string.Equals(i.CollectionType, viewType, StringComparison.OrdinalIgnoreCase))) if (parents.Count == 1 && parents.All(i => i.CollectionType == viewType))
{ {
if (!presetViews.Contains(viewType, StringComparison.OrdinalIgnoreCase)) if (!presetViews.Contains(viewType))
{ {
return (Folder)parents[0]; return (Folder)parents[0];
} }
@ -200,7 +199,7 @@ namespace Emby.Server.Implementations.Library
return _libraryManager.GetNamedView(user, name, viewType, sortName); return _libraryManager.GetNamedView(user, name, viewType, sortName);
} }
public UserView GetUserView(Folder parent, string viewType, string sortName) public UserView GetUserView(Folder parent, CollectionType? viewType, string sortName)
{ {
return _libraryManager.GetShadowView(parent, viewType, sortName); return _libraryManager.GetShadowView(parent, viewType, sortName);
} }
@ -280,7 +279,7 @@ namespace Emby.Server.Implementations.Library
var isPlayed = request.IsPlayed; var isPlayed = request.IsPlayed;
if (parents.OfType<ICollectionFolder>().Any(i => string.Equals(i.CollectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase))) if (parents.OfType<ICollectionFolder>().Any(i => i.CollectionType == CollectionType.Music))
{ {
isPlayed = null; isPlayed = null;
} }
@ -306,11 +305,11 @@ namespace Emby.Server.Implementations.Library
var hasCollectionType = parents.OfType<UserView>().ToArray(); var hasCollectionType = parents.OfType<UserView>().ToArray();
if (hasCollectionType.Length > 0) if (hasCollectionType.Length > 0)
{ {
if (hasCollectionType.All(i => string.Equals(i.CollectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase))) if (hasCollectionType.All(i => i.CollectionType == CollectionType.Movies))
{ {
includeItemTypes = new[] { BaseItemKind.Movie }; includeItemTypes = new[] { BaseItemKind.Movie };
} }
else if (hasCollectionType.All(i => string.Equals(i.CollectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))) else if (hasCollectionType.All(i => i.CollectionType == CollectionType.TvShows))
{ {
includeItemTypes = new[] { BaseItemKind.Episode }; includeItemTypes = new[] { BaseItemKind.Episode };
} }

@ -25,7 +25,7 @@ namespace Emby.Server.Implementations.Playlists
public override bool SupportsInheritedParentImages => false; public override bool SupportsInheritedParentImages => false;
[JsonIgnore] [JsonIgnore]
public override string CollectionType => MediaBrowser.Model.Entities.CollectionType.Playlists; public override CollectionType? CollectionType => Jellyfin.Data.Enums.CollectionType.Playlists;
protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user) protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
{ {

@ -131,8 +131,8 @@ public class GenresController : BaseJellyfinApiController
QueryResult<(BaseItem, ItemCounts)> result; QueryResult<(BaseItem, ItemCounts)> result;
if (parentItem is ICollectionFolder parentCollectionFolder if (parentItem is ICollectionFolder parentCollectionFolder
&& (string.Equals(parentCollectionFolder.CollectionType, CollectionType.Music, StringComparison.Ordinal) && (parentCollectionFolder.CollectionType == CollectionType.Music
|| string.Equals(parentCollectionFolder.CollectionType, CollectionType.MusicVideos, StringComparison.Ordinal))) || parentCollectionFolder.CollectionType == CollectionType.MusicVideos))
{ {
result = _libraryManager.GetMusicGenres(query); result = _libraryManager.GetMusicGenres(query);
} }

@ -5,6 +5,7 @@ using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Jellyfin.Api.Constants; using Jellyfin.Api.Constants;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Audio;
@ -164,18 +165,16 @@ public class ItemUpdateController : BaseJellyfinApiController
var inheritedContentType = _libraryManager.GetInheritedContentType(item); var inheritedContentType = _libraryManager.GetInheritedContentType(item);
var configuredContentType = _libraryManager.GetConfiguredContentType(item); var configuredContentType = _libraryManager.GetConfiguredContentType(item);
if (string.IsNullOrWhiteSpace(inheritedContentType) || if (inheritedContentType is null || configuredContentType is not null)
!string.IsNullOrWhiteSpace(configuredContentType))
{ {
info.ContentTypeOptions = GetContentTypeOptions(true).ToArray(); info.ContentTypeOptions = GetContentTypeOptions(true).ToArray();
info.ContentType = configuredContentType; info.ContentType = configuredContentType;
if (string.IsNullOrWhiteSpace(inheritedContentType) if (inheritedContentType is null || inheritedContentType == CollectionType.TvShows)
|| string.Equals(inheritedContentType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
{ {
info.ContentTypeOptions = info.ContentTypeOptions info.ContentTypeOptions = info.ContentTypeOptions
.Where(i => string.IsNullOrWhiteSpace(i.Value) .Where(i => string.IsNullOrWhiteSpace(i.Value)
|| string.Equals(i.Value, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase)) || string.Equals(i.Value, "TvShows", StringComparison.OrdinalIgnoreCase))
.ToArray(); .ToArray();
} }
} }

@ -269,13 +269,13 @@ public class ItemsController : BaseJellyfinApiController
folder = _libraryManager.GetUserRootFolder(); folder = _libraryManager.GetUserRootFolder();
} }
string? collectionType = null; CollectionType? collectionType = null;
if (folder is IHasCollectionType hasCollectionType) if (folder is IHasCollectionType hasCollectionType)
{ {
collectionType = hasCollectionType.CollectionType; collectionType = hasCollectionType.CollectionType;
} }
if (string.Equals(collectionType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase)) if (collectionType == CollectionType.Playlists)
{ {
recursive = true; recursive = true;
includeItemTypes = new[] { BaseItemKind.Playlist }; includeItemTypes = new[] { BaseItemKind.Playlist };

@ -788,7 +788,7 @@ public class LibraryController : BaseJellyfinApiController
[Authorize(Policy = Policies.FirstTimeSetupOrDefault)] [Authorize(Policy = Policies.FirstTimeSetupOrDefault)]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<LibraryOptionsResultDto> GetLibraryOptionsInfo( public ActionResult<LibraryOptionsResultDto> GetLibraryOptionsInfo(
[FromQuery] string? libraryContentType, [FromQuery] CollectionType? libraryContentType,
[FromQuery] bool isNewLibrary = false) [FromQuery] bool isNewLibrary = false)
{ {
var result = new LibraryOptionsResultDto(); var result = new LibraryOptionsResultDto();
@ -922,7 +922,7 @@ public class LibraryController : BaseJellyfinApiController
} }
} }
private static string[] GetRepresentativeItemTypes(string? contentType) private static string[] GetRepresentativeItemTypes(CollectionType? contentType)
{ {
return contentType switch return contentType switch
{ {

@ -6,6 +6,7 @@ using System.Linq;
using Jellyfin.Api.Extensions; using Jellyfin.Api.Extensions;
using Jellyfin.Api.ModelBinders; using Jellyfin.Api.ModelBinders;
using Jellyfin.Api.Models.UserViewDtos; using Jellyfin.Api.Models.UserViewDtos;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
@ -63,7 +64,7 @@ public class UserViewsController : BaseJellyfinApiController
public QueryResult<BaseItemDto> GetUserViews( public QueryResult<BaseItemDto> GetUserViews(
[FromRoute, Required] Guid userId, [FromRoute, Required] Guid userId,
[FromQuery] bool? includeExternalContent, [FromQuery] bool? includeExternalContent,
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] presetViews, [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] CollectionType?[] presetViews,
[FromQuery] bool includeHidden = false) [FromQuery] bool includeHidden = false)
{ {
var query = new UserViewQuery var query = new UserViewQuery

@ -0,0 +1,11 @@
using System;
namespace Jellyfin.Data.Attributes;
/// <summary>
/// Attribute to specify that the enum value is to be ignored when generating the openapi spec.
/// </summary>
[AttributeUsage(AttributeTargets.Field)]
public sealed class OpenApiIgnoreEnumAttribute : Attribute
{
}

@ -0,0 +1,164 @@
using Jellyfin.Data.Attributes;
namespace Jellyfin.Data.Enums;
/// <summary>
/// Collection type.
/// </summary>
public enum CollectionType
{
/// <summary>
/// Unknown collection.
/// </summary>
Unknown = 0,
/// <summary>
/// Movies collection.
/// </summary>
Movies = 1,
/// <summary>
/// Tv shows collection.
/// </summary>
TvShows = 2,
/// <summary>
/// Music collection.
/// </summary>
Music = 3,
/// <summary>
/// Music videos collection.
/// </summary>
MusicVideos = 4,
/// <summary>
/// Trailers collection.
/// </summary>
Trailers = 5,
/// <summary>
/// Home videos collection.
/// </summary>
HomeVideos = 6,
/// <summary>
/// Box sets collection.
/// </summary>
BoxSets = 7,
/// <summary>
/// Books collection.
/// </summary>
Books = 8,
/// <summary>
/// Photos collection.
/// </summary>
Photos = 9,
/// <summary>
/// Live tv collection.
/// </summary>
LiveTv = 10,
/// <summary>
/// Playlists collection.
/// </summary>
Playlists = 11,
/// <summary>
/// Folders collection.
/// </summary>
Folders = 12,
/// <summary>
/// Tv show series collection.
/// </summary>
[OpenApiIgnoreEnum]
TvShowSeries = 101,
/// <summary>
/// Tv genres collection.
/// </summary>
[OpenApiIgnoreEnum]
TvGenres = 102,
/// <summary>
/// Tv genre collection.
/// </summary>
[OpenApiIgnoreEnum]
TvGenre = 103,
/// <summary>
/// Tv latest collection.
/// </summary>
[OpenApiIgnoreEnum]
TvLatest = 104,
/// <summary>
/// Tv next up collection.
/// </summary>
[OpenApiIgnoreEnum]
TvNextUp = 105,
/// <summary>
/// Tv resume collection.
/// </summary>
[OpenApiIgnoreEnum]
TvResume = 106,
/// <summary>
/// Tv favorite series collection.
/// </summary>
[OpenApiIgnoreEnum]
TvFavoriteSeries = 107,
/// <summary>
/// Tv favorite episodes collection.
/// </summary>
[OpenApiIgnoreEnum]
TvFavoriteEpisodes = 108,
/// <summary>
/// Latest movies collection.
/// </summary>
[OpenApiIgnoreEnum]
MovieLatest = 109,
/// <summary>
/// Movies to resume collection.
/// </summary>
[OpenApiIgnoreEnum]
MovieResume = 110,
/// <summary>
/// Movie movie collection.
/// </summary>
[OpenApiIgnoreEnum]
MovieMovies = 111,
/// <summary>
/// Movie collections collection.
/// </summary>
[OpenApiIgnoreEnum]
MovieCollections = 112,
/// <summary>
/// Movie favorites collection.
/// </summary>
[OpenApiIgnoreEnum]
MovieFavorites = 113,
/// <summary>
/// Movie genres collection.
/// </summary>
[OpenApiIgnoreEnum]
MovieGenres = 114,
/// <summary>
/// Movie genre collection.
/// </summary>
[OpenApiIgnoreEnum]
MovieGenre = 115
}

@ -246,6 +246,7 @@ namespace Jellyfin.Server.Extensions
// TODO - remove when all types are supported in System.Text.Json // TODO - remove when all types are supported in System.Text.Json
c.AddSwaggerTypeMappings(); c.AddSwaggerTypeMappings();
c.SchemaFilter<IgnoreEnumSchemaFilter>();
c.OperationFilter<SecurityRequirementsOperationFilter>(); c.OperationFilter<SecurityRequirementsOperationFilter>();
c.OperationFilter<FileResponseFilter>(); c.OperationFilter<FileResponseFilter>();
c.OperationFilter<FileRequestFilter>(); c.OperationFilter<FileRequestFilter>();

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Jellyfin.Data.Attributes;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace Jellyfin.Server.Filters;
/// <summary>
/// Filter to remove ignored enum values.
/// </summary>
public class IgnoreEnumSchemaFilter : ISchemaFilter
{
/// <inheritdoc />
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
if (context.Type.IsEnum || (Nullable.GetUnderlyingType(context.Type)?.IsEnum ?? false))
{
var type = context.Type.IsEnum ? context.Type : Nullable.GetUnderlyingType(context.Type);
if (type is null)
{
return;
}
var enumOpenApiStrings = new List<IOpenApiAny>();
foreach (var enumName in Enum.GetNames(type))
{
var member = type.GetMember(enumName)[0];
if (!member.GetCustomAttributes<OpenApiIgnoreEnumAttribute>().Any())
{
enumOpenApiStrings.Add(new OpenApiString(enumName));
}
}
schema.Enum = enumOpenApiStrings;
}
}
}

@ -724,7 +724,7 @@ namespace MediaBrowser.Controller.Entities
if (this is IHasCollectionType view) if (this is IHasCollectionType view)
{ {
if (string.Equals(view.CollectionType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase)) if (view.CollectionType == CollectionType.LiveTv)
{ {
return true; return true;
} }

@ -1,6 +1,7 @@
#pragma warning disable CS1591 #pragma warning disable CS1591
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using Jellyfin.Data.Enums;
namespace MediaBrowser.Controller.Entities namespace MediaBrowser.Controller.Entities
{ {
@ -11,7 +12,7 @@ namespace MediaBrowser.Controller.Entities
public abstract class BasePluginFolder : Folder, ICollectionFolder public abstract class BasePluginFolder : Folder, ICollectionFolder
{ {
[JsonIgnore] [JsonIgnore]
public virtual string? CollectionType => null; public virtual CollectionType? CollectionType => null;
[JsonIgnore] [JsonIgnore]
public override bool SupportsInheritedParentImages => false; public override bool SupportsInheritedParentImages => false;

@ -11,6 +11,7 @@ using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Jellyfin.Data.Enums;
using Jellyfin.Extensions.Json; using Jellyfin.Extensions.Json;
using MediaBrowser.Controller.IO; using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
@ -69,7 +70,7 @@ namespace MediaBrowser.Controller.Entities
[JsonIgnore] [JsonIgnore]
public override bool SupportsInheritedParentImages => false; public override bool SupportsInheritedParentImages => false;
public string CollectionType { get; set; } public CollectionType? CollectionType { get; set; }
/// <summary> /// <summary>
/// Gets the item's children. /// Gets the item's children.

@ -3,6 +3,7 @@
#pragma warning disable CA1819, CS1591 #pragma warning disable CA1819, CS1591
using System; using System;
using Jellyfin.Data.Enums;
namespace MediaBrowser.Controller.Entities namespace MediaBrowser.Controller.Entities
{ {
@ -27,6 +28,6 @@ namespace MediaBrowser.Controller.Entities
public interface IHasCollectionType public interface IHasCollectionType
{ {
string CollectionType { get; } CollectionType? CollectionType { get; }
} }
} }

@ -42,7 +42,7 @@ namespace MediaBrowser.Controller.Entities
OrderBy = Array.Empty<(ItemSortBy, SortOrder)>(); OrderBy = Array.Empty<(ItemSortBy, SortOrder)>();
PersonIds = Array.Empty<Guid>(); PersonIds = Array.Empty<Guid>();
PersonTypes = Array.Empty<string>(); PersonTypes = Array.Empty<string>();
PresetViews = Array.Empty<string>(); PresetViews = Array.Empty<CollectionType?>();
SeriesStatuses = Array.Empty<SeriesStatus>(); SeriesStatuses = Array.Empty<SeriesStatus>();
SourceTypes = Array.Empty<SourceType>(); SourceTypes = Array.Empty<SourceType>();
StudioIds = Array.Empty<Guid>(); StudioIds = Array.Empty<Guid>();
@ -248,7 +248,7 @@ namespace MediaBrowser.Controller.Entities
public Guid[] TopParentIds { get; set; } public Guid[] TopParentIds { get; set; }
public string[] PresetViews { get; set; } public CollectionType?[] PresetViews { get; set; }
public TrailerType[] TrailerTypes { get; set; } public TrailerType[] TrailerTypes { get; set; }

@ -8,6 +8,7 @@ using System.Linq;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using System.Threading.Tasks; using System.Threading.Tasks;
using Jellyfin.Data.Entities; using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Extensions; using Jellyfin.Extensions;
using MediaBrowser.Controller.TV; using MediaBrowser.Controller.TV;
using MediaBrowser.Model.Querying; using MediaBrowser.Model.Querying;
@ -16,21 +17,21 @@ namespace MediaBrowser.Controller.Entities
{ {
public class UserView : Folder, IHasCollectionType public class UserView : Folder, IHasCollectionType
{ {
private static readonly string[] _viewTypesEligibleForGrouping = new string[] private static readonly CollectionType?[] _viewTypesEligibleForGrouping =
{ {
Model.Entities.CollectionType.Movies, Jellyfin.Data.Enums.CollectionType.Movies,
Model.Entities.CollectionType.TvShows, Jellyfin.Data.Enums.CollectionType.TvShows,
string.Empty null
}; };
private static readonly string[] _originalFolderViewTypes = new string[] private static readonly CollectionType?[] _originalFolderViewTypes =
{ {
Model.Entities.CollectionType.Books, Jellyfin.Data.Enums.CollectionType.Books,
Model.Entities.CollectionType.MusicVideos, Jellyfin.Data.Enums.CollectionType.MusicVideos,
Model.Entities.CollectionType.HomeVideos, Jellyfin.Data.Enums.CollectionType.HomeVideos,
Model.Entities.CollectionType.Photos, Jellyfin.Data.Enums.CollectionType.Photos,
Model.Entities.CollectionType.Music, Jellyfin.Data.Enums.CollectionType.Music,
Model.Entities.CollectionType.BoxSets Jellyfin.Data.Enums.CollectionType.BoxSets
}; };
public static ITVSeriesManager TVSeriesManager { get; set; } public static ITVSeriesManager TVSeriesManager { get; set; }
@ -38,7 +39,7 @@ namespace MediaBrowser.Controller.Entities
/// <summary> /// <summary>
/// Gets or sets the view type. /// Gets or sets the view type.
/// </summary> /// </summary>
public string ViewType { get; set; } public CollectionType? ViewType { get; set; }
/// <summary> /// <summary>
/// Gets or sets the display parent id. /// Gets or sets the display parent id.
@ -52,7 +53,7 @@ namespace MediaBrowser.Controller.Entities
/// <inheritdoc /> /// <inheritdoc />
[JsonIgnore] [JsonIgnore]
public string CollectionType => ViewType; public CollectionType? CollectionType => ViewType;
/// <inheritdoc /> /// <inheritdoc />
[JsonIgnore] [JsonIgnore]
@ -160,7 +161,7 @@ namespace MediaBrowser.Controller.Entities
return true; return true;
} }
return string.Equals(Model.Entities.CollectionType.Playlists, collectionFolder.CollectionType, StringComparison.OrdinalIgnoreCase); return collectionFolder.CollectionType == Jellyfin.Data.Enums.CollectionType.Playlists;
} }
public static bool IsEligibleForGrouping(Folder folder) public static bool IsEligibleForGrouping(Folder folder)
@ -169,14 +170,14 @@ namespace MediaBrowser.Controller.Entities
&& IsEligibleForGrouping(collectionFolder.CollectionType); && IsEligibleForGrouping(collectionFolder.CollectionType);
} }
public static bool IsEligibleForGrouping(string viewType) public static bool IsEligibleForGrouping(CollectionType? viewType)
{ {
return _viewTypesEligibleForGrouping.Contains(viewType ?? string.Empty, StringComparison.OrdinalIgnoreCase); return _viewTypesEligibleForGrouping.Contains(viewType);
} }
public static bool EnableOriginalFolder(string viewType) public static bool EnableOriginalFolder(CollectionType? viewType)
{ {
return _originalFolderViewTypes.Contains(viewType ?? string.Empty, StringComparison.OrdinalIgnoreCase); return _originalFolderViewTypes.Contains(viewType);
} }
protected override Task ValidateChildrenInternal(IProgress<double> progress, bool recursive, bool refreshChildMetadata, Providers.MetadataRefreshOptions refreshOptions, Providers.IDirectoryService directoryService, System.Threading.CancellationToken cancellationToken) protected override Task ValidateChildrenInternal(IProgress<double> progress, bool recursive, bool refreshChildMetadata, Providers.MetadataRefreshOptions refreshOptions, Providers.IDirectoryService directoryService, System.Threading.CancellationToken cancellationToken)

@ -42,7 +42,7 @@ namespace MediaBrowser.Controller.Entities
_tvSeriesManager = tvSeriesManager; _tvSeriesManager = tvSeriesManager;
} }
public QueryResult<BaseItem> GetUserItems(Folder queryParent, Folder displayParent, string viewType, InternalItemsQuery query) public QueryResult<BaseItem> GetUserItems(Folder queryParent, Folder displayParent, CollectionType? viewType, InternalItemsQuery query)
{ {
var user = query.User; var user = query.User;
@ -67,49 +67,49 @@ namespace MediaBrowser.Controller.Entities
case CollectionType.Movies: case CollectionType.Movies:
return GetMovieFolders(queryParent, user, query); return GetMovieFolders(queryParent, user, query);
case SpecialFolder.TvShowSeries: case CollectionType.TvShowSeries:
return GetTvSeries(queryParent, user, query); return GetTvSeries(queryParent, user, query);
case SpecialFolder.TvGenres: case CollectionType.TvGenres:
return GetTvGenres(queryParent, user, query); return GetTvGenres(queryParent, user, query);
case SpecialFolder.TvGenre: case CollectionType.TvGenre:
return GetTvGenreItems(queryParent, displayParent, user, query); return GetTvGenreItems(queryParent, displayParent, user, query);
case SpecialFolder.TvResume: case CollectionType.TvResume:
return GetTvResume(queryParent, user, query); return GetTvResume(queryParent, user, query);
case SpecialFolder.TvNextUp: case CollectionType.TvNextUp:
return GetTvNextUp(queryParent, query); return GetTvNextUp(queryParent, query);
case SpecialFolder.TvLatest: case CollectionType.TvLatest:
return GetTvLatest(queryParent, user, query); return GetTvLatest(queryParent, user, query);
case SpecialFolder.MovieFavorites: case CollectionType.MovieFavorites:
return GetFavoriteMovies(queryParent, user, query); return GetFavoriteMovies(queryParent, user, query);
case SpecialFolder.MovieLatest: case CollectionType.MovieLatest:
return GetMovieLatest(queryParent, user, query); return GetMovieLatest(queryParent, user, query);
case SpecialFolder.MovieGenres: case CollectionType.MovieGenres:
return GetMovieGenres(queryParent, user, query); return GetMovieGenres(queryParent, user, query);
case SpecialFolder.MovieGenre: case CollectionType.MovieGenre:
return GetMovieGenreItems(queryParent, displayParent, user, query); return GetMovieGenreItems(queryParent, displayParent, user, query);
case SpecialFolder.MovieResume: case CollectionType.MovieResume:
return GetMovieResume(queryParent, user, query); return GetMovieResume(queryParent, user, query);
case SpecialFolder.MovieMovies: case CollectionType.MovieMovies:
return GetMovieMovies(queryParent, user, query); return GetMovieMovies(queryParent, user, query);
case SpecialFolder.MovieCollections: case CollectionType.MovieCollections:
return GetMovieCollections(user, query); return GetMovieCollections(user, query);
case SpecialFolder.TvFavoriteEpisodes: case CollectionType.TvFavoriteEpisodes:
return GetFavoriteEpisodes(queryParent, user, query); return GetFavoriteEpisodes(queryParent, user, query);
case SpecialFolder.TvFavoriteSeries: case CollectionType.TvFavoriteSeries:
return GetFavoriteSeries(queryParent, user, query); return GetFavoriteSeries(queryParent, user, query);
default: default:
@ -146,12 +146,12 @@ namespace MediaBrowser.Controller.Entities
var list = new List<BaseItem> var list = new List<BaseItem>
{ {
GetUserView(SpecialFolder.MovieResume, "HeaderContinueWatching", "0", parent), GetUserView(CollectionType.MovieResume, "HeaderContinueWatching", "0", parent),
GetUserView(SpecialFolder.MovieLatest, "Latest", "1", parent), GetUserView(CollectionType.MovieLatest, "Latest", "1", parent),
GetUserView(SpecialFolder.MovieMovies, "Movies", "2", parent), GetUserView(CollectionType.MovieMovies, "Movies", "2", parent),
GetUserView(SpecialFolder.MovieCollections, "Collections", "3", parent), GetUserView(CollectionType.MovieCollections, "Collections", "3", parent),
GetUserView(SpecialFolder.MovieFavorites, "Favorites", "4", parent), GetUserView(CollectionType.MovieFavorites, "Favorites", "4", parent),
GetUserView(SpecialFolder.MovieGenres, "Genres", "5", parent) GetUserView(CollectionType.MovieGenres, "Genres", "5", parent)
}; };
return GetResult(list, query); return GetResult(list, query);
@ -264,7 +264,7 @@ namespace MediaBrowser.Controller.Entities
} }
}) })
.Where(i => i is not null) .Where(i => i is not null)
.Select(i => GetUserViewWithName(SpecialFolder.MovieGenre, i.SortName, parent)); .Select(i => GetUserViewWithName(CollectionType.MovieGenre, i.SortName, parent));
return GetResult(genres, query); return GetResult(genres, query);
} }
@ -303,13 +303,13 @@ namespace MediaBrowser.Controller.Entities
var list = new List<BaseItem> var list = new List<BaseItem>
{ {
GetUserView(SpecialFolder.TvResume, "HeaderContinueWatching", "0", parent), GetUserView(CollectionType.TvResume, "HeaderContinueWatching", "0", parent),
GetUserView(SpecialFolder.TvNextUp, "HeaderNextUp", "1", parent), GetUserView(CollectionType.TvNextUp, "HeaderNextUp", "1", parent),
GetUserView(SpecialFolder.TvLatest, "Latest", "2", parent), GetUserView(CollectionType.TvLatest, "Latest", "2", parent),
GetUserView(SpecialFolder.TvShowSeries, "Shows", "3", parent), GetUserView(CollectionType.TvShowSeries, "Shows", "3", parent),
GetUserView(SpecialFolder.TvFavoriteSeries, "HeaderFavoriteShows", "4", parent), GetUserView(CollectionType.TvFavoriteSeries, "HeaderFavoriteShows", "4", parent),
GetUserView(SpecialFolder.TvFavoriteEpisodes, "HeaderFavoriteEpisodes", "5", parent), GetUserView(CollectionType.TvFavoriteEpisodes, "HeaderFavoriteEpisodes", "5", parent),
GetUserView(SpecialFolder.TvGenres, "Genres", "6", parent) GetUserView(CollectionType.TvGenres, "Genres", "6", parent)
}; };
return GetResult(list, query); return GetResult(list, query);
@ -330,7 +330,7 @@ namespace MediaBrowser.Controller.Entities
private QueryResult<BaseItem> GetTvNextUp(Folder parent, InternalItemsQuery query) private QueryResult<BaseItem> GetTvNextUp(Folder parent, InternalItemsQuery query)
{ {
var parentFolders = GetMediaFolders(parent, query.User, new[] { CollectionType.TvShows, string.Empty }); var parentFolders = GetMediaFolders(parent, query.User, new[] { CollectionType.TvShows });
var result = _tvSeriesManager.GetNextUp( var result = _tvSeriesManager.GetNextUp(
new NextUpQuery new NextUpQuery
@ -392,7 +392,7 @@ namespace MediaBrowser.Controller.Entities
} }
}) })
.Where(i => i is not null) .Where(i => i is not null)
.Select(i => GetUserViewWithName(SpecialFolder.TvGenre, i.SortName, parent)); .Select(i => GetUserViewWithName(CollectionType.TvGenre, i.SortName, parent));
return GetResult(genres, query); return GetResult(genres, query);
} }
@ -943,7 +943,7 @@ namespace MediaBrowser.Controller.Entities
.Where(i => user.IsFolderGrouped(i.Id) && UserView.IsEligibleForGrouping(i)); .Where(i => user.IsFolderGrouped(i.Id) && UserView.IsEligibleForGrouping(i));
} }
private BaseItem[] GetMediaFolders(User user, IEnumerable<string> viewTypes) private BaseItem[] GetMediaFolders(User user, IEnumerable<CollectionType> viewTypes)
{ {
if (user is null) if (user is null)
{ {
@ -952,7 +952,7 @@ namespace MediaBrowser.Controller.Entities
{ {
var folder = i as ICollectionFolder; var folder = i as ICollectionFolder;
return folder is not null && viewTypes.Contains(folder.CollectionType ?? string.Empty, StringComparison.OrdinalIgnoreCase); return folder?.CollectionType is not null && viewTypes.Contains(folder.CollectionType.Value);
}).ToArray(); }).ToArray();
} }
@ -961,11 +961,11 @@ namespace MediaBrowser.Controller.Entities
{ {
var folder = i as ICollectionFolder; var folder = i as ICollectionFolder;
return folder is not null && viewTypes.Contains(folder.CollectionType ?? string.Empty, StringComparison.OrdinalIgnoreCase); return folder?.CollectionType is not null && viewTypes.Contains(folder.CollectionType.Value);
}).ToArray(); }).ToArray();
} }
private BaseItem[] GetMediaFolders(Folder parent, User user, IEnumerable<string> viewTypes) private BaseItem[] GetMediaFolders(Folder parent, User user, IEnumerable<CollectionType> viewTypes)
{ {
if (parent is null || parent is UserView) if (parent is null || parent is UserView)
{ {
@ -975,12 +975,12 @@ namespace MediaBrowser.Controller.Entities
return new BaseItem[] { parent }; return new BaseItem[] { parent };
} }
private UserView GetUserViewWithName(string type, string sortName, BaseItem parent) private UserView GetUserViewWithName(CollectionType? type, string sortName, BaseItem parent)
{ {
return _userViewManager.GetUserSubView(parent.Id, parent.Id.ToString("N", CultureInfo.InvariantCulture), type, sortName); return _userViewManager.GetUserSubView(parent.Id, type, parent.Id.ToString("N", CultureInfo.InvariantCulture), sortName);
} }
private UserView GetUserView(string type, string localizationKey, string sortName, BaseItem parent) private UserView GetUserView(CollectionType? type, string localizationKey, string sortName, BaseItem parent)
{ {
return _userViewManager.GetUserSubView(parent.Id, type, localizationKey, sortName); return _userViewManager.GetUserSubView(parent.Id, type, localizationKey, sortName);
} }

@ -79,7 +79,7 @@ namespace MediaBrowser.Controller.Library
IDirectoryService directoryService, IDirectoryService directoryService,
Folder parent, Folder parent,
LibraryOptions libraryOptions, LibraryOptions libraryOptions,
string collectionType = null); CollectionType? collectionType = null);
/// <summary> /// <summary>
/// Gets a Person. /// Gets a Person.
@ -256,28 +256,28 @@ namespace MediaBrowser.Controller.Library
/// </summary> /// </summary>
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
/// <returns>System.String.</returns> /// <returns>System.String.</returns>
string GetContentType(BaseItem item); CollectionType? GetContentType(BaseItem item);
/// <summary> /// <summary>
/// Gets the type of the inherited content. /// Gets the type of the inherited content.
/// </summary> /// </summary>
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
/// <returns>System.String.</returns> /// <returns>System.String.</returns>
string GetInheritedContentType(BaseItem item); CollectionType? GetInheritedContentType(BaseItem item);
/// <summary> /// <summary>
/// Gets the type of the configured content. /// Gets the type of the configured content.
/// </summary> /// </summary>
/// <param name="item">The item.</param> /// <param name="item">The item.</param>
/// <returns>System.String.</returns> /// <returns>System.String.</returns>
string GetConfiguredContentType(BaseItem item); CollectionType? GetConfiguredContentType(BaseItem item);
/// <summary> /// <summary>
/// Gets the type of the configured content. /// Gets the type of the configured content.
/// </summary> /// </summary>
/// <param name="path">The path.</param> /// <param name="path">The path.</param>
/// <returns>System.String.</returns> /// <returns>System.String.</returns>
string GetConfiguredContentType(string path); CollectionType? GetConfiguredContentType(string path);
/// <summary> /// <summary>
/// Normalizes the root path list. /// Normalizes the root path list.
@ -329,7 +329,7 @@ namespace MediaBrowser.Controller.Library
User user, User user,
string name, string name,
Guid parentId, Guid parentId,
string viewType, CollectionType? viewType,
string sortName); string sortName);
/// <summary> /// <summary>
@ -343,7 +343,7 @@ namespace MediaBrowser.Controller.Library
UserView GetNamedView( UserView GetNamedView(
User user, User user,
string name, string name,
string viewType, CollectionType? viewType,
string sortName); string sortName);
/// <summary> /// <summary>
@ -355,7 +355,7 @@ namespace MediaBrowser.Controller.Library
/// <returns>The named view.</returns> /// <returns>The named view.</returns>
UserView GetNamedView( UserView GetNamedView(
string name, string name,
string viewType, CollectionType viewType,
string sortName); string sortName);
/// <summary> /// <summary>
@ -370,7 +370,7 @@ namespace MediaBrowser.Controller.Library
UserView GetNamedView( UserView GetNamedView(
string name, string name,
Guid parentId, Guid parentId,
string viewType, CollectionType? viewType,
string sortName, string sortName,
string uniqueId); string uniqueId);
@ -383,7 +383,7 @@ namespace MediaBrowser.Controller.Library
/// <returns>The shadow view.</returns> /// <returns>The shadow view.</returns>
UserView GetShadowView( UserView GetShadowView(
BaseItem parent, BaseItem parent,
string viewType, CollectionType? viewType,
string sortName); string sortName);
/// <summary> /// <summary>

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Library; using MediaBrowser.Model.Library;
@ -28,7 +29,7 @@ namespace MediaBrowser.Controller.Library
/// <param name="localizationKey">Localization key to use.</param> /// <param name="localizationKey">Localization key to use.</param>
/// <param name="sortName">Sort to use.</param> /// <param name="sortName">Sort to use.</param>
/// <returns>User view.</returns> /// <returns>User view.</returns>
UserView GetUserSubView(Guid parentId, string type, string localizationKey, string sortName); UserView GetUserSubView(Guid parentId, CollectionType? type, string localizationKey, string sortName);
/// <summary> /// <summary>
/// Gets latest items. /// Gets latest items.

@ -5,6 +5,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
@ -120,7 +121,7 @@ namespace MediaBrowser.Controller.Library
} }
} }
public string CollectionType { get; set; } public CollectionType? CollectionType { get; set; }
public bool HasParent<T>() public bool HasParent<T>()
where T : Folder where T : Folder
@ -220,7 +221,7 @@ namespace MediaBrowser.Controller.Library
return GetFileSystemEntryByName(name) is not null; return GetFileSystemEntryByName(name) is not null;
} }
public string GetCollectionType() public CollectionType? GetCollectionType()
{ {
return CollectionType; return CollectionType;
} }
@ -229,7 +230,7 @@ namespace MediaBrowser.Controller.Library
/// Gets the configured content type for the path. /// Gets the configured content type for the path.
/// </summary> /// </summary>
/// <returns>The configured content type.</returns> /// <returns>The configured content type.</returns>
public string GetConfiguredContentType() public CollectionType? GetConfiguredContentType()
{ {
return _libraryManager.GetConfiguredContentType(Path); return _libraryManager.GetConfiguredContentType(Path);
} }

@ -1,6 +1,7 @@
#pragma warning disable CS1591 #pragma warning disable CS1591
using System.Collections.Generic; using System.Collections.Generic;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Providers;
@ -32,7 +33,7 @@ namespace MediaBrowser.Controller.Resolvers
MultiItemResolverResult ResolveMultiple( MultiItemResolverResult ResolveMultiple(
Folder parent, Folder parent,
List<FileSystemMetadata> files, List<FileSystemMetadata> files,
string collectionType, CollectionType? collectionType,
IDirectoryService directoryService); IDirectoryService directoryService);
} }

@ -420,7 +420,7 @@ namespace MediaBrowser.Model.Dto
/// Gets or sets the type of the collection. /// Gets or sets the type of the collection.
/// </summary> /// </summary>
/// <value>The type of the collection.</value> /// <value>The type of the collection.</value>
public string CollectionType { get; set; } public CollectionType? CollectionType { get; set; }
/// <summary> /// <summary>
/// Gets or sets the display order. /// Gets or sets the display order.

@ -2,6 +2,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Jellyfin.Data.Enums;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Providers; using MediaBrowser.Model.Providers;
@ -27,7 +28,7 @@ namespace MediaBrowser.Model.Dto
public IReadOnlyList<ExternalIdInfo> ExternalIdInfos { get; set; } public IReadOnlyList<ExternalIdInfo> ExternalIdInfos { get; set; }
public string? ContentType { get; set; } public CollectionType? ContentType { get; set; }
public IReadOnlyList<NameValuePair> ContentTypeOptions { get; set; } public IReadOnlyList<NameValuePair> ContentTypeOptions { get; set; }
} }

@ -1,27 +0,0 @@
#pragma warning disable CS1591
namespace MediaBrowser.Model.Entities
{
public static class CollectionType
{
public const string Movies = "movies";
public const string TvShows = "tvshows";
public const string Music = "music";
public const string MusicVideos = "musicvideos";
public const string Trailers = "trailers";
public const string HomeVideos = "homevideos";
public const string BoxSets = "boxsets";
public const string Books = "books";
public const string Photos = "photos";
public const string LiveTv = "livetv";
public const string Playlists = "playlists";
public const string Folders = "folders";
}
}

@ -1,6 +1,7 @@
#pragma warning disable CS1591 #pragma warning disable CS1591
using System; using System;
using Jellyfin.Data.Enums;
namespace MediaBrowser.Model.Library namespace MediaBrowser.Model.Library
{ {
@ -9,7 +10,7 @@ namespace MediaBrowser.Model.Library
public UserViewQuery() public UserViewQuery()
{ {
IncludeExternalContent = true; IncludeExternalContent = true;
PresetViews = Array.Empty<string>(); PresetViews = Array.Empty<CollectionType?>();
} }
/// <summary> /// <summary>
@ -30,6 +31,6 @@ namespace MediaBrowser.Model.Library
/// <value><c>true</c> if [include hidden]; otherwise, <c>false</c>.</value> /// <value><c>true</c> if [include hidden]; otherwise, <c>false</c>.</value>
public bool IncludeHidden { get; set; } public bool IncludeHidden { get; set; }
public string[] PresetViews { get; set; } public CollectionType?[] PresetViews { get; set; }
} }
} }

@ -1,6 +1,7 @@
using System.Linq; using System.Linq;
using Emby.Naming.Common; using Emby.Naming.Common;
using Emby.Server.Implementations.Library.Resolvers.Audio; using Emby.Server.Implementations.Library.Resolvers.Audio;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
@ -62,7 +63,7 @@ public class AudioResolverTests
null, null,
Mock.Of<ILibraryManager>()) Mock.Of<ILibraryManager>())
{ {
CollectionType = "books", CollectionType = CollectionType.Books,
FileInfo = new FileSystemMetadata FileInfo = new FileSystemMetadata
{ {
FullName = parent, FullName = parent,

@ -1,5 +1,6 @@
using Emby.Naming.Common; using Emby.Naming.Common;
using Emby.Server.Implementations.Library.Resolvers.TV; using Emby.Server.Implementations.Library.Resolvers.TV;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller; using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Entities.TV;

Loading…
Cancel
Save