using System; using System.Globalization; using System.Threading; using System.Threading.Tasks; using Jellyfin.Data.Enums; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.IO; using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Library.Validators { /// /// Class PeopleValidator. /// public class PeopleValidator { /// /// The _library manager. /// private readonly ILibraryManager _libraryManager; /// /// The _logger. /// private readonly ILogger _logger; private readonly IFileSystem _fileSystem; /// /// Initializes a new instance of the class. /// /// The library manager. /// The logger. /// The file system. public PeopleValidator(ILibraryManager libraryManager, ILogger logger, IFileSystem fileSystem) { _libraryManager = libraryManager; _logger = logger; _fileSystem = fileSystem; } /// /// Validates the people. /// /// The cancellation token. /// The progress. /// Task. public async Task ValidatePeople(CancellationToken cancellationToken, IProgress progress) { var people = _libraryManager.GetPeopleNames(new InternalPeopleQuery()); var numComplete = 0; var numPeople = people.Count; _logger.LogDebug("Will refresh {0} people", numPeople); foreach (var person in people) { cancellationToken.ThrowIfCancellationRequested(); try { var item = _libraryManager.GetPerson(person); if (item is null) { _logger.LogWarning("Failed to get person: {Name}", person); continue; } var options = new MetadataRefreshOptions(new DirectoryService(_fileSystem)) { ImageRefreshMode = MetadataRefreshMode.ValidationOnly, MetadataRefreshMode = MetadataRefreshMode.ValidationOnly }; await item.RefreshMetadata(options, cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { throw; } catch (Exception ex) { _logger.LogError(ex, "Error validating IBN entry {Person}", person); } // Update progress numComplete++; double percent = numComplete; percent /= numPeople; progress.Report(100 * percent); } var deadEntities = _libraryManager.GetItemList(new InternalItemsQuery { IncludeItemTypes = [BaseItemKind.Person], IsDeadPerson = true, IsLocked = false }); foreach (var item in deadEntities) { _logger.LogInformation( "Deleting dead {2} {0} {1}.", item.Id.ToString("N", CultureInfo.InvariantCulture), item.Name, item.GetType().Name); _libraryManager.DeleteItem( item, new DeleteOptions { DeleteFileLocation = false }, false); } progress.Report(100); _logger.LogInformation("People validation complete"); } } }