diff options
| author | Shadowghost <Ghost_of_Stone@web.de> | 2026-08-01 20:35:27 +0200 |
|---|---|---|
| committer | Shadowghost <Ghost_of_Stone@web.de> | 2026-08-01 20:35:27 +0200 |
| commit | cbc2c7c32345f670d928f7840e5fd7422241845d (patch) | |
| tree | 6f30a48c212c882a71cf08db93bfb430fa993678 /Jellyfin.Server.Implementations | |
| parent | e123a13e3853087a87a845c7738a74c22ea9064f (diff) | |
Preserve multiple roles per person type instead of deduping credits by name and type
Diffstat (limited to 'Jellyfin.Server.Implementations')
| -rw-r--r-- | Jellyfin.Server.Implementations/Item/PeopleRepository.cs | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/Jellyfin.Server.Implementations/Item/PeopleRepository.cs b/Jellyfin.Server.Implementations/Item/PeopleRepository.cs index 6637d99afa..367d48debb 100644 --- a/Jellyfin.Server.Implementations/Item/PeopleRepository.cs +++ b/Jellyfin.Server.Implementations/Item/PeopleRepository.cs @@ -40,7 +40,7 @@ public class PeopleRepository(IDbContextFactory<JellyfinDbContext> dbProvider, I if (!filter.ItemId.IsEmpty()) { dbQuery = dbQuery.Include(p => p.BaseItems!.Where(m => m.ItemId == filter.ItemId)) - .OrderBy(e => e.BaseItems!.First(e => e.ItemId == filter.ItemId).ListOrder) + .OrderBy(e => e.BaseItems!.Where(m => m.ItemId == filter.ItemId).Min(m => m.ListOrder)) .ThenBy(e => e.PersonType) .ThenBy(e => e.Name); } @@ -81,7 +81,7 @@ public class PeopleRepository(IDbContextFactory<JellyfinDbContext> dbProvider, I { StartIndex = filter.StartIndex ?? 0, TotalRecordCount = count, - Items = dbQuery.AsEnumerable().Select(Map).ToArray(), + Items = dbQuery.AsEnumerable().SelectMany(MapCredits).ToArray(), }; } @@ -117,9 +117,13 @@ public class PeopleRepository(IDbContextFactory<JellyfinDbContext> dbProvider, I person.Role = person.Role?.Trim() ?? string.Empty; } - // multiple metadata providers can provide the _same_ person; dedupe case-insensitively. - people = people.DistinctBy(e => e.Name.ToLowerInvariant() + "-" + e.Type).ToArray(); - var personKeys = people.Select(e => e.Name.ToLowerInvariant() + "-" + e.Type).ToArray(); + // multiple metadata providers can provide the _same_ credit; dedupe case-insensitively. + // The role is part of the key because one person can hold several credits of the same type + // on an item, e.g. a Writer credited for both the Novel and the Screenplay. + people = people.DistinctBy(e => e.Name.ToLowerInvariant() + "-" + e.Type + "-" + e.Role.ToLowerInvariant()).ToArray(); + + var distinctPersons = people.DistinctBy(e => e.Name.ToLowerInvariant() + "-" + e.Type).ToArray(); + var personKeys = distinctPersons.Select(e => e.Name.ToLowerInvariant() + "-" + e.Type).ToArray(); using var context = _dbProvider.CreateDbContext(); using var transaction = context.Database.BeginTransaction(); @@ -132,9 +136,10 @@ public class PeopleRepository(IDbContextFactory<JellyfinDbContext> dbProvider, I .Select(f => f.item) .ToArray(); - var toAdd = people + var toAdd = distinctPersons .Where(e => !existingPersons.Any(f => string.Equals(f.Name, e.Name, StringComparison.OrdinalIgnoreCase) && f.PersonType == e.Type.ToString())) - .Select(Map); + .Select(Map) + .ToArray(); context.Peoples.AddRange(toAdd); context.SaveChanges(); @@ -215,9 +220,19 @@ public class PeopleRepository(IDbContextFactory<JellyfinDbContext> dbProvider, I return result; } - private PersonInfo Map(People people) + private IEnumerable<PersonInfo> MapCredits(People people) + { + var mappings = people.BaseItems; + if (mappings is null || mappings.Count == 0) + { + return [Map(people, null)]; + } + + return mappings.OrderBy(m => m.ListOrder).Select(m => Map(people, m)); + } + + private PersonInfo Map(People people, PeopleBaseItemMap? mapping) { - var mapping = people.BaseItems?.FirstOrDefault(); var personInfo = new PersonInfo() { Id = people.Id, |
