using System.Collections.ObjectModel; using System.Text.Json; using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models.Properties; using View_by_Distance.Shared.Models.Stateless; namespace View_by_Distance.Distance.Models.Stateless; internal static class FaceEncodingLogic { internal static void MoveUnableToMatch(FilePath filePath) { string checkFile = $"{filePath.FullName}.unk"; if (File.Exists(filePath.FullName) && !File.Exists(checkFile)) File.Move(filePath.FullName, checkFile); } internal static ReadOnlyDictionary> GetMappedIdsThenWholePercentagesToLocationContainer(ResultSettings resultSettings, MetadataSettings metadataSettings, PeopleSettings peopleSettings, DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, ReadOnlyCollections readOnlyCollections) { ReadOnlyDictionary> results; List locationContainers = []; int maxDegreeOfParallelism = compareSettings.MaxDegreeOfParallelism; ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism }; ReadOnlyCollection exifDirectories = MappedLogicA.GetMapped(resultSettings, metadataSettings, peopleSettings, distanceSettings, compareSettings, compare, readOnlyCollections); int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - compare.Ticks).TotalSeconds); string message = $") Building Mapped with Encoding Face Files Collection - {totalSeconds} total second(s)"; compare.ConstructProgressBar(exifDirectories.Count, message); _ = Parallel.For(0, exifDirectories.Count, parallelOptions, (i, state) => LocationContainersParallelFor(distanceSettings, compareSettings, compare, exifDirectories, i, locationContainers)); results = GetMappedIdsThenWholePercentagesToLocationContainer(locationContainers); return results; } private static void LocationContainersParallelFor(DistanceSettings distanceSettings, ICompareSettings compareSettings, ICompare compare, ReadOnlyCollection exifDirectories, int i, List results) { compare.Tick(); ExifDirectory exifDirectory = exifDirectories[i]; LocationContainer? locationContainer = GetLocationContainer(distanceSettings, compareSettings, exifDirectory); results.Add(locationContainer); } internal static LocationContainer? GetLocationContainer(DistanceSettings distanceSettings, ICompareSettings compareSettings, ExifDirectory exifDirectory) { LocationContainer? result; string? json; DateOnly dateOnly; FaceFile? faceFile; int? wholePercentages; FaceEncoding? faceEncoding; FaceRecognitionDotNet.Models.FaceEncoding? encoding; wholePercentages = IMapping.GetWholePercentages(compareSettings, exifDirectory.FilePath); if (wholePercentages is null) { if (distanceSettings.DistanceMoveUnableToMatch) MoveUnableToMatch(exifDirectory.FilePath); result = null; } else { faceFile = GetFaceFile(distanceSettings, exifDirectory); if (faceFile is null) result = null; else { dateOnly = DateOnly.FromDateTime(new DateTime(exifDirectory.FilePath.CreationTicks)); json = Metadata.Models.Stateless.IMetadata.GetFaceEncoding(exifDirectory); faceEncoding = json is null ? null : JsonSerializer.Deserialize(json, FaceEncodingGenerationContext.Default.FaceEncoding); if (faceEncoding is null) result = null; else { encoding = FaceRecognitionDotNet.Models.FaceRecognition.LoadFaceEncoding(faceEncoding.RawEncoding); result = new(CreationDateOnly: dateOnly, ExifDirectory: exifDirectory, Encoding: encoding, FaceFile: faceFile, FilePath: exifDirectory.FilePath, LengthPermyriad: null, LengthSource: null, PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName: exifDirectory.PersonKeyFormattedAndKeyTicksAndDisplayDirectoryName, WholePercentages: wholePercentages); } } } return result; } private static FaceFile? GetFaceFile(DistanceSettings distanceSettings, ExifDirectory exifDirectory) { FaceFile? result; string? json = Metadata.Models.Stateless.IMetadata.GetOutputResolution(exifDirectory); if (json is null || !json.Contains(nameof(DateTime))) { if (distanceSettings.DistanceMoveUnableToMatch) MoveUnableToMatch(exifDirectory.FilePath); result = null; } else { result = JsonSerializer.Deserialize(json, FaceFileGenerationContext.Default.FaceFile); if (result is null || result.Location is null) { if (distanceSettings.DistanceMoveUnableToMatch) MoveUnableToMatch(exifDirectory.FilePath); result = null; } } return result; } private static ReadOnlyDictionary> GetMappedIdsThenWholePercentagesToLocationContainer(List locationContainers) { Dictionary> results = []; int id; int wholePercentages; Dictionary? keyValue; Dictionary> keyValuePairs = []; foreach (LocationContainer? locationContainer in locationContainers) { if (locationContainer?.FilePath.Id is null || locationContainer.WholePercentages is null) continue; id = locationContainer.FilePath.Id.Value; wholePercentages = locationContainer.WholePercentages.Value; if (!keyValuePairs.TryGetValue(id, out keyValue)) { keyValuePairs.Add(id, []); if (!keyValuePairs.TryGetValue(id, out keyValue)) throw new Exception(); } keyValue.Add(wholePercentages, locationContainer); } foreach (KeyValuePair> keyValuePair in keyValuePairs) results.Add(keyValuePair.Key, keyValuePair.Value.AsReadOnly()); return results.AsReadOnly(); } }