123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- using System;
- using System.Collections.Generic;
- using System.Collections.Immutable;
- using System.Linq;
- using Jellyfin.Data.Entities;
- using Jellyfin.Data.Enums;
- using Jellyfin.Extensions;
- using MediaBrowser.Controller.Entities;
- using MediaBrowser.Controller.Persistence;
- using Microsoft.EntityFrameworkCore;
- namespace Jellyfin.Server.Implementations.Item;
- /// <summary>
- /// Manager for handling people.
- /// </summary>
- /// <param name="dbProvider">Efcore Factory.</param>
- /// <remarks>
- /// Initializes a new instance of the <see cref="PeopleRepository"/> class.
- /// </remarks>
- public class PeopleRepository(IDbContextFactory<JellyfinDbContext> dbProvider) : IPeopleRepository
- {
- private readonly IDbContextFactory<JellyfinDbContext> _dbProvider = dbProvider;
- /// <inheritdoc/>
- public IReadOnlyList<PersonInfo> GetPeople(InternalPeopleQuery filter)
- {
- using var context = _dbProvider.CreateDbContext();
- var dbQuery = TranslateQuery(context.Peoples.AsNoTracking(), context, filter);
- dbQuery = dbQuery.OrderBy(e => e.ListOrder);
- if (filter.Limit > 0)
- {
- dbQuery = dbQuery.Take(filter.Limit);
- }
- return dbQuery.ToList().Select(Map).ToImmutableArray();
- }
- /// <inheritdoc/>
- public IReadOnlyList<string> GetPeopleNames(InternalPeopleQuery filter)
- {
- using var context = _dbProvider.CreateDbContext();
- var dbQuery = TranslateQuery(context.Peoples.AsNoTracking(), context, filter);
- dbQuery = dbQuery.OrderBy(e => e.ListOrder);
- if (filter.Limit > 0)
- {
- dbQuery = dbQuery.Take(filter.Limit);
- }
- return dbQuery.Select(e => e.Name).ToImmutableArray();
- }
- /// <inheritdoc />
- public void UpdatePeople(Guid itemId, IReadOnlyList<PersonInfo> people)
- {
- using var context = _dbProvider.CreateDbContext();
- using var transaction = context.Database.BeginTransaction();
- context.Peoples.Where(e => e.ItemId.Equals(itemId)).ExecuteDelete();
- context.Peoples.AddRange(people.Select(Map));
- context.SaveChanges();
- transaction.Commit();
- }
- private PersonInfo Map(People people)
- {
- var personInfo = new PersonInfo()
- {
- ItemId = people.ItemId,
- Name = people.Name,
- Role = people.Role,
- SortOrder = people.SortOrder,
- };
- if (Enum.TryParse<PersonKind>(people.PersonType, out var kind))
- {
- personInfo.Type = kind;
- }
- return personInfo;
- }
- private People Map(PersonInfo people)
- {
- var personInfo = new People()
- {
- ItemId = people.ItemId,
- Name = people.Name,
- Role = people.Role,
- SortOrder = people.SortOrder,
- PersonType = people.Type.ToString(),
- Item = null!,
- ListOrder = people.SortOrder
- };
- return personInfo;
- }
- private IQueryable<People> TranslateQuery(IQueryable<People> query, JellyfinDbContext context, InternalPeopleQuery filter)
- {
- if (filter.User is not null && filter.IsFavorite.HasValue)
- {
- query = query.Where(e => e.PersonType == typeof(Person).FullName)
- .Where(e => context.BaseItems.Where(d => context.UserData.Where(e => e.IsFavorite == filter.IsFavorite && e.UserId.Equals(filter.User.Id)).Any(f => f.Key == d.UserDataKey))
- .Select(f => f.Name).Contains(e.Name));
- }
- if (!filter.ItemId.IsEmpty())
- {
- query = query.Where(e => e.ItemId.Equals(filter.ItemId));
- }
- if (!filter.AppearsInItemId.IsEmpty())
- {
- query = query.Where(e => context.Peoples.Where(f => f.ItemId.Equals(filter.AppearsInItemId)).Select(e => e.Name).Contains(e.Name));
- }
- var queryPersonTypes = filter.PersonTypes.Where(IsValidPersonType).ToList();
- if (queryPersonTypes.Count > 0)
- {
- query = query.Where(e => queryPersonTypes.Contains(e.PersonType));
- }
- var queryExcludePersonTypes = filter.ExcludePersonTypes.Where(IsValidPersonType).ToList();
- if (queryExcludePersonTypes.Count > 0)
- {
- query = query.Where(e => !queryPersonTypes.Contains(e.PersonType));
- }
- if (filter.MaxListOrder.HasValue)
- {
- query = query.Where(e => e.ListOrder <= filter.MaxListOrder.Value);
- }
- if (!string.IsNullOrWhiteSpace(filter.NameContains))
- {
- query = query.Where(e => e.Name.Contains(filter.NameContains));
- }
- return query;
- }
- private bool IsAlphaNumeric(string str)
- {
- if (string.IsNullOrWhiteSpace(str))
- {
- return false;
- }
- for (int i = 0; i < str.Length; i++)
- {
- if (!char.IsLetter(str[i]) && !char.IsNumber(str[i]))
- {
- return false;
- }
- }
- return true;
- }
- private bool IsValidPersonType(string value)
- {
- return IsAlphaNumeric(value);
- }
- }
|