aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Server.Implementations
diff options
context:
space:
mode:
authorShadowghost <Ghost_of_Stone@web.de>2026-08-01 20:35:27 +0200
committerShadowghost <Ghost_of_Stone@web.de>2026-08-01 20:35:27 +0200
commitcbc2c7c32345f670d928f7840e5fd7422241845d (patch)
tree6f30a48c212c882a71cf08db93bfb430fa993678 /Jellyfin.Server.Implementations
parente123a13e3853087a87a845c7738a74c22ea9064f (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.cs33
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,