From 20f7ddbf8fe9e06e366ad80484dd386542245c61 Mon Sep 17 00:00:00 2001 From: JPVenson Date: Fri, 5 Sep 2025 22:39:15 +0200 Subject: [PATCH] Refactor Display preference manager (#14056) --- .../DisplayPreferencesController.cs | 7 +- .../Users/DisplayPreferencesManager.cs | 173 +++++++++--------- Jellyfin.Server/CoreAppHost.cs | 2 +- .../IDisplayPreferencesManager.cs | 11 +- 4 files changed, 102 insertions(+), 91 deletions(-) diff --git a/Jellyfin.Api/Controllers/DisplayPreferencesController.cs b/Jellyfin.Api/Controllers/DisplayPreferencesController.cs index 13064882cc..585318d245 100644 --- a/Jellyfin.Api/Controllers/DisplayPreferencesController.cs +++ b/Jellyfin.Api/Controllers/DisplayPreferencesController.cs @@ -96,9 +96,6 @@ public class DisplayPreferencesController : BaseJellyfinApiController dto.CustomPrefs.TryAdd(key, value); } - // This will essentially be a noop if no changes have been made, but new prefs must be saved at least. - _displayPreferencesManager.SaveChanges(); - return dto; } @@ -210,8 +207,8 @@ public class DisplayPreferencesController : BaseJellyfinApiController // Set all remaining custom preferences. _displayPreferencesManager.SetCustomItemDisplayPreferences(userId.Value, itemId, existingDisplayPreferences.Client, displayPreferences.CustomPrefs); - _displayPreferencesManager.SaveChanges(); - + _displayPreferencesManager.UpdateItemDisplayPreferences(itemPrefs); + _displayPreferencesManager.UpdateDisplayPreferences(existingDisplayPreferences); return NoContent(); } } diff --git a/Jellyfin.Server.Implementations/Users/DisplayPreferencesManager.cs b/Jellyfin.Server.Implementations/Users/DisplayPreferencesManager.cs index 0f21e11a35..0e126fe9a0 100644 --- a/Jellyfin.Server.Implementations/Users/DisplayPreferencesManager.cs +++ b/Jellyfin.Server.Implementations/Users/DisplayPreferencesManager.cs @@ -1,109 +1,116 @@ -#pragma warning disable CA1307 -#pragma warning disable CA1309 - using System; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using Jellyfin.Database.Implementations; using Jellyfin.Database.Implementations.Entities; using MediaBrowser.Controller; using Microsoft.EntityFrameworkCore; -namespace Jellyfin.Server.Implementations.Users +namespace Jellyfin.Server.Implementations.Users; + +/// +/// Manages the storage and retrieval of display preferences through Entity Framework. +/// +public sealed class DisplayPreferencesManager : IDisplayPreferencesManager { + private readonly IDbContextFactory _dbContextFactory; + /// - /// Manages the storage and retrieval of display preferences through Entity Framework. + /// Initializes a new instance of the class. /// - public sealed class DisplayPreferencesManager : IDisplayPreferencesManager, IAsyncDisposable + /// The database context factory. + public DisplayPreferencesManager(IDbContextFactory dbContextFactory) { - private readonly JellyfinDbContext _dbContext; + _dbContextFactory = dbContextFactory; + } - /// - /// Initializes a new instance of the class. - /// - /// The database context factory. - public DisplayPreferencesManager(IDbContextFactory dbContextFactory) + /// + public DisplayPreferences GetDisplayPreferences(Guid userId, Guid itemId, string client) + { + using var dbContext = _dbContextFactory.CreateDbContext(); + var prefs = dbContext.DisplayPreferences + .Include(pref => pref.HomeSections) + .FirstOrDefault(pref => + pref.UserId.Equals(userId) && pref.Client == client && pref.ItemId.Equals(itemId)); + + if (prefs is null) { - _dbContext = dbContextFactory.CreateDbContext(); + prefs = new DisplayPreferences(userId, itemId, client); + dbContext.DisplayPreferences.Add(prefs); + dbContext.SaveChanges(); } - /// - public DisplayPreferences GetDisplayPreferences(Guid userId, Guid itemId, string client) + return prefs; + } + + /// + public ItemDisplayPreferences GetItemDisplayPreferences(Guid userId, Guid itemId, string client) + { + using var dbContext = _dbContextFactory.CreateDbContext(); + var prefs = dbContext.ItemDisplayPreferences + .FirstOrDefault(pref => pref.UserId.Equals(userId) && pref.ItemId.Equals(itemId) && pref.Client == client); + + if (prefs is null) { - var prefs = _dbContext.DisplayPreferences - .Include(pref => pref.HomeSections) - .FirstOrDefault(pref => - pref.UserId.Equals(userId) && string.Equals(pref.Client, client) && pref.ItemId.Equals(itemId)); - - if (prefs is null) - { - prefs = new DisplayPreferences(userId, itemId, client); - _dbContext.DisplayPreferences.Add(prefs); - } - - return prefs; + prefs = new ItemDisplayPreferences(userId, Guid.Empty, client); + dbContext.ItemDisplayPreferences.Add(prefs); + dbContext.SaveChanges(); } - /// - public ItemDisplayPreferences GetItemDisplayPreferences(Guid userId, Guid itemId, string client) + return prefs; + } + + /// + public IList ListItemDisplayPreferences(Guid userId, string client) + { + using var dbContext = _dbContextFactory.CreateDbContext(); + return dbContext.ItemDisplayPreferences + .Where(prefs => prefs.UserId.Equals(userId) && !prefs.ItemId.Equals(default) && prefs.Client == client) + .ToList(); + } + + /// + public Dictionary ListCustomItemDisplayPreferences(Guid userId, Guid itemId, string client) + { + using var dbContext = _dbContextFactory.CreateDbContext(); + return dbContext.CustomItemDisplayPreferences + .Where(prefs => prefs.UserId.Equals(userId) + && prefs.ItemId.Equals(itemId) + && prefs.Client == client) + .ToDictionary(prefs => prefs.Key, prefs => prefs.Value); + } + + /// + public void SetCustomItemDisplayPreferences(Guid userId, Guid itemId, string client, Dictionary customPreferences) + { + using var dbContext = _dbContextFactory.CreateDbContext(); + dbContext.CustomItemDisplayPreferences.Where(prefs => prefs.UserId.Equals(userId) + && prefs.ItemId.Equals(itemId) + && prefs.Client == client) + .ExecuteDelete(); + + foreach (var (key, value) in customPreferences) { - var prefs = _dbContext.ItemDisplayPreferences - .FirstOrDefault(pref => pref.UserId.Equals(userId) && pref.ItemId.Equals(itemId) && string.Equals(pref.Client, client)); - - if (prefs is null) - { - prefs = new ItemDisplayPreferences(userId, Guid.Empty, client); - _dbContext.ItemDisplayPreferences.Add(prefs); - } - - return prefs; + dbContext.CustomItemDisplayPreferences + .Add(new CustomItemDisplayPreferences(userId, itemId, client, key, value)); } - /// - public IList ListItemDisplayPreferences(Guid userId, string client) - { - return _dbContext.ItemDisplayPreferences - .Where(prefs => prefs.UserId.Equals(userId) && !prefs.ItemId.Equals(default) && string.Equals(prefs.Client, client)) - .ToList(); - } + dbContext.SaveChanges(); + } - /// - public Dictionary ListCustomItemDisplayPreferences(Guid userId, Guid itemId, string client) - { - return _dbContext.CustomItemDisplayPreferences - .Where(prefs => prefs.UserId.Equals(userId) - && prefs.ItemId.Equals(itemId) - && string.Equals(prefs.Client, client)) - .ToDictionary(prefs => prefs.Key, prefs => prefs.Value); - } + /// + public void UpdateDisplayPreferences(DisplayPreferences displayPreferences) + { + using var dbContext = _dbContextFactory.CreateDbContext(); + dbContext.DisplayPreferences.Attach(displayPreferences).State = EntityState.Modified; + dbContext.SaveChanges(); + } - /// - public void SetCustomItemDisplayPreferences(Guid userId, Guid itemId, string client, Dictionary customPreferences) - { - var existingPrefs = _dbContext.CustomItemDisplayPreferences - .Where(prefs => prefs.UserId.Equals(userId) - && prefs.ItemId.Equals(itemId) - && string.Equals(prefs.Client, client)); - _dbContext.CustomItemDisplayPreferences.RemoveRange(existingPrefs); - - foreach (var (key, value) in customPreferences) - { - _dbContext.CustomItemDisplayPreferences - .Add(new CustomItemDisplayPreferences(userId, itemId, client, key, value)); - } - } - - /// - public void SaveChanges() - { - _dbContext.SaveChanges(); - } - - /// - public async ValueTask DisposeAsync() - { - await _dbContext.DisposeAsync().ConfigureAwait(false); - } + /// + public void UpdateItemDisplayPreferences(ItemDisplayPreferences itemDisplayPreferences) + { + using var dbContext = _dbContextFactory.CreateDbContext(); + dbContext.ItemDisplayPreferences.Attach(itemDisplayPreferences).State = EntityState.Modified; + dbContext.SaveChanges(); } } diff --git a/Jellyfin.Server/CoreAppHost.cs b/Jellyfin.Server/CoreAppHost.cs index f3bf6b805a..2548ddea7c 100644 --- a/Jellyfin.Server/CoreAppHost.cs +++ b/Jellyfin.Server/CoreAppHost.cs @@ -84,7 +84,7 @@ namespace Jellyfin.Server serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); - serviceCollection.AddScoped(); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); diff --git a/MediaBrowser.Controller/IDisplayPreferencesManager.cs b/MediaBrowser.Controller/IDisplayPreferencesManager.cs index a97096eaee..7e235ed26c 100644 --- a/MediaBrowser.Controller/IDisplayPreferencesManager.cs +++ b/MediaBrowser.Controller/IDisplayPreferencesManager.cs @@ -60,8 +60,15 @@ namespace MediaBrowser.Controller void SetCustomItemDisplayPreferences(Guid userId, Guid itemId, string client, Dictionary customPreferences); /// - /// Saves changes made to the database. + /// Updates or Creates the display preferences. /// - void SaveChanges(); + /// The entity to update or create. + void UpdateDisplayPreferences(DisplayPreferences displayPreferences); + + /// + /// Updates or Creates the display preferences for the given item. + /// + /// The entity to update or create. + void UpdateItemDisplayPreferences(ItemDisplayPreferences itemDisplayPreferences); } }