From 52230d1c30b76f34132c8c3ad21a09deea72d9d8 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Sat, 4 Feb 2023 17:56:12 +0100 Subject: Return NotFound when itemId isn't found --- MediaBrowser.Controller/Library/IUserManager.cs | 10 ++++------ MediaBrowser.Controller/Library/LibraryManagerExtensions.cs | 4 +--- 2 files changed, 5 insertions(+), 9 deletions(-) (limited to 'MediaBrowser.Controller/Library') diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs index 993e3e18f9..37b4afcf32 100644 --- a/MediaBrowser.Controller/Library/IUserManager.cs +++ b/MediaBrowser.Controller/Library/IUserManager.cs @@ -1,5 +1,3 @@ -#nullable disable - #pragma warning disable CS1591 using System; @@ -47,14 +45,14 @@ namespace MediaBrowser.Controller.Library /// The id. /// The user with the specified Id, or null if the user doesn't exist. /// id is an empty Guid. - User GetUserById(Guid id); + User? GetUserById(Guid id); /// /// Gets the name of the user by. /// /// The name. /// User. - User GetUserByName(string name); + User? GetUserByName(string name); /// /// Renames the user. @@ -128,7 +126,7 @@ namespace MediaBrowser.Controller.Library /// The user. /// The remote end point. /// UserDto. - UserDto GetUserDto(User user, string remoteEndPoint = null); + UserDto GetUserDto(User user, string? remoteEndPoint = null); /// /// Authenticates the user. @@ -139,7 +137,7 @@ namespace MediaBrowser.Controller.Library /// Remove endpoint to use. /// Specifies if a user session. /// User wrapped in awaitable task. - Task AuthenticateUser(string username, string password, string passwordSha1, string remoteEndPoint, bool isUserSession); + Task AuthenticateUser(string username, string password, string passwordSha1, string remoteEndPoint, bool isUserSession); /// /// Starts the forgot password process. diff --git a/MediaBrowser.Controller/Library/LibraryManagerExtensions.cs b/MediaBrowser.Controller/Library/LibraryManagerExtensions.cs index 7bc8fa5abd..6d2c3c3d29 100644 --- a/MediaBrowser.Controller/Library/LibraryManagerExtensions.cs +++ b/MediaBrowser.Controller/Library/LibraryManagerExtensions.cs @@ -1,5 +1,3 @@ -#nullable disable - #pragma warning disable CS1591 using System; @@ -9,7 +7,7 @@ namespace MediaBrowser.Controller.Library { public static class LibraryManagerExtensions { - public static BaseItem GetItemById(this ILibraryManager manager, string id) + public static BaseItem? GetItemById(this ILibraryManager manager, string id) { return manager.GetItemById(new Guid(id)); } -- cgit v1.2.3 From 160baa02fd9a2e7b4e2b3dcc28769274d0588413 Mon Sep 17 00:00:00 2001 From: Joe Rogers <1337joe@gmail.com> Date: Mon, 6 Mar 2023 22:18:26 -0500 Subject: Remove some BaseItem references to make ItemResolveArgs more usable for testing. --- Emby.Server.Implementations/Library/LibraryManager.cs | 2 +- MediaBrowser.Controller/Entities/AggregateFolder.cs | 2 +- MediaBrowser.Controller/Entities/CollectionFolder.cs | 2 +- MediaBrowser.Controller/Library/ItemResolveArgs.cs | 17 +++++++---------- .../Library/EpisodeResolverTest.cs | 6 ++++-- .../Library/MovieResolverTests.cs | 3 ++- 6 files changed, 16 insertions(+), 16 deletions(-) (limited to 'MediaBrowser.Controller/Library') diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 66bd68ddd0..9fa4d3599f 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -537,7 +537,7 @@ namespace Emby.Server.Implementations.Library collectionType = GetContentTypeOverride(fullPath, true); } - var args = new ItemResolveArgs(_configurationManager.ApplicationPaths, directoryService) + var args = new ItemResolveArgs(_configurationManager.ApplicationPaths, directoryService, this) { Parent = parent, FileInfo = fileInfo, diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs index 08c622cde0..aacb38607e 100644 --- a/MediaBrowser.Controller/Entities/AggregateFolder.cs +++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs @@ -120,7 +120,7 @@ namespace MediaBrowser.Controller.Entities var path = ContainingFolderPath; - var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths, directoryService) + var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths, directoryService, LibraryManager) { FileInfo = FileSystem.GetDirectoryInfo(path) }; diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs index 5ac619d8f5..ff17797179 100644 --- a/MediaBrowser.Controller/Entities/CollectionFolder.cs +++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs @@ -288,7 +288,7 @@ namespace MediaBrowser.Controller.Entities { var path = ContainingFolderPath; - var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths, directoryService) + var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths, directoryService, LibraryManager) { FileInfo = FileSystem.GetDirectoryInfo(path), Parent = GetParent() as Folder, diff --git a/MediaBrowser.Controller/Library/ItemResolveArgs.cs b/MediaBrowser.Controller/Library/ItemResolveArgs.cs index 01986d3032..730d89356d 100644 --- a/MediaBrowser.Controller/Library/ItemResolveArgs.cs +++ b/MediaBrowser.Controller/Library/ItemResolveArgs.cs @@ -23,6 +23,7 @@ namespace MediaBrowser.Controller.Library /// private readonly IServerApplicationPaths _appPaths; + private readonly ILibraryManager _libraryManager; private LibraryOptions _libraryOptions; /// @@ -30,10 +31,12 @@ namespace MediaBrowser.Controller.Library /// /// The app paths. /// The directory service. - public ItemResolveArgs(IServerApplicationPaths appPaths, IDirectoryService directoryService) + /// The library manager. + public ItemResolveArgs(IServerApplicationPaths appPaths, IDirectoryService directoryService, ILibraryManager libraryManager) { _appPaths = appPaths; DirectoryService = directoryService; + _libraryManager = libraryManager; } // TODO remove dependencies as properties, they should be injected where it makes sense @@ -47,7 +50,7 @@ namespace MediaBrowser.Controller.Library public LibraryOptions LibraryOptions { - get => _libraryOptions ??= Parent is null ? new LibraryOptions() : BaseItem.LibraryManager.GetLibraryOptions(Parent); + get => _libraryOptions ??= Parent is null ? new LibraryOptions() : _libraryManager.GetLibraryOptions(Parent); set => _libraryOptions = value; } @@ -231,21 +234,15 @@ namespace MediaBrowser.Controller.Library /// /// Gets the configured content type for the path. /// - /// - /// This is subject to future refactoring as it relies on a static property in BaseItem. - /// /// The configured content type. public string GetConfiguredContentType() { - return BaseItem.LibraryManager.GetConfiguredContentType(Path); + return _libraryManager.GetConfiguredContentType(Path); } /// /// Gets the file system children that do not hit the ignore file check. /// - /// - /// This is subject to future refactoring as it relies on a static property in BaseItem. - /// /// The file system children that are not ignored. public IEnumerable GetActualFileSystemChildren() { @@ -253,7 +250,7 @@ namespace MediaBrowser.Controller.Library for (var i = 0; i < numberOfChildren; i++) { var child = FileSystemChildren[i]; - if (BaseItem.LibraryManager.IgnoreFile(child, Parent)) + if (_libraryManager.IgnoreFile(child, Parent)) { continue; } diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs index 286ba04059..65f19a051a 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs @@ -25,7 +25,8 @@ namespace Jellyfin.Server.Implementations.Tests.Library var episodeResolver = new EpisodeResolver(Mock.Of>(), _namingOptions); var itemResolveArgs = new ItemResolveArgs( Mock.Of(), - Mock.Of()) + Mock.Of(), + null) { Parent = parent, CollectionType = CollectionType.TvShows, @@ -48,7 +49,8 @@ namespace Jellyfin.Server.Implementations.Tests.Library var episodeResolver = new EpisodeResolverMock(Mock.Of>(), _namingOptions); var itemResolveArgs = new ItemResolveArgs( Mock.Of(), - Mock.Of()) + Mock.Of(), + null) { Parent = series, CollectionType = CollectionType.TvShows, diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/MovieResolverTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/MovieResolverTests.cs index efc3ac0c2a..f96bd6138e 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Library/MovieResolverTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Library/MovieResolverTests.cs @@ -21,7 +21,8 @@ public class MovieResolverTests var movieResolver = new MovieResolver(Mock.Of(), Mock.Of>(), _namingOptions); var itemResolveArgs = new ItemResolveArgs( Mock.Of(), - Mock.Of()) + Mock.Of(), + null) { Parent = null, FileInfo = new FileSystemMetadata -- cgit v1.2.3 From 1c3a97bf6adadf4e3b22177e1e965691637d0426 Mon Sep 17 00:00:00 2001 From: Joe Rogers <1337joe@gmail.com> Date: Mon, 6 Mar 2023 23:00:55 -0500 Subject: Inject IDirectoryService where needed instead of passing it through ItemResolveArgs --- Emby.Server.Implementations/Library/LibraryManager.cs | 8 +++++--- .../Library/Resolvers/Audio/MusicAlbumResolver.cs | 7 +++++-- .../Library/Resolvers/Audio/MusicArtistResolver.cs | 15 +++++++++------ .../Library/Resolvers/BaseVideoResolver.cs | 7 +++++-- .../Library/Resolvers/ExtraResolver.cs | 8 +++++--- .../Library/Resolvers/GenericVideoResolver.cs | 6 ++++-- .../Library/Resolvers/Movies/MovieResolver.cs | 13 +++++++------ .../Library/Resolvers/PhotoResolver.cs | 18 ++++++++++++++---- .../Library/Resolvers/TV/EpisodeResolver.cs | 6 ++++-- MediaBrowser.Controller/Entities/AggregateFolder.cs | 2 +- MediaBrowser.Controller/Entities/CollectionFolder.cs | 2 +- MediaBrowser.Controller/Library/ItemResolveArgs.cs | 10 ++-------- .../Library/EpisodeResolverTest.cs | 8 +++----- .../Library/MovieResolverTests.cs | 3 +-- 14 files changed, 66 insertions(+), 47 deletions(-) (limited to 'MediaBrowser.Controller/Library') diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 9fa4d3599f..e5c520ca2b 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -113,6 +113,7 @@ namespace Emby.Server.Implementations.Library /// The image processor. /// The memory cache. /// The naming options. + /// The directory service. public LibraryManager( IServerApplicationHost appHost, ILoggerFactory loggerFactory, @@ -128,7 +129,8 @@ namespace Emby.Server.Implementations.Library IItemRepository itemRepository, IImageProcessor imageProcessor, IMemoryCache memoryCache, - NamingOptions namingOptions) + NamingOptions namingOptions, + IDirectoryService directoryService) { _appHost = appHost; _logger = loggerFactory.CreateLogger(); @@ -146,7 +148,7 @@ namespace Emby.Server.Implementations.Library _memoryCache = memoryCache; _namingOptions = namingOptions; - _extraResolver = new ExtraResolver(loggerFactory.CreateLogger(), namingOptions); + _extraResolver = new ExtraResolver(loggerFactory.CreateLogger(), namingOptions, directoryService); _configurationManager.ConfigurationUpdated += ConfigurationUpdated; @@ -537,7 +539,7 @@ namespace Emby.Server.Implementations.Library collectionType = GetContentTypeOverride(fullPath, true); } - var args = new ItemResolveArgs(_configurationManager.ApplicationPaths, directoryService, this) + var args = new ItemResolveArgs(_configurationManager.ApplicationPaths, this) { Parent = parent, FileInfo = fileInfo, diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs index a922e36855..bbc70701cb 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs @@ -25,16 +25,19 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio { private readonly ILogger _logger; private readonly NamingOptions _namingOptions; + private readonly IDirectoryService _directoryService; /// /// Initializes a new instance of the class. /// /// The logger. /// The naming options. - public MusicAlbumResolver(ILogger logger, NamingOptions namingOptions) + /// The directory service. + public MusicAlbumResolver(ILogger logger, NamingOptions namingOptions, IDirectoryService directoryService) { _logger = logger; _namingOptions = namingOptions; + _directoryService = directoryService; } /// @@ -109,7 +112,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio } // If args contains music it's a music album - if (ContainsMusic(args.FileSystemChildren, true, args.DirectoryService)) + if (ContainsMusic(args.FileSystemChildren, true, _directoryService)) { return true; } diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs index 2538c2b5b4..c858dc53d9 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Emby.Naming.Common; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Model.Entities; using Microsoft.Extensions.Logging; @@ -18,19 +19,23 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio public class MusicArtistResolver : ItemResolver { private readonly ILogger _logger; - private NamingOptions _namingOptions; + private readonly NamingOptions _namingOptions; + private readonly IDirectoryService _directoryService; /// /// Initializes a new instance of the class. /// /// Instance of the interface. /// The . + /// The directory service. public MusicArtistResolver( ILogger logger, - NamingOptions namingOptions) + NamingOptions namingOptions, + IDirectoryService directoryService) { _logger = logger; _namingOptions = namingOptions; + _directoryService = directoryService; } /// @@ -78,9 +83,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio return null; } - var directoryService = args.DirectoryService; - - var albumResolver = new MusicAlbumResolver(_logger, _namingOptions); + var albumResolver = new MusicAlbumResolver(_logger, _namingOptions, _directoryService); var directories = args.FileSystemChildren.Where(i => i.IsDirectory); @@ -97,7 +100,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio } // If we contain a music album assume we are an artist folder - if (albumResolver.IsMusicAlbum(fileSystemInfo.FullName, directoryService)) + if (albumResolver.IsMusicAlbum(fileSystemInfo.FullName, _directoryService)) { // Stop once we see a music album state.Stop(); diff --git a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs index e8615e7db7..9b133bef48 100644 --- a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs @@ -25,14 +25,17 @@ namespace Emby.Server.Implementations.Library.Resolvers { private readonly ILogger _logger; - protected BaseVideoResolver(ILogger logger, NamingOptions namingOptions) + protected BaseVideoResolver(ILogger logger, NamingOptions namingOptions, IDirectoryService directoryService) { _logger = logger; NamingOptions = namingOptions; + DirectoryService = directoryService; } protected NamingOptions NamingOptions { get; } + protected IDirectoryService DirectoryService { get; } + /// /// Resolves the specified args. /// @@ -65,7 +68,7 @@ namespace Emby.Server.Implementations.Library.Resolvers var filename = child.Name; if (child.IsDirectory) { - if (IsDvdDirectory(child.FullName, filename, args.DirectoryService)) + if (IsDvdDirectory(child.FullName, filename, DirectoryService)) { videoType = VideoType.Dvd; } diff --git a/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs b/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs index 30c52e19d3..0b255f673b 100644 --- a/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/ExtraResolver.cs @@ -4,6 +4,7 @@ using System.IO; using Emby.Naming.Common; using Emby.Naming.Video; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Model.Entities; using Microsoft.Extensions.Logging; @@ -25,11 +26,12 @@ namespace Emby.Server.Implementations.Library.Resolvers /// /// The logger. /// An instance of . - public ExtraResolver(ILogger logger, NamingOptions namingOptions) + /// The directory service. + public ExtraResolver(ILogger logger, NamingOptions namingOptions, IDirectoryService directoryService) { _namingOptions = namingOptions; - _trailerResolvers = new IItemResolver[] { new GenericVideoResolver(logger, namingOptions) }; - _videoResolvers = new IItemResolver[] { new GenericVideoResolver /// The app paths. - /// The directory service. /// The library manager. - public ItemResolveArgs(IServerApplicationPaths appPaths, IDirectoryService directoryService, ILibraryManager libraryManager) + public ItemResolveArgs(IServerApplicationPaths appPaths, ILibraryManager libraryManager) { _appPaths = appPaths; - DirectoryService = directoryService; _libraryManager = libraryManager; } - // TODO remove dependencies as properties, they should be injected where it makes sense - public IDirectoryService DirectoryService { get; } - /// /// Gets or sets the file system children. /// diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs index 65f19a051a..6d0ed7bbba 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs @@ -22,10 +22,9 @@ namespace Jellyfin.Server.Implementations.Tests.Library { var parent = new Folder { Name = "extras" }; - var episodeResolver = new EpisodeResolver(Mock.Of>(), _namingOptions); + var episodeResolver = new EpisodeResolver(Mock.Of>(), _namingOptions, Mock.Of()); var itemResolveArgs = new ItemResolveArgs( Mock.Of(), - Mock.Of(), null) { Parent = parent, @@ -46,10 +45,9 @@ namespace Jellyfin.Server.Implementations.Tests.Library // Have to create a mock because of moq proxies not being castable to a concrete implementation // https://github.com/jellyfin/jellyfin/blob/ab0cff8556403e123642dc9717ba778329554634/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs#L48 - var episodeResolver = new EpisodeResolverMock(Mock.Of>(), _namingOptions); + var episodeResolver = new EpisodeResolverMock(Mock.Of>(), _namingOptions, Mock.Of()); var itemResolveArgs = new ItemResolveArgs( Mock.Of(), - Mock.Of(), null) { Parent = series, @@ -64,7 +62,7 @@ namespace Jellyfin.Server.Implementations.Tests.Library private sealed class EpisodeResolverMock : EpisodeResolver { - public EpisodeResolverMock(ILogger logger, NamingOptions namingOptions) : base(logger, namingOptions) + public EpisodeResolverMock(ILogger logger, NamingOptions namingOptions, IDirectoryService directoryService) : base(logger, namingOptions, directoryService) { } diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/MovieResolverTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/MovieResolverTests.cs index f96bd6138e..aed584355c 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Library/MovieResolverTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Library/MovieResolverTests.cs @@ -18,10 +18,9 @@ public class MovieResolverTests [Fact] public void Resolve_GivenLocalAlternateVersion_ResolvesToVideo() { - var movieResolver = new MovieResolver(Mock.Of(), Mock.Of>(), _namingOptions); + var movieResolver = new MovieResolver(Mock.Of(), Mock.Of>(), _namingOptions, Mock.Of()); var itemResolveArgs = new ItemResolveArgs( Mock.Of(), - Mock.Of(), null) { Parent = null, -- cgit v1.2.3 From 716bcc6410c91edd755ea294f5908b7f383fc326 Mon Sep 17 00:00:00 2001 From: cvium Date: Fri, 26 May 2023 19:40:40 +0200 Subject: chore: deprecate EasyPassword as it isn't very secure --- Jellyfin.Api/Controllers/UserController.cs | 26 ++-------------- Jellyfin.Data/Entities/User.cs | 10 ------ .../Migrations/JellyfinDbModelSnapshot.cs | 34 +++++++++----------- .../Users/DefaultPasswordResetProvider.cs | 2 -- .../Users/UserManager.cs | 36 ---------------------- .../Migrations/Routines/MigrateUserDb.cs | 1 - MediaBrowser.Controller/Library/IUserManager.cs | 16 ---------- MediaBrowser.Model/Dto/UserDto.cs | 1 + 8 files changed, 18 insertions(+), 108 deletions(-) (limited to 'MediaBrowser.Controller/Library') diff --git a/Jellyfin.Api/Controllers/UserController.cs b/Jellyfin.Api/Controllers/UserController.cs index e495288670..f7202a34c6 100644 --- a/Jellyfin.Api/Controllers/UserController.cs +++ b/Jellyfin.Api/Controllers/UserController.cs @@ -323,36 +323,16 @@ public class UserController : BaseJellyfinApiController /// User not found. /// A indicating success or a or a on failure. [HttpPost("{userId}/EasyPassword")] + [Obsolete("Use Quick Connect instead")] [Authorize] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task UpdateUserEasyPassword( + public ActionResult UpdateUserEasyPassword( [FromRoute, Required] Guid userId, [FromBody, Required] UpdateUserEasyPassword request) { - if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true)) - { - return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update the easy password."); - } - - var user = _userManager.GetUserById(userId); - - if (user is null) - { - return NotFound("User not found"); - } - - if (request.ResetPassword) - { - await _userManager.ResetEasyPassword(user).ConfigureAwait(false); - } - else - { - await _userManager.ChangeEasyPassword(user, request.NewPw ?? string.Empty, request.NewPassword ?? string.Empty).ConfigureAwait(false); - } - - return NoContent(); + return BadRequest("Deprecated"); } /// diff --git a/Jellyfin.Data/Entities/User.cs b/Jellyfin.Data/Entities/User.cs index 606e1b5427..58ddaaf83a 100644 --- a/Jellyfin.Data/Entities/User.cs +++ b/Jellyfin.Data/Entities/User.cs @@ -91,16 +91,6 @@ namespace Jellyfin.Data.Entities [StringLength(65535)] public string? Password { get; set; } - /// - /// Gets or sets the user's easy password, or null if none is set. - /// - /// - /// Max length = 65535. - /// - [MaxLength(65535)] - [StringLength(65535)] - public string? EasyPassword { get; set; } - /// /// Gets or sets a value indicating whether the user must update their password. /// diff --git a/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs b/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs index dd5f7f0121..d23508096f 100644 --- a/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs +++ b/Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs @@ -15,9 +15,7 @@ namespace Jellyfin.Server.Implementations.Migrations protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder - .HasDefaultSchema("jellyfin") - .HasAnnotation("ProductVersion", "6.0.9"); + modelBuilder.HasAnnotation("ProductVersion", "7.0.5"); modelBuilder.Entity("Jellyfin.Data.Entities.AccessSchedule", b => { @@ -41,7 +39,7 @@ namespace Jellyfin.Server.Implementations.Migrations b.HasIndex("UserId"); - b.ToTable("AccessSchedules", "jellyfin"); + b.ToTable("AccessSchedules"); }); modelBuilder.Entity("Jellyfin.Data.Entities.ActivityLog", b => @@ -89,7 +87,7 @@ namespace Jellyfin.Server.Implementations.Migrations b.HasIndex("DateCreated"); - b.ToTable("ActivityLogs", "jellyfin"); + b.ToTable("ActivityLogs"); }); modelBuilder.Entity("Jellyfin.Data.Entities.CustomItemDisplayPreferences", b => @@ -121,7 +119,7 @@ namespace Jellyfin.Server.Implementations.Migrations b.HasIndex("UserId", "ItemId", "Client", "Key") .IsUnique(); - b.ToTable("CustomItemDisplayPreferences", "jellyfin"); + b.ToTable("CustomItemDisplayPreferences"); }); modelBuilder.Entity("Jellyfin.Data.Entities.DisplayPreferences", b => @@ -178,7 +176,7 @@ namespace Jellyfin.Server.Implementations.Migrations b.HasIndex("UserId", "ItemId", "Client") .IsUnique(); - b.ToTable("DisplayPreferences", "jellyfin"); + b.ToTable("DisplayPreferences"); }); modelBuilder.Entity("Jellyfin.Data.Entities.HomeSection", b => @@ -200,7 +198,7 @@ namespace Jellyfin.Server.Implementations.Migrations b.HasIndex("DisplayPreferencesId"); - b.ToTable("HomeSection", "jellyfin"); + b.ToTable("HomeSection"); }); modelBuilder.Entity("Jellyfin.Data.Entities.ImageInfo", b => @@ -225,7 +223,7 @@ namespace Jellyfin.Server.Implementations.Migrations b.HasIndex("UserId") .IsUnique(); - b.ToTable("ImageInfos", "jellyfin"); + b.ToTable("ImageInfos"); }); modelBuilder.Entity("Jellyfin.Data.Entities.ItemDisplayPreferences", b => @@ -269,7 +267,7 @@ namespace Jellyfin.Server.Implementations.Migrations b.HasIndex("UserId"); - b.ToTable("ItemDisplayPreferences", "jellyfin"); + b.ToTable("ItemDisplayPreferences"); }); modelBuilder.Entity("Jellyfin.Data.Entities.Permission", b => @@ -300,7 +298,7 @@ namespace Jellyfin.Server.Implementations.Migrations .IsUnique() .HasFilter("[UserId] IS NOT NULL"); - b.ToTable("Permissions", "jellyfin"); + b.ToTable("Permissions"); }); modelBuilder.Entity("Jellyfin.Data.Entities.Preference", b => @@ -333,7 +331,7 @@ namespace Jellyfin.Server.Implementations.Migrations .IsUnique() .HasFilter("[UserId] IS NOT NULL"); - b.ToTable("Preferences", "jellyfin"); + b.ToTable("Preferences"); }); modelBuilder.Entity("Jellyfin.Data.Entities.Security.ApiKey", b => @@ -362,7 +360,7 @@ namespace Jellyfin.Server.Implementations.Migrations b.HasIndex("AccessToken") .IsUnique(); - b.ToTable("ApiKeys", "jellyfin"); + b.ToTable("ApiKeys"); }); modelBuilder.Entity("Jellyfin.Data.Entities.Security.Device", b => @@ -420,7 +418,7 @@ namespace Jellyfin.Server.Implementations.Migrations b.HasIndex("UserId", "DeviceId"); - b.ToTable("Devices", "jellyfin"); + b.ToTable("Devices"); }); modelBuilder.Entity("Jellyfin.Data.Entities.Security.DeviceOptions", b => @@ -441,7 +439,7 @@ namespace Jellyfin.Server.Implementations.Migrations b.HasIndex("DeviceId") .IsUnique(); - b.ToTable("DeviceOptions", "jellyfin"); + b.ToTable("DeviceOptions"); }); modelBuilder.Entity("Jellyfin.Data.Entities.User", b => @@ -465,10 +463,6 @@ namespace Jellyfin.Server.Implementations.Migrations b.Property("DisplayMissingEpisodes") .HasColumnType("INTEGER"); - b.Property("EasyPassword") - .HasMaxLength(65535) - .HasColumnType("TEXT"); - b.Property("EnableAutoLogin") .HasColumnType("INTEGER"); @@ -554,7 +548,7 @@ namespace Jellyfin.Server.Implementations.Migrations b.HasIndex("Username") .IsUnique(); - b.ToTable("Users", "jellyfin"); + b.ToTable("Users"); }); modelBuilder.Entity("Jellyfin.Data.Entities.AccessSchedule", b => diff --git a/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs b/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs index 9601954671..cefbd0624d 100644 --- a/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs +++ b/Jellyfin.Server.Implementations/Users/DefaultPasswordResetProvider.cs @@ -114,8 +114,6 @@ namespace Jellyfin.Server.Implementations.Users await JsonSerializer.SerializeAsync(fileStream, spr).ConfigureAwait(false); } - user.EasyPassword = pin; - return new ForgotPasswordResult { Action = ForgotPasswordAction.PinCode, diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index c4756433e0..fa23fe148b 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -268,12 +268,6 @@ namespace Jellyfin.Server.Implementations.Users return ChangePassword(user, string.Empty); } - /// - public Task ResetEasyPassword(User user) - { - return ChangeEasyPassword(user, string.Empty, null); - } - /// public async Task ChangePassword(User user, string newPassword) { @@ -285,25 +279,6 @@ namespace Jellyfin.Server.Implementations.Users await _eventManager.PublishAsync(new UserPasswordChangedEventArgs(user)).ConfigureAwait(false); } - /// - public async Task ChangeEasyPassword(User user, string newPassword, string? newPasswordSha1) - { - if (newPassword is not null) - { - newPasswordSha1 = _cryptoProvider.CreatePasswordHash(newPassword).ToString(); - } - - if (string.IsNullOrWhiteSpace(newPasswordSha1)) - { - throw new ArgumentNullException(nameof(newPasswordSha1)); - } - - user.EasyPassword = newPasswordSha1; - await UpdateUserAsync(user).ConfigureAwait(false); - - await _eventManager.PublishAsync(new UserPasswordChangedEventArgs(user)).ConfigureAwait(false); - } - /// public UserDto GetUserDto(User user, string? remoteEndPoint = null) { @@ -315,7 +290,6 @@ namespace Jellyfin.Server.Implementations.Users ServerId = _appHost.SystemId, HasPassword = hasPassword, HasConfiguredPassword = hasPassword, - HasConfiguredEasyPassword = !string.IsNullOrEmpty(user.EasyPassword), EnableAutoLogin = user.EnableAutoLogin, LastLoginDate = user.LastLoginDate, LastActivityDate = user.LastActivityDate, @@ -832,16 +806,6 @@ namespace Jellyfin.Server.Implementations.Users } } - if (!success - && _networkManager.IsInLocalNetwork(remoteEndPoint) - && user?.EnableLocalPassword == true - && !string.IsNullOrEmpty(user.EasyPassword)) - { - // Check easy password - var passwordHash = PasswordHash.Parse(user.EasyPassword); - success = _cryptoProvider.Verify(passwordHash, password); - } - return (authenticationProvider, username, success); } diff --git a/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs index 9bf1e6b808..0186500a12 100644 --- a/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs +++ b/Jellyfin.Server/Migrations/Routines/MigrateUserDb.cs @@ -127,7 +127,6 @@ namespace Jellyfin.Server.Migrations.Routines RememberSubtitleSelections = config.RememberSubtitleSelections, SubtitleLanguagePreference = config.SubtitleLanguagePreference, Password = mockup.Password, - EasyPassword = mockup.EasyPassword, LastLoginDate = mockup.LastLoginDate, LastActivityDate = mockup.LastActivityDate }; diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs index 37b4afcf32..6d6a532dba 100644 --- a/MediaBrowser.Controller/Library/IUserManager.cs +++ b/MediaBrowser.Controller/Library/IUserManager.cs @@ -96,13 +96,6 @@ namespace MediaBrowser.Controller.Library /// Task. Task ResetPassword(User user); - /// - /// Resets the easy password. - /// - /// The user. - /// Task. - Task ResetEasyPassword(User user); - /// /// Changes the password. /// @@ -111,15 +104,6 @@ namespace MediaBrowser.Controller.Library /// Awaitable task. Task ChangePassword(User user, string newPassword); - /// - /// Changes the easy password. - /// - /// The user. - /// New password to use. - /// Hash of new password. - /// Task. - Task ChangeEasyPassword(User user, string newPassword, string newPasswordSha1); - /// /// Gets the user dto. /// diff --git a/MediaBrowser.Model/Dto/UserDto.cs b/MediaBrowser.Model/Dto/UserDto.cs index 256d7b10f1..05019741e0 100644 --- a/MediaBrowser.Model/Dto/UserDto.cs +++ b/MediaBrowser.Model/Dto/UserDto.cs @@ -66,6 +66,7 @@ namespace MediaBrowser.Model.Dto /// Gets or sets a value indicating whether this instance has configured easy password. /// /// true if this instance has configured easy password; otherwise, false. + [Obsolete("Easy Password has been replaced with Quick Connect")] public bool HasConfiguredEasyPassword { get; set; } /// -- cgit v1.2.3 From 3982b0e057cc692875ba35573197b86abf8d7adb Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Thu, 22 Jun 2023 05:01:47 +0200 Subject: Reduce bottlenecks scan code (#9863) --- Jellyfin.Api/Controllers/LibraryController.cs | 20 ++----- .../BaseItemManager/BaseItemManager.cs | 65 +++------------------- .../BaseItemManager/IBaseItemManager.cs | 5 -- .../Entities/Audio/MusicArtist.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 33 +++-------- MediaBrowser.Controller/Entities/Folder.cs | 38 +++---------- .../Library/MetadataConfigurationExtensions.cs | 17 ++++-- .../Providers/IProviderManager.cs | 17 ------ MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 5 +- .../Configuration/ServerConfiguration.cs | 8 +-- MediaBrowser.Providers/Manager/ProviderManager.cs | 63 ++++----------------- .../Plugins/StudioImages/StudiosImageProvider.cs | 8 +-- src/Jellyfin.Drawing/ImageProcessor.cs | 2 - 13 files changed, 64 insertions(+), 219 deletions(-) (limited to 'MediaBrowser.Controller/Library') diff --git a/Jellyfin.Api/Controllers/LibraryController.cs b/Jellyfin.Api/Controllers/LibraryController.cs index e094d2d774..46c0a8d527 100644 --- a/Jellyfin.Api/Controllers/LibraryController.cs +++ b/Jellyfin.Api/Controllers/LibraryController.cs @@ -969,12 +969,8 @@ public class LibraryController : BaseJellyfinApiController || string.Equals(name, "MusicBrainz", StringComparison.OrdinalIgnoreCase); } - var metadataOptions = _serverConfigurationManager.Configuration.MetadataOptions - .Where(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)) - .ToArray(); - - return metadataOptions.Length == 0 - || metadataOptions.Any(i => !i.DisabledMetadataFetchers.Contains(name, StringComparison.OrdinalIgnoreCase)); + var metadataOptions = _serverConfigurationManager.GetMetadataOptionsForType(type); + return metadataOptions is null || !metadataOptions.DisabledMetadataFetchers.Contains(name, StringComparison.OrdinalIgnoreCase); } private bool IsImageFetcherEnabledByDefault(string name, string type, bool isNewLibrary) @@ -995,15 +991,7 @@ public class LibraryController : BaseJellyfinApiController || string.Equals(name, "Image Extractor", StringComparison.OrdinalIgnoreCase); } - var metadataOptions = _serverConfigurationManager.Configuration.MetadataOptions - .Where(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)) - .ToArray(); - - if (metadataOptions.Length == 0) - { - return true; - } - - return metadataOptions.Any(i => !i.DisabledImageFetchers.Contains(name, StringComparison.OrdinalIgnoreCase)); + var metadataOptions = _serverConfigurationManager.GetMetadataOptionsForType(type); + return metadataOptions is null || !metadataOptions.DisabledImageFetchers.Contains(name, StringComparison.OrdinalIgnoreCase); } } diff --git a/MediaBrowser.Controller/BaseItemManager/BaseItemManager.cs b/MediaBrowser.Controller/BaseItemManager/BaseItemManager.cs index ed7c2c2c17..b263c173eb 100644 --- a/MediaBrowser.Controller/BaseItemManager/BaseItemManager.cs +++ b/MediaBrowser.Controller/BaseItemManager/BaseItemManager.cs @@ -1,11 +1,10 @@ using System; -using System.Diagnostics.CodeAnalysis; using System.Linq; -using System.Threading; using Jellyfin.Extensions; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; using MediaBrowser.Model.Configuration; namespace MediaBrowser.Controller.BaseItemManager @@ -15,8 +14,6 @@ namespace MediaBrowser.Controller.BaseItemManager { private readonly IServerConfigurationManager _serverConfigurationManager; - private int _metadataRefreshConcurrency; - /// /// Initializes a new instance of the class. /// @@ -24,16 +21,8 @@ namespace MediaBrowser.Controller.BaseItemManager public BaseItemManager(IServerConfigurationManager serverConfigurationManager) { _serverConfigurationManager = serverConfigurationManager; - - _metadataRefreshConcurrency = GetMetadataRefreshConcurrency(); - SetupMetadataThrottler(); - - _serverConfigurationManager.ConfigurationUpdated += OnConfigurationUpdated; } - /// - public SemaphoreSlim MetadataRefreshThrottler { get; private set; } - /// public bool IsMetadataFetcherEnabled(BaseItem baseItem, TypeOptions? libraryTypeOptions, string name) { @@ -51,12 +40,11 @@ namespace MediaBrowser.Controller.BaseItemManager if (libraryTypeOptions is not null) { - return libraryTypeOptions.MetadataFetchers.Contains(name.AsSpan(), StringComparison.OrdinalIgnoreCase); + return libraryTypeOptions.MetadataFetchers.Contains(name, StringComparison.OrdinalIgnoreCase); } - var itemConfig = _serverConfigurationManager.Configuration.MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, baseItem.GetType().Name, StringComparison.OrdinalIgnoreCase)); - - return itemConfig is null || !itemConfig.DisabledMetadataFetchers.Contains(name.AsSpan(), StringComparison.OrdinalIgnoreCase); + var itemConfig = _serverConfigurationManager.GetMetadataOptionsForType(baseItem.GetType().Name); + return itemConfig is null || !itemConfig.DisabledMetadataFetchers.Contains(name, StringComparison.OrdinalIgnoreCase); } /// @@ -76,50 +64,11 @@ namespace MediaBrowser.Controller.BaseItemManager if (libraryTypeOptions is not null) { - return libraryTypeOptions.ImageFetchers.Contains(name.AsSpan(), StringComparison.OrdinalIgnoreCase); - } - - var itemConfig = _serverConfigurationManager.Configuration.MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, baseItem.GetType().Name, StringComparison.OrdinalIgnoreCase)); - - return itemConfig is null || !itemConfig.DisabledImageFetchers.Contains(name.AsSpan(), StringComparison.OrdinalIgnoreCase); - } - - /// - /// Called when the configuration is updated. - /// It will refresh the metadata throttler if the relevant config changed. - /// - private void OnConfigurationUpdated(object? sender, EventArgs e) - { - int newMetadataRefreshConcurrency = GetMetadataRefreshConcurrency(); - if (_metadataRefreshConcurrency != newMetadataRefreshConcurrency) - { - _metadataRefreshConcurrency = newMetadataRefreshConcurrency; - SetupMetadataThrottler(); - } - } - - /// - /// Creates the metadata refresh throttler. - /// - [MemberNotNull(nameof(MetadataRefreshThrottler))] - private void SetupMetadataThrottler() - { - MetadataRefreshThrottler = new SemaphoreSlim(_metadataRefreshConcurrency); - } - - /// - /// Returns the metadata refresh concurrency. - /// - private int GetMetadataRefreshConcurrency() - { - var concurrency = _serverConfigurationManager.Configuration.LibraryMetadataRefreshConcurrency; - - if (concurrency <= 0) - { - concurrency = Environment.ProcessorCount; + return libraryTypeOptions.ImageFetchers.Contains(name, StringComparison.OrdinalIgnoreCase); } - return concurrency; + var itemConfig = _serverConfigurationManager.GetMetadataOptionsForType(baseItem.GetType().Name); + return itemConfig is null || !itemConfig.DisabledImageFetchers.Contains(name, StringComparison.OrdinalIgnoreCase); } } } diff --git a/MediaBrowser.Controller/BaseItemManager/IBaseItemManager.cs b/MediaBrowser.Controller/BaseItemManager/IBaseItemManager.cs index b07c80879d..ac20120d97 100644 --- a/MediaBrowser.Controller/BaseItemManager/IBaseItemManager.cs +++ b/MediaBrowser.Controller/BaseItemManager/IBaseItemManager.cs @@ -9,11 +9,6 @@ namespace MediaBrowser.Controller.BaseItemManager /// public interface IBaseItemManager { - /// - /// Gets the semaphore used to limit the amount of concurrent metadata refreshes. - /// - SemaphoreSlim MetadataRefreshThrottler { get; } - /// /// Is metadata fetcher enabled. /// diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index 15a79fa1fc..18d948a62f 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -59,7 +59,7 @@ namespace MediaBrowser.Controller.Entities.Audio { if (IsAccessedByName) { - return new List(); + return Enumerable.Empty(); } return base.Children; diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 1e868194e6..5018110035 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1244,14 +1244,6 @@ namespace MediaBrowser.Controller.Entities return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService(FileSystem)), cancellationToken); } - protected virtual void TriggerOnRefreshStart() - { - } - - protected virtual void TriggerOnRefreshComplete() - { - } - /// /// Overrides the base implementation to refresh metadata for local trailers. /// @@ -1260,8 +1252,6 @@ namespace MediaBrowser.Controller.Entities /// true if a provider reports we changed. public async Task RefreshMetadata(MetadataRefreshOptions options, CancellationToken cancellationToken) { - TriggerOnRefreshStart(); - var requiresSave = false; if (SupportsOwnedItems) @@ -1281,21 +1271,14 @@ namespace MediaBrowser.Controller.Entities } } - try - { - var refreshOptions = requiresSave - ? new MetadataRefreshOptions(options) - { - ForceSave = true - } - : options; + var refreshOptions = requiresSave + ? new MetadataRefreshOptions(options) + { + ForceSave = true + } + : options; - return await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false); - } - finally - { - TriggerOnRefreshComplete(); - } + return await ProviderManager.RefreshSingleItem(this, refreshOptions, cancellationToken).ConfigureAwait(false); } protected bool IsVisibleStandaloneInternal(User user, bool checkFolders) @@ -1367,7 +1350,7 @@ namespace MediaBrowser.Controller.Entities private async Task RefreshExtras(BaseItem item, MetadataRefreshOptions options, IReadOnlyList fileSystemChildren, CancellationToken cancellationToken) { var extras = LibraryManager.FindExtras(item, fileSystemChildren, options.DirectoryService).ToArray(); - var newExtraIds = extras.Select(i => i.Id).ToArray(); + var newExtraIds = Array.ConvertAll(extras, x => x.Id); var extrasChanged = !item.ExtraIds.SequenceEqual(newExtraIds); if (!extrasChanged && !options.ReplaceAllMetadata && options.MetadataRefreshMode != MetadataRefreshMode.FullRefresh) diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 84952295c4..44fe65103e 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -301,14 +301,6 @@ namespace MediaBrowser.Controller.Entities return dictionary; } - protected override void TriggerOnRefreshStart() - { - } - - protected override void TriggerOnRefreshComplete() - { - } - /// /// Validates the children internal. /// @@ -510,26 +502,17 @@ namespace MediaBrowser.Controller.Entities private async Task RefreshAllMetadataForContainer(IMetadataContainer container, MetadataRefreshOptions refreshOptions, IProgress progress, CancellationToken cancellationToken) { - // limit the amount of concurrent metadata refreshes - await ProviderManager.RunMetadataRefresh( - async () => - { - var series = container as Series; - if (series is not null) - { - await series.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false); - } + if (container is Series series) + { + await series.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false); + } - await container.RefreshAllMetadata(refreshOptions, progress, cancellationToken).ConfigureAwait(false); - }, - cancellationToken).ConfigureAwait(false); + await container.RefreshAllMetadata(refreshOptions, progress, cancellationToken).ConfigureAwait(false); } private async Task RefreshChildMetadata(BaseItem child, MetadataRefreshOptions refreshOptions, bool recursive, IProgress progress, CancellationToken cancellationToken) { - var container = child as IMetadataContainer; - - if (container is not null) + if (child is IMetadataContainer container) { await RefreshAllMetadataForContainer(container, refreshOptions, progress, cancellationToken).ConfigureAwait(false); } @@ -537,10 +520,7 @@ namespace MediaBrowser.Controller.Entities { if (refreshOptions.RefreshItem(child)) { - // limit the amount of concurrent metadata refreshes - await ProviderManager.RunMetadataRefresh( - async () => await child.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false), - cancellationToken).ConfigureAwait(false); + await child.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false); } if (recursive && child is Folder folder) @@ -586,7 +566,7 @@ namespace MediaBrowser.Controller.Entities } var fanoutConcurrency = ConfigurationManager.Configuration.LibraryScanFanoutConcurrency; - var parallelism = fanoutConcurrency == 0 ? Environment.ProcessorCount : fanoutConcurrency; + var parallelism = fanoutConcurrency > 0 ? fanoutConcurrency : 2 * Environment.ProcessorCount; var actionBlock = new ActionBlock( async i => @@ -618,7 +598,7 @@ namespace MediaBrowser.Controller.Entities for (var i = 0; i < childrenCount; i++) { - actionBlock.Post(i); + await actionBlock.SendAsync(i).ConfigureAwait(false); } actionBlock.Complete(); diff --git a/MediaBrowser.Controller/Library/MetadataConfigurationExtensions.cs b/MediaBrowser.Controller/Library/MetadataConfigurationExtensions.cs index 41cfcae163..ee9420cb43 100644 --- a/MediaBrowser.Controller/Library/MetadataConfigurationExtensions.cs +++ b/MediaBrowser.Controller/Library/MetadataConfigurationExtensions.cs @@ -1,8 +1,8 @@ -#nullable disable - #pragma warning disable CS1591 +using System; using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Model.Configuration; namespace MediaBrowser.Controller.Library @@ -10,8 +10,15 @@ namespace MediaBrowser.Controller.Library public static class MetadataConfigurationExtensions { public static MetadataConfiguration GetMetadataConfiguration(this IConfigurationManager config) - { - return config.GetConfiguration("metadata"); - } + => config.GetConfiguration("metadata"); + + /// + /// Gets the for the specified type. + /// + /// The . + /// The type to get the for. + /// The for the specified type or null. + public static MetadataOptions? GetMetadataOptionsForType(this IServerConfigurationManager config, string type) + => Array.Find(config.Configuration.MetadataOptions, i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)); } } diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs index 7e0a69586c..16943f6aaa 100644 --- a/MediaBrowser.Controller/Providers/IProviderManager.cs +++ b/MediaBrowser.Controller/Providers/IProviderManager.cs @@ -54,14 +54,6 @@ namespace MediaBrowser.Controller.Providers /// Task. Task RefreshSingleItem(BaseItem item, MetadataRefreshOptions options, CancellationToken cancellationToken); - /// - /// Runs multiple metadata refreshes concurrently. - /// - /// The action to run. - /// The cancellation token. - /// A representing the result of the asynchronous operation. - Task RunMetadataRefresh(Func action, CancellationToken cancellationToken); - /// /// Saves the image. /// @@ -207,15 +199,6 @@ namespace MediaBrowser.Controller.Providers where TItemType : BaseItem, new() where TLookupType : ItemLookupInfo; - /// - /// Gets the search image. - /// - /// Name of the provider. - /// The URL. - /// The cancellation token. - /// Task{HttpResponseInfo}. - Task GetSearchImage(string providerName, string url, CancellationToken cancellationToken); - HashSet GetRefreshQueue(); void OnRefreshStart(BaseItem item); diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index d2112e5dc2..4e63d205c9 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -57,7 +57,7 @@ namespace MediaBrowser.MediaEncoding.Encoder private readonly IServerConfigurationManager _serverConfig; private readonly string _startupOptionFFmpegPath; - private readonly SemaphoreSlim _thumbnailResourcePool = new SemaphoreSlim(2, 2); + private readonly SemaphoreSlim _thumbnailResourcePool; private readonly object _runningProcessesLock = new object(); private readonly List _runningProcesses = new List(); @@ -113,6 +113,9 @@ namespace MediaBrowser.MediaEncoding.Encoder _jsonSerializerOptions = new JsonSerializerOptions(JsonDefaults.Options); _jsonSerializerOptions.Converters.Add(new JsonBoolStringConverter()); + + var semaphoreCount = 2 * Environment.ProcessorCount; + _thumbnailResourcePool = new SemaphoreSlim(semaphoreCount, semaphoreCount); } /// diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 8af782b3d5..78a310f0b1 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -189,7 +189,7 @@ namespace MediaBrowser.Model.Configuration public NameValuePair[] ContentTypes { get; set; } = Array.Empty(); - public int RemoteClientBitrateLimit { get; set; } = 0; + public int RemoteClientBitrateLimit { get; set; } public bool EnableFolderView { get; set; } = false; @@ -203,7 +203,7 @@ namespace MediaBrowser.Model.Configuration public bool EnableExternalContentInSuggestions { get; set; } = true; - public int ImageExtractionTimeoutMs { get; set; } = 0; + public int ImageExtractionTimeoutMs { get; set; } public PathSubstitution[] PathSubstitutions { get; set; } = Array.Empty(); @@ -251,7 +251,7 @@ namespace MediaBrowser.Model.Configuration /// Gets or sets the dummy chapter duration in seconds, use 0 (zero) or less to disable generation alltogether. /// /// The dummy chapters duration. - public int DummyChapterDuration { get; set; } = 0; + public int DummyChapterDuration { get; set; } /// /// Gets or sets the chapter image resolution. @@ -263,6 +263,6 @@ namespace MediaBrowser.Model.Configuration /// Gets or sets the limit for parallel image encoding. /// /// The limit for parallel image encoding. - public int ParallelImageEncodingLimit { get; set; } = 0; + public int ParallelImageEncodingLimit { get; set; } } } diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 1028da32ba..5cb28402e8 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -131,12 +131,12 @@ namespace MediaBrowser.Providers.Manager { var type = item.GetType(); - var service = _metadataServices.FirstOrDefault(current => current.CanRefreshPrimary(type)); - service ??= _metadataServices.FirstOrDefault(current => current.CanRefresh(item)); + var service = _metadataServices.FirstOrDefault(current => current.CanRefreshPrimary(type)) + ?? _metadataServices.FirstOrDefault(current => current.CanRefresh(item)); if (service is null) { - _logger.LogError("Unable to find a metadata service for item of type {TypeName}", item.GetType().Name); + _logger.LogError("Unable to find a metadata service for item of type {TypeName}", type.Name); return Task.FromResult(ItemUpdateType.None); } @@ -160,7 +160,7 @@ namespace MediaBrowser.Providers.Manager // TODO: Isolate this hack into the tvh plugin if (string.IsNullOrEmpty(contentType)) { - if (url.IndexOf("/imagecache/", StringComparison.OrdinalIgnoreCase) != -1) + if (url.Contains("/imagecache/", StringComparison.OrdinalIgnoreCase)) { contentType = "image/png"; } @@ -232,6 +232,11 @@ namespace MediaBrowser.Providers.Manager providers = providers.Where(i => string.Equals(i.Name, providerName, StringComparison.OrdinalIgnoreCase)); } + if (query.ImageType is not null) + { + providers = providers.Where(i => i.GetSupportedImages(item).Contains(query.ImageType.Value)); + } + var preferredLanguage = item.GetPreferredMetadataLanguage(); var tasks = providers.Select(i => GetImages(item, i, preferredLanguage, query.IncludeAllLanguages, cancellationToken, query.ImageType)); @@ -568,13 +573,7 @@ namespace MediaBrowser.Providers.Manager /// public MetadataOptions GetMetadataOptions(BaseItem item) - { - var type = item.GetType().Name; - - return _configurationManager.Configuration.MetadataOptions - .FirstOrDefault(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)) ?? - new MetadataOptions(); - } + => _configurationManager.GetMetadataOptionsForType(item.GetType().Name) ?? new MetadataOptions(); /// public Task SaveMetadataAsync(BaseItem item, ItemUpdateType updateType) @@ -809,27 +808,12 @@ namespace MediaBrowser.Providers.Manager { var results = await provider.GetSearchResults(searchInfo, cancellationToken).ConfigureAwait(false); - var list = results.ToList(); - - foreach (var item in list) + foreach (var item in results) { item.SearchProviderName = provider.Name; } - return list; - } - - /// - public Task GetSearchImage(string providerName, string url, CancellationToken cancellationToken) - { - var provider = _metadataProviders.OfType().FirstOrDefault(i => string.Equals(i.Name, providerName, StringComparison.OrdinalIgnoreCase)); - - if (provider is null) - { - throw new ArgumentException("Search provider not found."); - } - - return provider.GetImageResponse(url, cancellationToken); + return results; } private IEnumerable GetExternalIds(IHasProviderIds item) @@ -1102,29 +1086,6 @@ namespace MediaBrowser.Providers.Manager return RefreshItem(item, options, cancellationToken); } - /// - /// Runs multiple metadata refreshes concurrently. - /// - /// The action to run. - /// The cancellation token. - /// A representing the result of the asynchronous operation. - public async Task RunMetadataRefresh(Func action, CancellationToken cancellationToken) - { - // create a variable for this since it is possible MetadataRefreshThrottler could change due to a config update during a scan - var metadataRefreshThrottler = _baseItemManager.MetadataRefreshThrottler; - - await metadataRefreshThrottler.WaitAsync(cancellationToken).ConfigureAwait(false); - - try - { - await action().ConfigureAwait(false); - } - finally - { - metadataRefreshThrottler.Release(); - } - } - /// public void Dispose() { diff --git a/MediaBrowser.Providers/Plugins/StudioImages/StudiosImageProvider.cs b/MediaBrowser.Providers/Plugins/StudioImages/StudiosImageProvider.cs index ae244da19b..a8461e9912 100644 --- a/MediaBrowser.Providers/Plugins/StudioImages/StudiosImageProvider.cs +++ b/MediaBrowser.Providers/Plugins/StudioImages/StudiosImageProvider.cs @@ -64,7 +64,7 @@ namespace MediaBrowser.Providers.Plugins.StudioImages { var thumbsPath = Path.Combine(_config.ApplicationPaths.CachePath, "imagesbyname", "remotestudiothumbs.txt"); - thumbsPath = await EnsureThumbsList(thumbsPath, cancellationToken).ConfigureAwait(false); + await EnsureThumbsList(thumbsPath, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); @@ -107,7 +107,7 @@ namespace MediaBrowser.Providers.Plugins.StudioImages return string.Format(CultureInfo.InvariantCulture, "{0}/images/{1}/{2}.jpg", GetRepositoryUrl(), image, filename); } - private Task EnsureThumbsList(string file, CancellationToken cancellationToken) + private Task EnsureThumbsList(string file, CancellationToken cancellationToken) { string url = string.Format(CultureInfo.InvariantCulture, "{0}/thumbs.txt", GetRepositoryUrl()); @@ -129,7 +129,7 @@ namespace MediaBrowser.Providers.Plugins.StudioImages /// The file system. /// The cancellation token. /// A Task to ensure existence of a file listing. - public async Task EnsureList(string url, string file, IFileSystem fileSystem, CancellationToken cancellationToken) + public async Task EnsureList(string url, string file, IFileSystem fileSystem, CancellationToken cancellationToken) { var fileInfo = fileSystem.GetFileInfo(file); @@ -148,8 +148,6 @@ namespace MediaBrowser.Providers.Plugins.StudioImages } } } - - return file; } /// diff --git a/src/Jellyfin.Drawing/ImageProcessor.cs b/src/Jellyfin.Drawing/ImageProcessor.cs index 533baba4fa..4e5d3b4d55 100644 --- a/src/Jellyfin.Drawing/ImageProcessor.cs +++ b/src/Jellyfin.Drawing/ImageProcessor.cs @@ -50,14 +50,12 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable /// The server application paths. /// The filesystem. /// The image encoder. - /// The media encoder. /// The configuration. public ImageProcessor( ILogger logger, IServerApplicationPaths appPaths, IFileSystem fileSystem, IImageEncoder imageEncoder, - IMediaEncoder mediaEncoder, IServerConfigurationManager config) { _logger = logger; -- cgit v1.2.3