Merge pull request #16160 from Shadowghost/fix-itemvalues-uniqueness
Some checks failed
Stale PR Check / Check PRs with merge conflicts (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Has been cancelled
OpenAPI / OpenAPI - BASE (push) Has been cancelled
OpenAPI / OpenAPI - HEAD (push) Has been cancelled
OpenAPI / OpenAPI - Difference (push) Has been cancelled
OpenAPI / OpenAPI - Publish Unstable Spec (push) Has been cancelled
OpenAPI / OpenAPI - Publish Stable Spec (push) Has been cancelled
Tests / run-tests (macos-latest) (push) Has been cancelled
Tests / run-tests (ubuntu-latest) (push) Has been cancelled
Tests / run-tests (windows-latest) (push) Has been cancelled
Project Automation / Project board (push) Has been cancelled
Merge Conflict Labeler / Labeling (push) Has been cancelled
Stale Issue Labeler / Check for stale issues (push) Has been cancelled

Fix ItemValues Type checks
This commit is contained in:
Bond-009
2026-03-10 21:26:05 +01:00
committed by GitHub
2 changed files with 20 additions and 19 deletions

View File

@@ -249,7 +249,7 @@ public class ItemUpdateController : BaseJellyfinApiController
item.IndexNumber = request.IndexNumber; item.IndexNumber = request.IndexNumber;
item.ParentIndexNumber = request.ParentIndexNumber; item.ParentIndexNumber = request.ParentIndexNumber;
item.Overview = request.Overview; item.Overview = request.Overview;
item.Genres = request.Genres; item.Genres = request.Genres.Distinct(StringComparer.OrdinalIgnoreCase).ToArray();
if (item is Episode episode) if (item is Episode episode)
{ {
@@ -270,7 +270,7 @@ public class ItemUpdateController : BaseJellyfinApiController
if (request.Studios is not null) if (request.Studios is not null)
{ {
item.Studios = Array.ConvertAll(request.Studios, x => x.Name); item.Studios = Array.ConvertAll(request.Studios, x => x.Name).Distinct(StringComparer.OrdinalIgnoreCase).ToArray();
} }
if (request.DateCreated.HasValue) if (request.DateCreated.HasValue)
@@ -287,7 +287,7 @@ public class ItemUpdateController : BaseJellyfinApiController
item.CustomRating = request.CustomRating; item.CustomRating = request.CustomRating;
var currentTags = item.Tags; var currentTags = item.Tags;
var newTags = request.Tags; var newTags = request.Tags.Distinct(StringComparer.OrdinalIgnoreCase).ToArray();
var removedTags = currentTags.Except(newTags).ToList(); var removedTags = currentTags.Except(newTags).ToList();
var addedTags = newTags.Except(currentTags).ToList(); var addedTags = newTags.Except(currentTags).ToList();
item.Tags = newTags; item.Tags = newTags;
@@ -373,7 +373,7 @@ public class ItemUpdateController : BaseJellyfinApiController
if (request.ProductionLocations is not null) if (request.ProductionLocations is not null)
{ {
item.ProductionLocations = request.ProductionLocations; item.ProductionLocations = request.ProductionLocations.Distinct(StringComparer.OrdinalIgnoreCase).ToArray();
} }
item.PreferredMetadataCountryCode = request.PreferredMetadataCountryCode; item.PreferredMetadataCountryCode = request.PreferredMetadataCountryCode;
@@ -421,7 +421,7 @@ public class ItemUpdateController : BaseJellyfinApiController
{ {
if (item is IHasAlbumArtist hasAlbumArtists) if (item is IHasAlbumArtist hasAlbumArtists)
{ {
hasAlbumArtists.AlbumArtists = Array.ConvertAll(request.AlbumArtists, i => i.Name.Trim()); hasAlbumArtists.AlbumArtists = Array.ConvertAll(request.AlbumArtists, i => i.Name.Trim()).Distinct(StringComparer.OrdinalIgnoreCase).ToArray();
} }
} }
@@ -429,7 +429,7 @@ public class ItemUpdateController : BaseJellyfinApiController
{ {
if (item is IHasArtist hasArtists) if (item is IHasArtist hasArtists)
{ {
hasArtists.Artists = Array.ConvertAll(request.ArtistItems, i => i.Name.Trim()); hasArtists.Artists = Array.ConvertAll(request.ArtistItems, i => i.Name.Trim()).Distinct(StringComparer.OrdinalIgnoreCase).ToArray();
} }
} }

View File

@@ -683,14 +683,15 @@ public sealed class BaseItemRepository
.SelectMany(f => f.Values) .SelectMany(f => f.Values)
.Distinct() .Distinct()
.ToArray(); .ToArray();
var types = allListedItemValues.Select(e => e.MagicNumber).Distinct().ToArray();
var values = allListedItemValues.Select(e => e.Value).Distinct().ToArray();
var allListedItemValuesSet = allListedItemValues.ToHashSet();
var existingValues = context.ItemValues var existingValues = context.ItemValues
.Select(e => new .Where(e => types.Contains(e.Type) && values.Contains(e.Value))
{ .AsEnumerable()
item = e, .Where(e => allListedItemValuesSet.Contains((e.Type, e.Value)))
Key = e.Type + "+" + e.Value
})
.Where(f => allListedItemValues.Select(e => $"{(int)e.MagicNumber}+{e.Value}").Contains(f.Key))
.Select(e => e.item)
.ToArray(); .ToArray();
var missingItemValues = allListedItemValues.Except(existingValues.Select(f => (MagicNumber: f.Type, f.Value))).Select(f => new ItemValue() var missingItemValues = allListedItemValues.Except(existingValues.Select(f => (MagicNumber: f.Type, f.Value))).Select(f => new ItemValue()
{ {
@@ -1050,7 +1051,7 @@ public sealed class BaseItemRepository
entity.TotalBitrate = dto.TotalBitrate; entity.TotalBitrate = dto.TotalBitrate;
entity.ExternalId = dto.ExternalId; entity.ExternalId = dto.ExternalId;
entity.Size = dto.Size; entity.Size = dto.Size;
entity.Genres = string.Join('|', dto.Genres); entity.Genres = string.Join('|', dto.Genres.Distinct(StringComparer.OrdinalIgnoreCase));
entity.DateCreated = dto.DateCreated == DateTime.MinValue ? null : dto.DateCreated; entity.DateCreated = dto.DateCreated == DateTime.MinValue ? null : dto.DateCreated;
entity.DateModified = dto.DateModified == DateTime.MinValue ? null : dto.DateModified; entity.DateModified = dto.DateModified == DateTime.MinValue ? null : dto.DateModified;
entity.ChannelId = dto.ChannelId; entity.ChannelId = dto.ChannelId;
@@ -1077,9 +1078,9 @@ public sealed class BaseItemRepository
} }
entity.ExtraIds = dto.ExtraIds is not null ? string.Join('|', dto.ExtraIds) : null; entity.ExtraIds = dto.ExtraIds is not null ? string.Join('|', dto.ExtraIds) : null;
entity.ProductionLocations = dto.ProductionLocations is not null ? string.Join('|', dto.ProductionLocations.Where(p => !string.IsNullOrWhiteSpace(p))) : null; entity.ProductionLocations = dto.ProductionLocations is not null ? string.Join('|', dto.ProductionLocations.Where(p => !string.IsNullOrWhiteSpace(p)).Distinct(StringComparer.OrdinalIgnoreCase)) : null;
entity.Studios = dto.Studios is not null ? string.Join('|', dto.Studios) : null; entity.Studios = dto.Studios is not null ? string.Join('|', dto.Studios.Distinct(StringComparer.OrdinalIgnoreCase)) : null;
entity.Tags = dto.Tags is not null ? string.Join('|', dto.Tags) : null; entity.Tags = dto.Tags is not null ? string.Join('|', dto.Tags.Distinct(StringComparer.OrdinalIgnoreCase)) : null;
entity.LockedFields = dto.LockedFields is not null ? dto.LockedFields entity.LockedFields = dto.LockedFields is not null ? dto.LockedFields
.Select(e => new BaseItemMetadataField() .Select(e => new BaseItemMetadataField()
{ {
@@ -1122,12 +1123,12 @@ public sealed class BaseItemRepository
if (dto is IHasArtist hasArtists) if (dto is IHasArtist hasArtists)
{ {
entity.Artists = hasArtists.Artists is not null ? string.Join('|', hasArtists.Artists) : null; entity.Artists = hasArtists.Artists is not null ? string.Join('|', hasArtists.Artists.Distinct(StringComparer.OrdinalIgnoreCase)) : null;
} }
if (dto is IHasAlbumArtist hasAlbumArtists) if (dto is IHasAlbumArtist hasAlbumArtists)
{ {
entity.AlbumArtists = hasAlbumArtists.AlbumArtists is not null ? string.Join('|', hasAlbumArtists.AlbumArtists) : null; entity.AlbumArtists = hasAlbumArtists.AlbumArtists is not null ? string.Join('|', hasAlbumArtists.AlbumArtists.Distinct(StringComparer.OrdinalIgnoreCase)) : null;
} }
if (dto is LiveTvProgram program) if (dto is LiveTvProgram program)