diff options
| author | JPVenson <github@jpb.email> | 2025-09-25 00:20:30 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-24 15:20:30 -0600 |
| commit | 5a6d9180fed81a30cb91ef3fed30176cd4402116 (patch) | |
| tree | c67bfa1cfe27ff1a7b7a09e3a7d201ef543652a0 /Jellyfin.Server.Implementations/Item | |
| parent | 897975fc57f1669322f6db18753939dbf6be43e8 (diff) | |
Add People Dedup and multiple progress fixes (#14848)
Diffstat (limited to 'Jellyfin.Server.Implementations/Item')
| -rw-r--r-- | Jellyfin.Server.Implementations/Item/BaseItemRepository.cs | 20 | ||||
| -rw-r--r-- | Jellyfin.Server.Implementations/Item/PeopleRepository.cs | 34 |
2 files changed, 40 insertions, 14 deletions
diff --git a/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs b/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs index a34e95c4d..68260fbf0 100644 --- a/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs +++ b/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs @@ -99,11 +99,11 @@ public sealed class BaseItemRepository } /// <inheritdoc /> - public void DeleteItem(Guid id) + public void DeleteItem(params IReadOnlyList<Guid> ids) { - if (id.IsEmpty() || id.Equals(PlaceholderId)) + if (ids is null || ids.Count == 0 || ids.Any(f => f.Equals(PlaceholderId))) { - throw new ArgumentException("Guid can't be empty or the placeholder id.", nameof(id)); + throw new ArgumentException("Guid can't be empty or the placeholder id.", nameof(ids)); } using var context = _dbProvider.CreateDbContext(); @@ -111,7 +111,7 @@ public sealed class BaseItemRepository var date = (DateTime?)DateTime.UtcNow; - var relatedItems = TraverseHirachyDown(id, context).ToArray(); + var relatedItems = ids.SelectMany(f => TraverseHirachyDown(f, context)).ToArray(); // Remove any UserData entries for the placeholder item that would conflict with the UserData // being detached from the item being deleted. This is necessary because, during an update, @@ -2538,4 +2538,16 @@ public sealed class BaseItemRepository return folderList; } + + /// <inheritdoc/> + public IReadOnlyDictionary<string, MusicArtist[]> FindArtists(IReadOnlyList<string> artistNames) + { + using var dbContext = _dbProvider.CreateDbContext(); + + var artists = dbContext.BaseItems.Where(e => e.Type == _itemTypeLookup.BaseItemKindNames[BaseItemKind.MusicArtist]!) + .Where(e => artistNames.Contains(e.Name)) + .ToArray(); + + return artists.GroupBy(e => e.Name).ToDictionary(e => e.Key!, e => e.Select(f => DeserializeBaseItem(f)).Cast<MusicArtist>().ToArray()); + } } diff --git a/Jellyfin.Server.Implementations/Item/PeopleRepository.cs b/Jellyfin.Server.Implementations/Item/PeopleRepository.cs index 24afaea55..0f423cf5d 100644 --- a/Jellyfin.Server.Implementations/Item/PeopleRepository.cs +++ b/Jellyfin.Server.Implementations/Item/PeopleRepository.cs @@ -74,20 +74,34 @@ public class PeopleRepository(IDbContextFactory<JellyfinDbContext> dbProvider, I /// <inheritdoc /> public void UpdatePeople(Guid itemId, IReadOnlyList<PersonInfo> people) { - // TODO: yes for __SOME__ reason there can be duplicates. - people = people.DistinctBy(e => e.Id).ToArray(); - var personids = people.Select(f => f.Id); + // multiple metadata providers can provide the _same_ person + people = people.DistinctBy(e => e.Name + "-" + e.Type).ToArray(); + var personKeys = people.Select(e => e.Name + "-" + e.Type).ToArray(); using var context = _dbProvider.CreateDbContext(); using var transaction = context.Database.BeginTransaction(); - var existingPersons = context.Peoples.Where(p => personids.Contains(p.Id)).Select(f => f.Id).ToArray(); - context.Peoples.AddRange(people.Where(e => !existingPersons.Contains(e.Id)).Select(Map)); + var existingPersons = context.Peoples.Select(e => new + { + item = e, + SelectionKey = e.Name + "-" + e.PersonType + }) + .Where(p => personKeys.Contains(p.SelectionKey)) + .Select(f => f.item) + .ToArray(); + + var toAdd = people + .Where(e => !existingPersons.Any(f => f.Name == e.Name && f.PersonType == e.Type.ToString())) + .Select(Map); + context.Peoples.AddRange(toAdd); context.SaveChanges(); - var maps = context.PeopleBaseItemMap.Where(e => e.ItemId == itemId).ToList(); + var personsEntities = toAdd.Concat(existingPersons).ToArray(); + + var existingMaps = context.PeopleBaseItemMap.Include(e => e.People).Where(e => e.ItemId == itemId).ToList(); foreach (var person in people) { - var existingMap = maps.FirstOrDefault(e => e.PeopleId == person.Id); + var entityPerson = personsEntities.First(e => e.Name == person.Name && e.PersonType == person.Type.ToString()); + var existingMap = existingMaps.FirstOrDefault(e => e.People.Name == person.Name && e.Role == person.Role); if (existingMap is null) { var sortOrder = (person.SortOrder ?? context.PeopleBaseItemMap.Where(e => e.ItemId == itemId).Max(e => e.SortOrder) ?? 0) + 1; @@ -96,7 +110,7 @@ public class PeopleRepository(IDbContextFactory<JellyfinDbContext> dbProvider, I Item = null!, ItemId = itemId, People = null!, - PeopleId = person.Id, + PeopleId = entityPerson.Id, ListOrder = sortOrder, SortOrder = sortOrder, Role = person.Role @@ -105,11 +119,11 @@ public class PeopleRepository(IDbContextFactory<JellyfinDbContext> dbProvider, I else { // person mapping already exists so remove from list - maps.Remove(existingMap); + existingMaps.Remove(existingMap); } } - context.PeopleBaseItemMap.RemoveRange(maps); + context.PeopleBaseItemMap.RemoveRange(existingMaps); context.SaveChanges(); transaction.Commit(); |
