Forráskód Böngészése

Add ItemId to all display preferences

crobibero 4 éve
szülő
commit
3db6ae91f6

+ 5 - 5
Jellyfin.Api/Controllers/DisplayPreferencesController.cs

@@ -48,14 +48,14 @@ namespace Jellyfin.Api.Controllers
             [FromQuery, Required] string client)
         {
             _ = Guid.TryParse(displayPreferencesId, out var itemId);
-            var displayPreferences = _displayPreferencesManager.GetDisplayPreferences(userId, client);
+            var displayPreferences = _displayPreferencesManager.GetDisplayPreferences(userId, itemId, client);
             var itemPreferences = _displayPreferencesManager.GetItemDisplayPreferences(displayPreferences.UserId, itemId, displayPreferences.Client);
             itemPreferences.ItemId = itemId;
 
             var dto = new DisplayPreferencesDto
             {
                 Client = displayPreferences.Client,
-                Id = displayPreferences.UserId.ToString(),
+                Id = displayPreferences.ItemId.ToString(),
                 ViewType = itemPreferences.ViewType.ToString(),
                 SortBy = itemPreferences.SortBy,
                 SortOrder = itemPreferences.SortOrder,
@@ -84,7 +84,7 @@ namespace Jellyfin.Api.Controllers
             dto.CustomPrefs["tvhome"] = displayPreferences.TvHome;
 
             // Load all custom display preferences
-            var customDisplayPreferences = _displayPreferencesManager.ListCustomItemDisplayPreferences(displayPreferences.UserId, displayPreferences.Client);
+            var customDisplayPreferences = _displayPreferencesManager.ListCustomItemDisplayPreferences(displayPreferences.UserId, itemId, displayPreferences.Client);
             if (customDisplayPreferences != null)
             {
                 foreach (var (key, value) in customDisplayPreferences)
@@ -128,7 +128,7 @@ namespace Jellyfin.Api.Controllers
             };
 
             _ = Guid.TryParse(displayPreferencesId, out var itemId);
-            var existingDisplayPreferences = _displayPreferencesManager.GetDisplayPreferences(userId, client);
+            var existingDisplayPreferences = _displayPreferencesManager.GetDisplayPreferences(userId, itemId, client);
             existingDisplayPreferences.IndexBy = Enum.TryParse<IndexingKind>(displayPreferences.IndexBy, true, out var indexBy) ? indexBy : (IndexingKind?)null;
             existingDisplayPreferences.ShowBackdrop = displayPreferences.ShowBackdrop;
             existingDisplayPreferences.ShowSidebar = displayPreferences.ShowSidebar;
@@ -201,7 +201,7 @@ namespace Jellyfin.Api.Controllers
             }
 
             // Set all remaining custom preferences.
-            _displayPreferencesManager.SetCustomItemDisplayPreferences(userId, existingDisplayPreferences.Client, displayPreferences.CustomPrefs);
+            _displayPreferencesManager.SetCustomItemDisplayPreferences(userId, itemId, existingDisplayPreferences.Client, displayPreferences.CustomPrefs);
             _displayPreferencesManager.SaveChanges();
 
             return NoContent();

+ 11 - 1
Jellyfin.Data/Entities/CustomItemDisplayPreferences.cs

@@ -13,12 +13,14 @@ namespace Jellyfin.Data.Entities
         /// Initializes a new instance of the <see cref="CustomItemDisplayPreferences"/> class.
         /// </summary>
         /// <param name="userId">The user id.</param>
+        /// <param name="itemId">The item id.</param>
         /// <param name="client">The client.</param>
         /// <param name="preferenceKey">The preference key.</param>
         /// <param name="preferenceValue">The preference value.</param>
-        public CustomItemDisplayPreferences(Guid userId, string client, string preferenceKey, string preferenceValue)
+        public CustomItemDisplayPreferences(Guid userId, Guid itemId, string client, string preferenceKey, string preferenceValue)
         {
             UserId = userId;
+            ItemId = itemId;
             Client = client;
             Key = preferenceKey;
             Value = preferenceValue;
@@ -48,6 +50,14 @@ namespace Jellyfin.Data.Entities
         /// </remarks>
         public Guid UserId { get; set; }
 
+        /// <summary>
+        /// Gets or sets the id of the associated item.
+        /// </summary>
+        /// <remarks>
+        /// Required.
+        /// </remarks>
+        public Guid ItemId { get; set; }
+
         /// <summary>
         /// Gets or sets the client string.
         /// </summary>

+ 11 - 1
Jellyfin.Data/Entities/DisplayPreferences.cs

@@ -17,10 +17,12 @@ namespace Jellyfin.Data.Entities
         /// Initializes a new instance of the <see cref="DisplayPreferences"/> class.
         /// </summary>
         /// <param name="userId">The user's id.</param>
+        /// <param name="itemId">The item id.</param>
         /// <param name="client">The client string.</param>
-        public DisplayPreferences(Guid userId, string client)
+        public DisplayPreferences(Guid userId, Guid itemId, string client)
         {
             UserId = userId;
+            ItemId = itemId;
             Client = client;
             ShowSidebar = false;
             ShowBackdrop = true;
@@ -58,6 +60,14 @@ namespace Jellyfin.Data.Entities
         /// </remarks>
         public Guid UserId { get; set; }
 
+        /// <summary>
+        /// Gets or sets the id of the associated item.
+        /// </summary>
+        /// <remarks>
+        /// Required.
+        /// </remarks>
+        public Guid ItemId { get; set; }
+
         /// <summary>
         /// Gets or sets the client string.
         /// </summary>

+ 1 - 1
Jellyfin.Data/Jellyfin.Data.csproj

@@ -29,7 +29,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All"/>
+    <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
   </ItemGroup>
 
   <!-- Code analysers-->

+ 2 - 2
Jellyfin.Server.Implementations/JellyfinDb.cs

@@ -153,7 +153,7 @@ namespace Jellyfin.Server.Implementations
                 .IsUnique(false);
 
             modelBuilder.Entity<DisplayPreferences>()
-                .HasIndex(entity => new { entity.UserId, entity.Client })
+                .HasIndex(entity => new { entity.UserId, entity.ItemId, entity.Client })
                 .IsUnique();
 
             modelBuilder.Entity<CustomItemDisplayPreferences>()
@@ -161,7 +161,7 @@ namespace Jellyfin.Server.Implementations
                 .IsUnique(false);
 
             modelBuilder.Entity<CustomItemDisplayPreferences>()
-                .HasIndex(entity => new { entity.UserId, entity.Client, entity.Key })
+                .HasIndex(entity => new { entity.UserId, entity.ItemId, entity.Client, entity.Key })
                 .IsUnique();
         }
     }

+ 9 - 3
Jellyfin.Server.Implementations/Migrations/20201203203707_AddCustomDisplayPreferences.Designer.cs → Jellyfin.Server.Implementations/Migrations/20201204223655_AddCustomDisplayPreferences.Designer.cs

@@ -10,7 +10,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
 namespace Jellyfin.Server.Implementations.Migrations
 {
     [DbContext(typeof(JellyfinDb))]
-    [Migration("20201203203707_AddCustomDisplayPreferences")]
+    [Migration("20201204223655_AddCustomDisplayPreferences")]
     partial class AddCustomDisplayPreferences
     {
         protected override void BuildTargetModel(ModelBuilder modelBuilder)
@@ -102,6 +102,9 @@ namespace Jellyfin.Server.Implementations.Migrations
                         .HasMaxLength(32)
                         .HasColumnType("TEXT");
 
+                    b.Property<Guid>("ItemId")
+                        .HasColumnType("TEXT");
+
                     b.Property<string>("Key")
                         .IsRequired()
                         .HasColumnType("TEXT");
@@ -117,7 +120,7 @@ namespace Jellyfin.Server.Implementations.Migrations
 
                     b.HasIndex("UserId");
 
-                    b.HasIndex("UserId", "Client", "Key")
+                    b.HasIndex("UserId", "ItemId", "Client", "Key")
                         .IsUnique();
 
                     b.ToTable("CustomItemDisplayPreferences");
@@ -147,6 +150,9 @@ namespace Jellyfin.Server.Implementations.Migrations
                     b.Property<int?>("IndexBy")
                         .HasColumnType("INTEGER");
 
+                    b.Property<Guid>("ItemId")
+                        .HasColumnType("TEXT");
+
                     b.Property<int>("ScrollDirection")
                         .HasColumnType("INTEGER");
 
@@ -173,7 +179,7 @@ namespace Jellyfin.Server.Implementations.Migrations
 
                     b.HasIndex("UserId");
 
-                    b.HasIndex("UserId", "Client")
+                    b.HasIndex("UserId", "ItemId", "Client")
                         .IsUnique();
 
                     b.ToTable("DisplayPreferences");

+ 40 - 2
Jellyfin.Server.Implementations/Migrations/20201203203707_AddCustomDisplayPreferences.cs → Jellyfin.Server.Implementations/Migrations/20201204223655_AddCustomDisplayPreferences.cs

@@ -9,6 +9,11 @@ namespace Jellyfin.Server.Implementations.Migrations
     {
         protected override void Up(MigrationBuilder migrationBuilder)
         {
+            migrationBuilder.DropIndex(
+                name: "IX_DisplayPreferences_UserId_Client",
+                schema: "jellyfin",
+                table: "DisplayPreferences");
+
             migrationBuilder.AlterColumn<int>(
                 name: "MaxActiveSessions",
                 schema: "jellyfin",
@@ -20,6 +25,14 @@ namespace Jellyfin.Server.Implementations.Migrations
                 oldType: "INTEGER",
                 oldNullable: true);
 
+            migrationBuilder.AddColumn<Guid>(
+                name: "ItemId",
+                schema: "jellyfin",
+                table: "DisplayPreferences",
+                type: "TEXT",
+                nullable: false,
+                defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
+
             migrationBuilder.CreateTable(
                 name: "CustomItemDisplayPreferences",
                 schema: "jellyfin",
@@ -28,6 +41,7 @@ namespace Jellyfin.Server.Implementations.Migrations
                     Id = table.Column<int>(type: "INTEGER", nullable: false)
                         .Annotation("Sqlite:Autoincrement", true),
                     UserId = table.Column<Guid>(type: "TEXT", nullable: false),
+                    ItemId = table.Column<Guid>(type: "TEXT", nullable: false),
                     Client = table.Column<string>(type: "TEXT", maxLength: 32, nullable: false),
                     Key = table.Column<string>(type: "TEXT", nullable: false),
                     Value = table.Column<string>(type: "TEXT", nullable: false)
@@ -37,6 +51,13 @@ namespace Jellyfin.Server.Implementations.Migrations
                     table.PrimaryKey("PK_CustomItemDisplayPreferences", x => x.Id);
                 });
 
+            migrationBuilder.CreateIndex(
+                name: "IX_DisplayPreferences_UserId_ItemId_Client",
+                schema: "jellyfin",
+                table: "DisplayPreferences",
+                columns: new[] { "UserId", "ItemId", "Client" },
+                unique: true);
+
             migrationBuilder.CreateIndex(
                 name: "IX_CustomItemDisplayPreferences_UserId",
                 schema: "jellyfin",
@@ -44,10 +65,10 @@ namespace Jellyfin.Server.Implementations.Migrations
                 column: "UserId");
 
             migrationBuilder.CreateIndex(
-                name: "IX_CustomItemDisplayPreferences_UserId_Client_Key",
+                name: "IX_CustomItemDisplayPreferences_UserId_ItemId_Client_Key",
                 schema: "jellyfin",
                 table: "CustomItemDisplayPreferences",
-                columns: new[] { "UserId", "Client", "Key" },
+                columns: new[] { "UserId", "ItemId", "Client", "Key" },
                 unique: true);
         }
 
@@ -57,6 +78,16 @@ namespace Jellyfin.Server.Implementations.Migrations
                 name: "CustomItemDisplayPreferences",
                 schema: "jellyfin");
 
+            migrationBuilder.DropIndex(
+                name: "IX_DisplayPreferences_UserId_ItemId_Client",
+                schema: "jellyfin",
+                table: "DisplayPreferences");
+
+            migrationBuilder.DropColumn(
+                name: "ItemId",
+                schema: "jellyfin",
+                table: "DisplayPreferences");
+
             migrationBuilder.AlterColumn<int>(
                 name: "MaxActiveSessions",
                 schema: "jellyfin",
@@ -65,6 +96,13 @@ namespace Jellyfin.Server.Implementations.Migrations
                 nullable: true,
                 oldClrType: typeof(int),
                 oldType: "INTEGER");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_DisplayPreferences_UserId_Client",
+                schema: "jellyfin",
+                table: "DisplayPreferences",
+                columns: new[] { "UserId", "Client" },
+                unique: true);
         }
     }
 }

+ 8 - 2
Jellyfin.Server.Implementations/Migrations/JellyfinDbModelSnapshot.cs

@@ -99,6 +99,9 @@ namespace Jellyfin.Server.Implementations.Migrations
                         .HasMaxLength(32)
                         .HasColumnType("TEXT");
 
+                    b.Property<Guid>("ItemId")
+                        .HasColumnType("TEXT");
+
                     b.Property<string>("Key")
                         .IsRequired()
                         .HasColumnType("TEXT");
@@ -114,7 +117,7 @@ namespace Jellyfin.Server.Implementations.Migrations
 
                     b.HasIndex("UserId");
 
-                    b.HasIndex("UserId", "Client", "Key")
+                    b.HasIndex("UserId", "ItemId", "Client", "Key")
                         .IsUnique();
 
                     b.ToTable("CustomItemDisplayPreferences");
@@ -144,6 +147,9 @@ namespace Jellyfin.Server.Implementations.Migrations
                     b.Property<int?>("IndexBy")
                         .HasColumnType("INTEGER");
 
+                    b.Property<Guid>("ItemId")
+                        .HasColumnType("TEXT");
+
                     b.Property<int>("ScrollDirection")
                         .HasColumnType("INTEGER");
 
@@ -170,7 +176,7 @@ namespace Jellyfin.Server.Implementations.Migrations
 
                     b.HasIndex("UserId");
 
-                    b.HasIndex("UserId", "Client")
+                    b.HasIndex("UserId", "ItemId", "Client")
                         .IsUnique();
 
                     b.ToTable("DisplayPreferences");

+ 12 - 8
Jellyfin.Server.Implementations/Users/DisplayPreferencesManager.cs

@@ -26,16 +26,16 @@ namespace Jellyfin.Server.Implementations.Users
         }
 
         /// <inheritdoc />
-        public DisplayPreferences GetDisplayPreferences(Guid userId, string client)
+        public DisplayPreferences GetDisplayPreferences(Guid userId, Guid itemId, string client)
         {
             var prefs = _dbContext.DisplayPreferences
                 .Include(pref => pref.HomeSections)
                 .FirstOrDefault(pref =>
-                    pref.UserId == userId && string.Equals(pref.Client, client));
+                    pref.UserId == userId && string.Equals(pref.Client, client) && pref.ItemId == itemId);
 
             if (prefs == null)
             {
-                prefs = new DisplayPreferences(userId, client);
+                prefs = new DisplayPreferences(userId,  itemId, client);
                 _dbContext.DisplayPreferences.Add(prefs);
             }
 
@@ -67,26 +67,30 @@ namespace Jellyfin.Server.Implementations.Users
         }
 
         /// <inheritdoc />
-        public IDictionary<string, string> ListCustomItemDisplayPreferences(Guid userId, string client)
+        public IDictionary<string, string> ListCustomItemDisplayPreferences(Guid userId, Guid itemId, string client)
         {
             return _dbContext.CustomItemDisplayPreferences
                 .AsQueryable()
-                .Where(prefs => prefs.UserId == userId && string.Equals(prefs.Client, client))
+                .Where(prefs => prefs.UserId == userId
+                                && prefs.ItemId == itemId
+                                && string.Equals(prefs.Client, client))
                 .ToDictionary(prefs => prefs.Key, prefs => prefs.Value);
         }
 
         /// <inheritdoc />
-        public void SetCustomItemDisplayPreferences(Guid userId, string client, Dictionary<string, string> customPreferences)
+        public void SetCustomItemDisplayPreferences(Guid userId, Guid itemId, string client, Dictionary<string, string> customPreferences)
         {
             var existingPrefs = _dbContext.CustomItemDisplayPreferences
                 .AsQueryable()
-                .Where(prefs => prefs.UserId == userId && string.Equals(prefs.Client, client));
+                .Where(prefs => prefs.UserId == userId
+                                && prefs.ItemId == itemId
+                                && string.Equals(prefs.Client, client));
             _dbContext.CustomItemDisplayPreferences.RemoveRange(existingPrefs);
 
             foreach (var (key, value) in customPreferences)
             {
                 _dbContext.CustomItemDisplayPreferences
-                    .Add(new CustomItemDisplayPreferences(userId, client, key, value));
+                    .Add(new CustomItemDisplayPreferences(userId, itemId, client, key, value));
             }
         }
 

+ 12 - 4
Jellyfin.Server/Migrations/Routines/MigrateDisplayPreferencesDb.cs

@@ -8,6 +8,7 @@ using System.Text.Json.Serialization;
 using Jellyfin.Data.Entities;
 using Jellyfin.Data.Enums;
 using Jellyfin.Server.Implementations;
+using MediaBrowser.Common.Extensions;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Model.Entities;
@@ -80,6 +81,7 @@ namespace Jellyfin.Server.Migrations.Routines
                 { "unstable", ChromecastVersion.Unstable }
             };
 
+            var defaultDisplayPrefsId = "usersettings".GetMD5();
             var dbFilePath = Path.Combine(_paths.DataPath, DbFilename);
             using (var connection = SQLite3.Open(dbFilePath, ConnectionFlags.ReadOnly, null))
             {
@@ -94,6 +96,12 @@ namespace Jellyfin.Server.Migrations.Routines
                         continue;
                     }
 
+                    var itemId = new Guid(result[1].ToBlob());
+                    if (itemId == defaultDisplayPrefsId)
+                    {
+                        itemId = Guid.Empty;
+                    }
+
                     var dtoUserId = new Guid(result[1].ToBlob());
                     var existingUser = _userManager.GetUserById(dtoUserId);
                     if (existingUser == null)
@@ -107,7 +115,7 @@ namespace Jellyfin.Server.Migrations.Routines
                         : ChromecastVersion.Stable;
                     dto.CustomPrefs.Remove("chromecastVersion");
 
-                    var displayPreferences = new DisplayPreferences(dtoUserId, result[2].ToString())
+                    var displayPreferences = new DisplayPreferences(dtoUserId, itemId, result[2].ToString())
                     {
                         IndexBy = Enum.TryParse<IndexingKind>(dto.IndexBy, true, out var indexBy) ? indexBy : (IndexingKind?)null,
                         ShowBackdrop = dto.ShowBackdrop,
@@ -159,12 +167,12 @@ namespace Jellyfin.Server.Migrations.Routines
 
                     foreach (var key in dto.CustomPrefs.Keys.Where(key => key.StartsWith("landing-", StringComparison.Ordinal)))
                     {
-                        if (!Guid.TryParse(key.AsSpan().Slice("landing-".Length), out var itemId))
+                        if (!Guid.TryParse(key.AsSpan().Slice("landing-".Length), out var landingItemId))
                         {
                             continue;
                         }
 
-                        var libraryDisplayPreferences = new ItemDisplayPreferences(displayPreferences.UserId, itemId, displayPreferences.Client)
+                        var libraryDisplayPreferences = new ItemDisplayPreferences(displayPreferences.UserId, landingItemId, displayPreferences.Client)
                         {
                             SortBy = dto.SortBy ?? "SortName",
                             SortOrder = dto.SortOrder,
@@ -183,7 +191,7 @@ namespace Jellyfin.Server.Migrations.Routines
 
                     foreach (var (key, value) in dto.CustomPrefs)
                     {
-                        dbContext.Add(new CustomItemDisplayPreferences(displayPreferences.UserId, displayPreferences.Client, key, value));
+                        dbContext.Add(new CustomItemDisplayPreferences(displayPreferences.UserId, itemId, displayPreferences.Client, key, value));
                     }
 
                     dbContext.Add(displayPreferences);

+ 6 - 3
MediaBrowser.Controller/IDisplayPreferencesManager.cs

@@ -16,9 +16,10 @@ namespace MediaBrowser.Controller
         /// This will create the display preferences if it does not exist, but it will not save automatically.
         /// </remarks>
         /// <param name="userId">The user's id.</param>
+        /// <param name="itemId">The item id.</param>
         /// <param name="client">The client string.</param>
         /// <returns>The associated display preferences.</returns>
-        DisplayPreferences GetDisplayPreferences(Guid userId, string client);
+        DisplayPreferences GetDisplayPreferences(Guid userId, Guid itemId, string client);
 
         /// <summary>
         /// Gets the default item display preferences for the user and client.
@@ -44,17 +45,19 @@ namespace MediaBrowser.Controller
         /// Gets all of the custom item display preferences for the user and client.
         /// </summary>
         /// <param name="userId">The user id.</param>
+        /// <param name="itemId">The item id.</param>
         /// <param name="client">The client string.</param>
         /// <returns>The dictionary of custom item display preferences.</returns>
-        IDictionary<string, string> ListCustomItemDisplayPreferences(Guid userId, string client);
+        IDictionary<string, string> ListCustomItemDisplayPreferences(Guid userId, Guid itemId, string client);
 
         /// <summary>
         /// Sets the custom item display preference for the user and client.
         /// </summary>
         /// <param name="userId">The user id.</param>
+        /// <param name="itemId">The item id.</param>
         /// <param name="client">The client id.</param>
         /// <param name="customPreferences">A dictionary of custom item display preferences.</param>
-        void SetCustomItemDisplayPreferences(Guid userId, string client, Dictionary<string, string> customPreferences);
+        void SetCustomItemDisplayPreferences(Guid userId, Guid itemId, string client, Dictionary<string, string> customPreferences);
 
         /// <summary>
         /// Saves changes made to the database.