People Aliases and Merging (#3795)
Co-authored-by: Joseph Milazzo <josephmajora@gmail.com>
This commit is contained in:
parent
cd2a6af6f2
commit
7ce36bfc44
67 changed files with 5288 additions and 284 deletions
|
@ -15,6 +15,7 @@ using API.DTOs.KavitaPlus.Manage;
|
|||
using API.DTOs.KavitaPlus.Metadata;
|
||||
using API.DTOs.MediaErrors;
|
||||
using API.DTOs.Metadata;
|
||||
using API.DTOs.Person;
|
||||
using API.DTOs.Progress;
|
||||
using API.DTOs.Reader;
|
||||
using API.DTOs.ReadingLists;
|
||||
|
@ -68,7 +69,8 @@ public class AutoMapperProfiles : Profile
|
|||
CreateMap<AppUserCollection, AppUserCollectionDto>()
|
||||
.ForMember(dest => dest.Owner, opt => opt.MapFrom(src => src.AppUser.UserName))
|
||||
.ForMember(dest => dest.ItemCount, opt => opt.MapFrom(src => src.Items.Count));
|
||||
CreateMap<Person, PersonDto>();
|
||||
CreateMap<Person, PersonDto>()
|
||||
.ForMember(dest => dest.Aliases, opt => opt.MapFrom(src => src.Aliases.Select(s => s.Alias)));
|
||||
CreateMap<Genre, GenreTagDto>();
|
||||
CreateMap<Tag, TagDto>();
|
||||
CreateMap<AgeRating, AgeRatingDto>();
|
||||
|
|
19
API/Helpers/Builders/PersonAliasBuilder.cs
Normal file
19
API/Helpers/Builders/PersonAliasBuilder.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
using API.Entities.Person;
|
||||
using API.Extensions;
|
||||
|
||||
namespace API.Helpers.Builders;
|
||||
|
||||
public class PersonAliasBuilder : IEntityBuilder<PersonAlias>
|
||||
{
|
||||
private readonly PersonAlias _alias;
|
||||
public PersonAlias Build() => _alias;
|
||||
|
||||
public PersonAliasBuilder(string name)
|
||||
{
|
||||
_alias = new PersonAlias()
|
||||
{
|
||||
Alias = name.Trim(),
|
||||
NormalizedAlias = name.ToNormalized(),
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using API.Entities;
|
||||
using API.Entities.Enums;
|
||||
using API.Entities.Metadata;
|
||||
using System.Linq;
|
||||
using API.Entities.Person;
|
||||
using API.Extensions;
|
||||
|
||||
|
@ -34,6 +32,20 @@ public class PersonBuilder : IEntityBuilder<Person>
|
|||
return this;
|
||||
}
|
||||
|
||||
public PersonBuilder WithAlias(string alias)
|
||||
{
|
||||
if (_person.Aliases.Any(a => a.NormalizedAlias.Equals(alias.ToNormalized())))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
_person.Aliases.Add(new PersonAliasBuilder(alias).Build());
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public PersonBuilder WithSeriesMetadata(SeriesMetadataPeople seriesMetadataPeople)
|
||||
{
|
||||
_person.SeriesMetadataPeople.Add(seriesMetadataPeople);
|
||||
|
|
|
@ -17,6 +17,20 @@ namespace API.Helpers;
|
|||
public static class PersonHelper
|
||||
{
|
||||
|
||||
public static Dictionary<string, Person> ConstructNameAndAliasDictionary(IList<Person> people)
|
||||
{
|
||||
var dict = new Dictionary<string, Person>();
|
||||
foreach (var person in people)
|
||||
{
|
||||
dict.TryAdd(person.NormalizedName, person);
|
||||
foreach (var alias in person.Aliases)
|
||||
{
|
||||
dict.TryAdd(alias.NormalizedAlias, person);
|
||||
}
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
|
||||
public static async Task UpdateSeriesMetadataPeopleAsync(SeriesMetadata metadata, ICollection<SeriesMetadataPeople> metadataPeople,
|
||||
IEnumerable<ChapterPeople> chapterPeople, PersonRole role, IUnitOfWork unitOfWork)
|
||||
{
|
||||
|
@ -38,7 +52,9 @@ public static class PersonHelper
|
|||
|
||||
// Identify people to remove from metadataPeople
|
||||
var peopleToRemove = existingMetadataPeople
|
||||
.Where(person => !peopleToAddSet.Contains(person.Person.NormalizedName))
|
||||
.Where(person =>
|
||||
!peopleToAddSet.Contains(person.Person.NormalizedName) &&
|
||||
!person.Person.Aliases.Any(pa => peopleToAddSet.Contains(pa.NormalizedAlias)))
|
||||
.ToList();
|
||||
|
||||
// Remove identified people from metadataPeople
|
||||
|
@ -53,11 +69,7 @@ public static class PersonHelper
|
|||
.GetPeopleByNames(peopleToAdd.Select(p => p.NormalizedName).ToList());
|
||||
|
||||
// Prepare a dictionary for quick lookup of existing people by normalized name
|
||||
var existingPeopleDict = new Dictionary<string, Person>();
|
||||
foreach (var person in existingPeopleInDb)
|
||||
{
|
||||
existingPeopleDict.TryAdd(person.NormalizedName, person);
|
||||
}
|
||||
var existingPeopleDict = ConstructNameAndAliasDictionary(existingPeopleInDb);
|
||||
|
||||
// Track the people to attach (newly created people)
|
||||
var peopleToAttach = new List<Person>();
|
||||
|
@ -129,15 +141,12 @@ public static class PersonHelper
|
|||
var existingPeople = await unitOfWork.PersonRepository.GetPeopleByNames(normalizedPeople);
|
||||
|
||||
// Prepare a dictionary for quick lookup by normalized name
|
||||
var existingPeopleDict = new Dictionary<string, Person>();
|
||||
foreach (var person in existingPeople)
|
||||
{
|
||||
existingPeopleDict.TryAdd(person.NormalizedName, person);
|
||||
}
|
||||
var existingPeopleDict = ConstructNameAndAliasDictionary(existingPeople);
|
||||
|
||||
// Identify people to remove (those present in ChapterPeople but not in the new list)
|
||||
foreach (var existingChapterPerson in existingChapterPeople
|
||||
.Where(existingChapterPerson => !normalizedPeople.Contains(existingChapterPerson.Person.NormalizedName)))
|
||||
var toRemove = existingChapterPeople
|
||||
.Where(existingChapterPerson => !normalizedPeople.Contains(existingChapterPerson.Person.NormalizedName));
|
||||
foreach (var existingChapterPerson in toRemove)
|
||||
{
|
||||
chapter.People.Remove(existingChapterPerson);
|
||||
unitOfWork.PersonRepository.Remove(existingChapterPerson);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue