/// <summary> /// Validates the people. /// </summary> /// <param name="cancellationToken">The cancellation token.</param> /// <param name="progress">The progress.</param> /// <returns>Task.</returns> public async Task ValidatePeople(CancellationToken cancellationToken, IProgress <double> progress) { var innerProgress = new ActionableProgress <double>(); innerProgress.RegisterAction(pct => progress.Report(pct * .15)); var peopleOptions = _config.Configuration.PeopleMetadataOptions; var people = _libraryManager.GetAllPeople(); var dict = new Dictionary <string, bool>(StringComparer.OrdinalIgnoreCase); foreach (var person in people) { bool current; if (!dict.TryGetValue(person.Name, out current) || !current) { dict[person.Name] = DownloadMetadata(person, peopleOptions); } } var numComplete = 0; foreach (var person in dict) { cancellationToken.ThrowIfCancellationRequested(); try { var item = _libraryManager.GetPerson(person.Key); var options = new MetadataRefreshOptions { MetadataRefreshMode = person.Value ? MetadataRefreshMode.Default : MetadataRefreshMode.ValidationOnly, ImageRefreshMode = person.Value ? ImageRefreshMode.Default : ImageRefreshMode.ValidationOnly }; await item.RefreshMetadata(options, cancellationToken).ConfigureAwait(false); } catch (Exception ex) { _logger.ErrorException("Error validating IBN entry {0}", ex, person); } // Update progress numComplete++; double percent = numComplete; percent /= people.Count; progress.Report(100 * percent); } progress.Report(100); _logger.Info("People validation complete"); // Bad practice, i know. But we keep a lot in memory, unfortunately. GC.Collect(2, GCCollectionMode.Forced, true); GC.Collect(2, GCCollectionMode.Forced, true); }
/// <summary> /// Validates the people. /// </summary> /// <param name="cancellationToken">The cancellation token.</param> /// <param name="progress">The progress.</param> /// <returns>Task.</returns> public async Task ValidatePeople(CancellationToken cancellationToken, IProgress <double> progress) { var innerProgress = new ActionableProgress <double>(); innerProgress.RegisterAction(pct => progress.Report(pct * .15)); var peopleOptions = _config.Configuration.PeopleMetadataOptions; var people = _libraryManager.GetAllPeople(); var dict = new Dictionary <string, bool>(StringComparer.OrdinalIgnoreCase); foreach (var person in people) { var isMetadataEnabled = DownloadMetadata(person, peopleOptions); bool currentValue; if (dict.TryGetValue(person.Name, out currentValue)) { if (!currentValue && isMetadataEnabled) { dict[person.Name] = true; } } else { dict[person.Name] = isMetadataEnabled; } } var numComplete = 0; var validIds = new List <Guid>(); foreach (var person in dict) { cancellationToken.ThrowIfCancellationRequested(); try { var item = _libraryManager.GetPerson(person.Key); validIds.Add(item.Id); var options = new MetadataRefreshOptions(_fileSystem) { MetadataRefreshMode = person.Value ? MetadataRefreshMode.Default : MetadataRefreshMode.ValidationOnly, ImageRefreshMode = person.Value ? ImageRefreshMode.Default : ImageRefreshMode.ValidationOnly }; await item.RefreshMetadata(options, cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { throw; } catch (Exception ex) { _logger.ErrorException("Error validating IBN entry {0}", ex, person); } // Update progress numComplete++; double percent = numComplete; percent /= people.Count; progress.Report(100 * percent); } var allIds = _libraryManager.GetItemIds(new InternalItemsQuery { IncludeItemTypes = new[] { typeof(Person).Name } }); var invalidIds = allIds .Except(validIds) .ToList(); foreach (var id in invalidIds) { cancellationToken.ThrowIfCancellationRequested(); var item = _libraryManager.GetItemById(id); if (item != null) { await _libraryManager.DeleteItem(item, new DeleteOptions { DeleteFileLocation = false }).ConfigureAwait(false); } } progress.Report(100); _logger.Info("People validation complete"); // Bad practice, i know. But we keep a lot in memory, unfortunately. GC.Collect(2, GCCollectionMode.Forced, true); GC.Collect(2, GCCollectionMode.Forced, true); }