From 9ebfdc8af2e97a6f440852364251fba532281b34 Mon Sep 17 00:00:00 2001 From: Mike Phares Date: Sat, 20 Jul 2024 10:48:26 -0700 Subject: [PATCH] Reuse count over t FilePath over String Support first run better Bump --- Copy-Distinct/CopyDistinct.cs | 3 +- Instance/DlibDotNet.cs | 155 ++++++++++-------- Map/Models/MapLogic.cs | 21 +-- Map/Models/Stateless/MapLogic.cs | 4 +- Shared/Models/Stateless/Methods/Container.cs | 46 +++--- Shared/Models/Stateless/Methods/IContainer.cs | 8 +- Shared/Models/Stateless/Methods/IDirectory.cs | 26 ++- Shared/Models/Stateless/Methods/XDirectory.cs | 92 ++++++++--- Tests/Tests.csproj | 4 +- .../TestsWithFaceRecognitionDotNet.csproj | 4 +- 10 files changed, 216 insertions(+), 147 deletions(-) diff --git a/Copy-Distinct/CopyDistinct.cs b/Copy-Distinct/CopyDistinct.cs index 769a6d5..eea9737 100644 --- a/Copy-Distinct/CopyDistinct.cs +++ b/Copy-Distinct/CopyDistinct.cs @@ -180,7 +180,8 @@ public class CopyDistinct progressBar = new(count, message, options); string key = string.IsNullOrEmpty(_AppSettings.ResultDirectoryKey) ? _PropertyConfiguration.ResultAllInOne : _AppSettings.ResultDirectoryKey; string[] directories = _FileGroups[key]; - (distinctDirectories, toDoCollection) = IDirectory.GetToDoCollection(_PropertyConfiguration, _AppSettings.CopyDuplicates, _AppSettings.IfCanUseId, filesCollection, directories, () => progressBar.Tick()); + ReadOnlyCollection> filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, filesCollection); + (distinctDirectories, toDoCollection) = IDirectory.GetToDoCollection(_PropertyConfiguration, _AppSettings.CopyDuplicates, _AppSettings.IfCanUseId, filePathsCollection, directories, () => progressBar.Tick()); progressBar.Dispose(); } foreach (string distinctDirectory in distinctDirectories) diff --git a/Instance/DlibDotNet.cs b/Instance/DlibDotNet.cs index ff33baa..32b6129 100644 --- a/Instance/DlibDotNet.cs +++ b/Instance/DlibDotNet.cs @@ -252,26 +252,26 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable throw new Exception("Configuration has SaveSortingWithoutPerson and FocusDirectory!"); } - private ReadOnlyCollection GetNotNineCollection(ReadOnlyCollection filesCollection) + private ReadOnlyCollection GetNotNineCollection(ReadOnlyCollection> filePathsCollection) { List results = []; FileInfo fileInfo; - FilePath filePath; FileHolder fileHolder; - foreach (string[] files in filesCollection) + FilePath checkFilePath; + foreach (ReadOnlyCollection filePaths in filePathsCollection) { - foreach (string file in files) + foreach (FilePath filePath in filePaths) { - if (!file.Contains(" !9")) + if (!filePath.FullName.Contains(" !9")) continue; - fileInfo = new(file); + fileInfo = new(filePath.FullName); fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(fileInfo); if (!fileInfo.Attributes.HasFlag(FileAttributes.Hidden)) File.SetAttributes(fileHolder.FullName, FileAttributes.Hidden); - filePath = FilePath.Get(_Configuration.PropertyConfiguration, fileHolder, index: null); - if (filePath.Id is null) + checkFilePath = FilePath.Get(_Configuration.PropertyConfiguration, fileHolder, index: null); + if (checkFilePath.Id is null) continue; - results.Add(filePath.Id.Value); + results.Add(checkFilePath.Id.Value); } } return new(results); @@ -320,10 +320,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable private void Search(long ticks, ReadOnlyCollection personContainers, string argZero, string propertyRoot) { - int t; string message; MapLogic? mapLogic; - Container[] containers; A_Property propertyLogic; string eDistanceContentDirectory; string? a2PeopleContentDirectory; @@ -337,11 +335,12 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable const string directorySearchFilter = "*"; string? filesCollectionRootDirectory = null; bool configurationOutputResolutionsHas = false; + ReadOnlyCollection readOnlyContainers; ReadOnlyCollection? notNineCollection = null; ReadOnlyDictionary> personKeyToIds; - ReadOnlyCollection? filesCollection = null; + ReadOnlyCollection>? filePathsCollection = null; + bool runToDoCollectionFirst = GetRunToDoCollectionFirst(_Configuration, ticks); (aResultsFullGroupDirectory, bResultsFullGroupDirectory) = GetResultsFullGroupDirectories(); - bool runToDoCollectionFirst = GetRunToDoCollectionFirst(_Configuration.PropertyConfiguration, ticks); ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; Shared.Models.Stateless.Methods.IPath.ChangeDateForEmptyDirectories(_Configuration.PropertyConfiguration.RootDirectory, ticks); a2PeopleContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "([])"); @@ -359,8 +358,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable configurationOutputResolutionsHas = true; if (!runToDoCollectionFirst) break; - (filesCollectionRootDirectory, filesCollection, filesCollectionCountIsOne) = GetFilesCollectionThenCopyOrMove(ticks, fileSearchFilter, directorySearchFilter, options, outputResolution); - notNineCollection = GetNotNineCollection(filesCollection); + (filesCollectionRootDirectory, filePathsCollection, filesCollectionCountIsOne) = GetFilesCollectionThenCopyOrMove(ticks, fileSearchFilter, directorySearchFilter, options, outputResolution); + notNineCollection = GetNotNineCollection(filePathsCollection); break; } fPhotoPrismContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(F_PhotoPrism), _Configuration.PropertyConfiguration.ResultContent); @@ -368,8 +367,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse, aResultsFullGroupDirectory); if (filesCollectionCountIsOne) { - if (filesCollection is null) - throw new NullReferenceException(nameof(filesCollection)); + if (filePathsCollection is null) + throw new NullReferenceException(nameof(filePathsCollection)); string resultsGroupDirectory; a2PeopleContentDirectory = null; eDistanceContentDirectory = Path.Combine($"{Path.GetPathRoot(argZero)}", _Configuration.PropertyConfiguration.ResultContent); @@ -380,7 +379,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable resultsGroupDirectory = Property.Models.Stateless.IResult.GetResultsGroupDirectory(_Configuration.PropertyConfiguration, string.Empty, create: true); _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(resultsGroupDirectory); } - argZero = SaveUrlAndGetNewRootDirectory(filesCollection.First()); + argZero = SaveUrlAndGetNewRootDirectory(filePathsCollection.First()); _Configuration.PropertyConfiguration.ChangeRootDirectory(argZero); (aResultsFullGroupDirectory, bResultsFullGroupDirectory) = GetResultsFullGroupDirectories(); propertyRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(_Configuration.PropertyConfiguration, nameof(A_Property), create: false); @@ -388,34 +387,32 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable } if (configurationOutputResolutionsHas) { - int count; foreach (string outputResolution in _Configuration.OutputResolutions) { if (outputResolution.Any(char.IsNumber)) continue; (cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution); filesCollectionRootDirectory = Path.Combine(cResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent); - filesCollection = IDirectory.GetFilesCollection(filesCollectionRootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage: true); - count = filesCollection.Select(l => l.Length).Sum(); + filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, filesCollectionRootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage: true); break; } } - if (filesCollectionRootDirectory is null || filesCollection is null) - throw new NullReferenceException(nameof(filesCollection)); - message = $") Building Container(s) - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)"; + if (filesCollectionRootDirectory is null || filePathsCollection is null) + throw new NullReferenceException(nameof(filePathsCollection)); string aPropertySingletonDirectory = Path.Combine(aResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultSingleton); if (!Directory.Exists(aPropertySingletonDirectory)) _ = Directory.CreateDirectory(aPropertySingletonDirectory); - _ProgressBar = new(short.MaxValue, message, options); - (t, containers) = Shared.Models.Stateless.Methods.IContainer.GetContainers(this, _Configuration.PropertyConfiguration, aPropertySingletonDirectory, filesCollectionRootDirectory, filesCollection); + int count = filePathsCollection.Select(l => l.Count).Sum(); + SaveDistinctIds(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, filePathsCollection); + message = $") Building Container(s) - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)"; + _ProgressBar = new(count, message, options); + readOnlyContainers = Shared.Models.Stateless.Methods.IContainer.GetContainers(this, _Configuration.PropertyConfiguration, aPropertySingletonDirectory, filesCollectionRootDirectory, filePathsCollection); _ProgressBar.Dispose(); - ReadOnlyCollection readOnlyContainers = new(containers); - SaveDistinctIds(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, readOnlyContainers); mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _Distance, personContainers, ticks, a2PeopleContentDirectory, a2PeopleSingletonDirectory, eDistanceContentDirectory); DeleteContinueFiles(personContainers); if (!runToDoCollectionFirst) MapFaceFileLogic(ticks, personContainers, mapLogic, a2PeopleContentDirectory, eDistanceContentDirectory, options); - FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, fPhotoPrismSingletonDirectory, t, readOnlyContainers, propertyLogic, mapLogic); + FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, fPhotoPrismSingletonDirectory, count, readOnlyContainers, propertyLogic, mapLogic); ReadOnlyCollection distinctValidImageItems = Shared.Models.Stateless.Methods.IContainer.GetValidImageItems(_Configuration.PropertyConfiguration, readOnlyContainers, distinctItems: true, filterItems: true); if (_Configuration.LookForAbandoned) { @@ -475,9 +472,11 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable } } - private bool GetRunToDoCollectionFirst(Property.Models.Configuration propertyConfiguration, long ticks) + private bool GetRunToDoCollectionFirst(Models.Configuration configuration, long ticks) { - bool result = !IId.IsOffsetDeterministicHashCode(propertyConfiguration); + bool result = configuration.SaveSortingWithoutPerson; + if (!result) + result = !IId.IsOffsetDeterministicHashCode(configuration.PropertyConfiguration); if (!result) { string[] directories; @@ -530,12 +529,12 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable return result; } - private string SaveUrlAndGetNewRootDirectory(string[] files) + private string SaveUrlAndGetNewRootDirectory(ReadOnlyCollection filePaths) { string result; - if (files.Length == 0) + if (filePaths.Count == 0) throw new NotSupportedException(); - string? sourceDirectory = Path.GetDirectoryName(files.First()); + string? sourceDirectory = filePaths[0].DirectoryName; if (string.IsNullOrEmpty(sourceDirectory)) throw new NotSupportedException(); Uri uri; @@ -576,7 +575,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable return result; } - private void FullDoWork(string argZero, string propertyRoot, long ticks, string aResultsFullGroupDirectory, string bResultsFullGroupDirectory, string fPhotoPrismSingletonDirectory, int t, ReadOnlyCollection readOnlyContainers, A_Property propertyLogic, MapLogic mapLogic) + private void FullDoWork(string argZero, string propertyRoot, long ticks, string aResultsFullGroupDirectory, string bResultsFullGroupDirectory, string fPhotoPrismSingletonDirectory, int count, ReadOnlyCollection readOnlyContainers, A_Property propertyLogic, MapLogic mapLogic) { int total; int notMapped; @@ -620,7 +619,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable sourceDirectoryChanges.Clear(); anyNullOrNoIsUniqueFileName = filteredItems.Any(l => !l.IsUniqueFileName); totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); - message = $"{i + 1:000} [{filteredItems.Count:000}] / {containersLength:000} - {total} / {t} total - {totalSeconds} total second(s) - {outputResolution} - <{container.SourceDirectory}> - total not mapped {totalNotMapped:000000}"; + message = $"{i + 1:000} [{filteredItems.Count:000}] / {containersLength:000} - {total} / {count} total - {totalSeconds} total second(s) - {outputResolution} - <{container.SourceDirectory}> - total not mapped {totalNotMapped:000000}"; propertyLogic.SetAngleBracketCollection(aResultsFullGroupDirectory, container.SourceDirectory, anyNullOrNoIsUniqueFileName); if (outputResolutionHasNumber) _Resize.SetAngleBracketCollection(cResultsFullGroupDirectory, container.SourceDirectory); @@ -657,14 +656,14 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable total += container.Items.Count; } totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); - message = $"### [###] / {containersLength:000} - {total} / {t} total - {totalSeconds} total second(s) - {outputResolution} - <> - total not mapped {totalNotMapped:000000}"; + message = $"### [###] / {containersLength:000} - {total} / {count} total - {totalSeconds} total second(s) - {outputResolution} - <> - total not mapped {totalNotMapped:000000}"; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; using ProgressBar progressBar = new(1, message, options); progressBar.Tick(); } } - private static void SaveDistinctIds(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, ReadOnlyCollection readOnlyContainers) + private static void SaveDistinctIds(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, ReadOnlyCollection> filePathsCollection) { string paddedId; List distinct = []; @@ -672,21 +671,19 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable string bMetadataCollectionDirectory = Path.Combine(bResultsFullGroupDirectory, propertyConfiguration.ResultCollection); if (!Directory.Exists(bMetadataCollectionDirectory)) _ = Directory.CreateDirectory(bMetadataCollectionDirectory); - foreach (Container container in readOnlyContainers) + foreach (ReadOnlyCollection filePaths in filePathsCollection) { - if (container.Items.Count == 0) + if (filePaths.Count == 0) continue; - foreach (Item item in container.Items) + foreach (FilePath filePath in filePaths) { - if (item.Property?.Id is null) + if (filePath.Id is null) continue; - if (item.Property.Id != item.FilePath.Id) - throw new NotSupportedException(); - if (distinct.Contains(item.Property.Id.Value)) + if (distinct.Contains(filePath.Id.Value)) continue; - distinct.Add(item.Property.Id.Value); - paddedId = IId.GetPaddedId(propertyConfiguration, item.Property.Id.Value, item.FilePath.HasIgnoreKeyword, item.FilePath.HasDateTimeOriginal, index: null); - identifiers.Add(new(item.Property.Id.Value, paddedId)); + distinct.Add(filePath.Id.Value); + paddedId = IId.GetPaddedId(propertyConfiguration, filePath.Id.Value, filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal, index: null); + identifiers.Add(new(filePath.Id.Value, paddedId)); } } string json = JsonSerializer.Serialize(identifiers.OrderBy(l => l.PaddedId).ToArray(), IdentifierCollectionSourceGenerationContext.Default.IdentifierArray); @@ -1158,6 +1155,23 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable _ = _BlurHasher.EncodeAndSave(item.FilePath, resizedFileHolder); } } + bool? shouldIgnore = property is null || property.Keywords is null ? null : _Configuration.PropertyConfiguration.IgnoreRulesKeyWords.Any(l => property.Keywords.Contains(l)); + if (shouldIgnore is not null) + { + if (shouldIgnore.Value) + { + FileInfo fileInfo = new(resizedFileHolder.FullName); + if (!fileInfo.Attributes.HasFlag(FileAttributes.Hidden)) + File.SetAttributes(resizedFileHolder.FullName, FileAttributes.Hidden); + } + if (resizedFileHolder.Exists && item.FilePath.HasIgnoreKeyword is not null && item.FilePath.HasIgnoreKeyword.Value != shouldIgnore.Value) + { + if (item.FilePath.DirectoryName.Contains("Results") && item.FilePath.DirectoryName.Contains("Resize")) + File.Delete(resizedFileHolder.FullName); + else + throw new NotSupportedException($"Rename File! <{item.FilePath.FileNameFirstSegment}>"); + } + } if (property is null || item.Property is null) throw new NullReferenceException(nameof(property)); item.SetResizedFileHolder(_Resize.FileNameExtension, resizedFileHolder); @@ -1187,7 +1201,12 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable } Dictionary outputResolutionToResize = _Resize.GetResizeKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, item.FilePath, subFileTuples, parseExceptions, item.Property, mappingFromItem); if (_Configuration.SaveResizedSubfiles) - _Resize.SaveResizedSubfile(_Configuration.PropertyConfiguration, outputResolution, cResultsFullGroupDirectory, subFileTuples, item, item.Property, mappingFromItem, outputResolutionToResize); + { + if (shouldIgnore is not null && item.FilePath.HasIgnoreKeyword is not null && item.FilePath.HasIgnoreKeyword.Value != shouldIgnore.Value) + faces = []; + else + _Resize.SaveResizedSubfile(_Configuration.PropertyConfiguration, outputResolution, cResultsFullGroupDirectory, subFileTuples, item, item.Property, mappingFromItem, outputResolutionToResize); + } if (!_Configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions.Contains(outputResolution)) faces = []; else if (!mappingFromItem.ResizedFileHolder.Exists && !File.Exists(mappingFromItem.ResizedFileHolder.FullName)) @@ -1400,41 +1419,41 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable } } - private static void CheckForAllWindowsLinks(ReadOnlyCollection filesCollection) + private static void CheckForAllWindowsLinks(ReadOnlyCollection> filePathsCollection) { string fileFullPath; WindowsShortcut windowsShortcut; - foreach (string[] files in filesCollection) + foreach (ReadOnlyCollection filePaths in filePathsCollection) { - if (files.Length == 0) + if (filePaths.Count == 0) continue; - if (files.All(l => l.EndsWith(".lnk"))) + if (filePaths.All(l => l.ExtensionLowered == ".lnk")) { - foreach (string file in files) + foreach (FilePath filePath in filePaths) { - windowsShortcut = WindowsShortcut.Load(file); + windowsShortcut = WindowsShortcut.Load(filePath.FullName); if (windowsShortcut.Path is null) { - File.Delete(file); + File.Delete(filePath.FullName); continue; } fileFullPath = windowsShortcut.Path; windowsShortcut.Dispose(); - File.WriteAllText(Path.ChangeExtension(file, ".url"), fileFullPath); - File.Delete(file); + File.WriteAllText(Path.ChangeExtension(filePath.FullName, ".url"), fileFullPath); + File.Delete(filePath.FullName); } throw new NotSupportedException("All are Windows *.lnk files!"); } } } - private static bool IsFilesCollectionCountIsOne(ReadOnlyCollection filesCollection) + private static bool IsFilesCollectionCountIsOne(ReadOnlyCollection> filePathsCollection) { bool result = true; int count = 0; - foreach (string[] files in filesCollection) + foreach (ReadOnlyCollection filePaths in filePathsCollection) { - if (files.Length == 0) + if (filePaths.Count == 0) continue; count += 1; if (count > 1) @@ -1444,22 +1463,22 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable } } if (result) - CheckForAllWindowsLinks(filesCollection); + CheckForAllWindowsLinks(filePathsCollection); return result; } - private (string, ReadOnlyCollection, bool) GetFilesCollectionThenCopyOrMove(long ticks, string fileSearchFilter, string directorySearchFilter, ProgressBarOptions options, string outputResolution) + private (string, ReadOnlyCollection>, bool) GetFilesCollectionThenCopyOrMove(long ticks, string fileSearchFilter, string directorySearchFilter, ProgressBarOptions options, string outputResolution) { ProgressBar progressBar; string filesCollectionRootDirectory = _Configuration.PropertyConfiguration.RootDirectory; (string cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution); IReadOnlyDictionary fileGroups = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, [_Configuration.PropertyConfiguration.ResultContent]); - ReadOnlyCollection filesCollection = IDirectory.GetFilesCollection(filesCollectionRootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage: false); - int count = filesCollection.Select(l => l.Length).Sum(); - bool filesCollectionCountIsOne = IsFilesCollectionCountIsOne(filesCollection); + ReadOnlyCollection> filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, filesCollectionRootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage: false); + int count = filePathsCollection.Select(l => l.Count).Sum(); + bool filesCollectionCountIsOne = IsFilesCollectionCountIsOne(filePathsCollection); string message = $") Selecting for ## pattern directory - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)"; progressBar = new(count, message, options); - (string[] distinctDirectories, List<(FilePath, string)> toDoCollection) = IDirectory.GetToDoCollection(_Configuration.PropertyConfiguration, filesCollection, fileGroups[_Configuration.PropertyConfiguration.ResultContent], () => progressBar.Tick()); + (string[] distinctDirectories, List<(FilePath, string)> toDoCollection) = IDirectory.GetToDoCollection(_Configuration.PropertyConfiguration, filePathsCollection, fileGroups[_Configuration.PropertyConfiguration.ResultContent], () => progressBar.Tick()); progressBar.Dispose(); foreach (string distinctDirectory in distinctDirectories) { @@ -1470,7 +1489,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable progressBar = new(count, message, options); _ = IDirectory.CopyOrMove(toDoCollection, move: false, moveBack: false, () => progressBar.Tick()); progressBar.Dispose(); - return (filesCollectionRootDirectory, new(filesCollection), filesCollectionCountIsOne); + return (filesCollectionRootDirectory, filePathsCollection, filesCollectionCountIsOne); } } \ No newline at end of file diff --git a/Map/Models/MapLogic.cs b/Map/Models/MapLogic.cs index 309d720..79c1676 100644 --- a/Map/Models/MapLogic.cs +++ b/Map/Models/MapLogic.cs @@ -829,18 +829,19 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic private string? GetDisplayDirectoryName(string? displayDirectoryName, LocationContainer locationContainer, ReadOnlyDictionary personKeyToPersonContainer) { string? result = displayDirectoryName; - if (personKeyToPersonContainer.Count == 0) - throw new NotImplementedException(nameof(GetPersonKeyToPersonContainer)); - ReadOnlyDictionary>? wholePercentagesToPersonContainers = GetWholePercentagesToPersonContainers(locationContainer.Id); - if (wholePercentagesToPersonContainers is not null) + if (personKeyToPersonContainer.Count != 0) { - foreach (KeyValuePair> keyValuePair in wholePercentagesToPersonContainers) + ReadOnlyDictionary>? wholePercentagesToPersonContainers = GetWholePercentagesToPersonContainers(locationContainer.Id); + if (wholePercentagesToPersonContainers is not null) { - if (keyValuePair.Key != locationContainer.WholePercentages) - continue; - if (keyValuePair.Value.Count != 1) - continue; - result = keyValuePair.Value[0].DisplayDirectoryName; + foreach (KeyValuePair> keyValuePair in wholePercentagesToPersonContainers) + { + if (keyValuePair.Key != locationContainer.WholePercentages) + continue; + if (keyValuePair.Value.Count != 1) + continue; + result = keyValuePair.Value[0].DisplayDirectoryName; + } } } return result; diff --git a/Map/Models/Stateless/MapLogic.cs b/Map/Models/Stateless/MapLogic.cs index 2280705..29495ab 100644 --- a/Map/Models/Stateless/MapLogic.cs +++ b/Map/Models/Stateless/MapLogic.cs @@ -325,7 +325,7 @@ internal abstract class MapLogic continue; } if (!personKeyFormattedToPersonContainer.TryGetValue(personKeyFormattedIdThenWholePercentages.PersonKeyFormatted, out personContainer)) - throw new Exception(); + continue; if (!results.TryGetValue(personKeyFormattedIdThenWholePercentages.Id, out idTo)) { results.Add(personKeyFormattedIdThenWholePercentages.Id, []); @@ -735,7 +735,7 @@ internal abstract class MapLogic personDisplayDirectoryName = personKeyFormattedIdThenWholePercentages.PersonDisplayDirectoryName is null ? configuration.MappingDefaultName : personKeyFormattedIdThenWholePercentages.PersonDisplayDirectoryName; matches = configuration.PersonCharacters.Where(l => personDisplayDirectoryName.Contains(l)).ToArray(); if (matches.Length == 0) - throw new NotSupportedException(); + continue; group = IPerson.GetHourGroup(personKeyFormattedIdThenWholePercentages.PersonDisplayDirectoryName, personBirthday.Value.Hour); (status, sex, first) = IPerson.GetPersonHour(personKeyFormattedIdThenWholePercentages.PersonDisplayDirectoryName, personBirthday.Value.Hour); personDirectory = new(matches.First(), group, status, sex, first); diff --git a/Shared/Models/Stateless/Methods/Container.cs b/Shared/Models/Stateless/Methods/Container.cs index a3508b5..8fd2294 100644 --- a/Shared/Models/Stateless/Methods/Container.cs +++ b/Shared/Models/Stateless/Methods/Container.cs @@ -29,22 +29,21 @@ internal abstract class Container return container.Items.Count == results.Count ? container.Items : new(results); } - internal static List GetFilePairs(IDlibDotNet? dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string extension, string aPropertySingletonDirectory, ReadOnlyCollection filesCollection) + private static List GetFilePairs(Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string extension, string aPropertySingletonDirectory, ReadOnlyCollection> filePathsCollection) { int renamed; const bool useCeilingAverage = true; List? filePairs = null; ReadOnlyCollection? jsonFilesCollection = null; IReadOnlyDictionary>? compareFileNamesToFiles = null; - IReadOnlyDictionary> fileNamesToFiles = XDirectory.GetFilesKeyValuePairs(filesCollection); + IReadOnlyDictionary> fileNamesToFiles = XDirectory.GetFilesKeyValuePairs(filePathsCollection); for (int i = 0; i < short.MaxValue; i++) { renamed = 0; - dlibDotNet?.Tick(); jsonFilesCollection = IDirectory.GetFilesCollection(aPropertySingletonDirectory, directorySearchFilter, extension, useCeilingAverage); compareFileNamesToFiles = XDirectory.GetFilesKeyValuePairs(jsonFilesCollection); renamed += XDirectory.LookForAbandoned(jsonFilesCollection, fileNamesToFiles, extension); - filePairs = XDirectory.GetFiles(propertyConfiguration, filesCollection, fileNamesToFiles, extension, compareFileNamesToFiles); + filePairs = XDirectory.GetFiles(propertyConfiguration, filePathsCollection, fileNamesToFiles, extension, compareFileNamesToFiles); renamed += XDirectory.MaybeMove(propertyConfiguration, filePairs, aPropertySingletonDirectory, extension); if (renamed == 0) break; @@ -72,8 +71,9 @@ internal abstract class Container return result; } - private static void ParallelFor(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string extension, int rootDirectoryLength, Models.FilePair filePair, List results) + private static void ParallelFor(IDlibDotNet? dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string extension, int rootDirectoryLength, Models.FilePair filePair, List results) { + dlibDotNet?.Tick(); bool abandoned = false; Models.FileHolder sourceDirectoryFileHolder; Models.Property? property = GetProperty(filePair); @@ -81,16 +81,16 @@ internal abstract class Container FilePath filePath = FilePath.Get(propertyConfiguration, imageFileHolder, index: null); bool? fileSizeChanged = property is not null ? property.FileSize != filePath.Length : null; bool isValidImageFormatExtension = propertyConfiguration.ValidImageFormatExtensions.Contains(filePath.ExtensionLowered); - if (property is not null && property.Keywords is not null) + bool? shouldIgnore = property is null || property.Keywords is null ? null : propertyConfiguration.IgnoreRulesKeyWords.Any(l => property.Keywords.Contains(l)); + if (shouldIgnore is not null) { - bool shouldIgnore = propertyConfiguration.IgnoreRulesKeyWords.Any(l => property.Keywords.Contains(l)); - if (shouldIgnore) + if (shouldIgnore.Value) { FileInfo fileInfo = new(filePath.FullName); if (!fileInfo.Attributes.HasFlag(FileAttributes.Hidden)) File.SetAttributes(imageFileHolder.FullName, FileAttributes.Hidden); } - if (filePath.HasIgnoreKeyword is not null && filePath.HasIgnoreKeyword.Value != shouldIgnore) + if (filePath.HasIgnoreKeyword is not null && filePath.HasIgnoreKeyword.Value != shouldIgnore.Value) { if (filePath.DirectoryName.Contains("Results") && filePath.DirectoryName.Contains("Resize")) File.Delete(filePath.FullName); @@ -120,31 +120,31 @@ internal abstract class Container results.Add(new(filePair.IsUnique, filePair.Collection, filePath, item)); } - private static List GetFilePairs(IDlibDotNet? dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection filesCollection, string directorySearchFilter) + private static List GetFilePairs(IDlibDotNet? dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection> filePathsCollection, string directorySearchFilter) { List results = []; const string extension = ".json"; int maxDegreeOfParallelism = Environment.ProcessorCount; int filesCollectionDirectoryLength = filesCollectionDirectory.Length; ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism }; - List filePairs = GetFilePairs(dlibDotNet, propertyConfiguration, directorySearchFilter, extension, aPropertySingletonDirectory, filesCollection); - _ = Parallel.For(0, filePairs.Count, parallelOptions, (i, state) => ParallelFor(propertyConfiguration, aPropertySingletonDirectory, extension, filesCollectionDirectoryLength, filePairs[i], results)); + List filePairs = GetFilePairs(propertyConfiguration, directorySearchFilter, extension, aPropertySingletonDirectory, filePathsCollection); + _ = Parallel.For(0, filePairs.Count, parallelOptions, (i, state) => ParallelFor(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, extension, filesCollectionDirectoryLength, filePairs[i], results)); return results; } - private static (int, Models.Container[]) GetContainers(IDlibDotNet? dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection filesCollection, string directorySearchFilter) + private static (int, Models.Container[]) GetContainers(IDlibDotNet? dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection> filePathsCollection, string directorySearchFilter) { List results = []; - string? directory; + string directory; List? items; Models.Container container; List directories = []; Dictionary> directoryToItems = []; - foreach (string[] files in filesCollection) + foreach (ReadOnlyCollection filePaths in filePathsCollection) { - if (files.Length == 0) + if (filePaths.Count == 0) continue; - directory = Path.GetDirectoryName(files.First()); + directory = filePaths[0].DirectoryName; if (directory is null) continue; if (!directories.Contains(directory)) @@ -156,7 +156,7 @@ internal abstract class Container throw new Exception(); } } - List filePairs = GetFilePairs(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, filesCollection, directorySearchFilter); + List filePairs = GetFilePairs(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, filePathsCollection, directorySearchFilter); foreach (FilePair filePair in filePairs) { if (!directoryToItems.TryGetValue(filePair.FilePath.DirectoryName, out items)) @@ -177,13 +177,12 @@ internal abstract class Container return (filePairs.Count, results.ToArray()); } - internal static (int, Models.Container[]) GetContainers(IDlibDotNet dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection filesCollection) + internal static ReadOnlyCollection GetContainers(IDlibDotNet dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection> filePathsCollection) { - int count; Models.Container[] results; const string directorySearchFilter = "*"; - (count, results) = GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, filesCollection, directorySearchFilter); - return (count, results); + (_, results) = GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, filePathsCollection, directorySearchFilter); + return new(results); } internal static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory) @@ -195,7 +194,8 @@ internal abstract class Container const string fileSearchFilter = "*"; const string directorySearchFilter = "*"; ReadOnlyCollection filesCollection = IDirectory.GetFilesCollection(propertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage); - (count, results) = GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, propertyConfiguration.RootDirectory, filesCollection, directorySearchFilter); + ReadOnlyCollection> filePathsCollection = IDirectory.GetFilePathCollections(propertyConfiguration, filesCollection); + (count, results) = GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, propertyConfiguration.RootDirectory, filePathsCollection, directorySearchFilter); return (count, results); } diff --git a/Shared/Models/Stateless/Methods/IContainer.cs b/Shared/Models/Stateless/Methods/IContainer.cs index a8fa000..f727e3c 100644 --- a/Shared/Models/Stateless/Methods/IContainer.cs +++ b/Shared/Models/Stateless/Methods/IContainer.cs @@ -20,10 +20,10 @@ public interface IContainer static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory) => Container.GetContainers(propertyConfiguration, aPropertySingletonDirectory); - (int, Models.Container[]) TestStatic_GetContainers(IDlibDotNet dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection filesCollection) => - GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, filesCollection); - static (int, Models.Container[]) GetContainers(IDlibDotNet dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection filesCollection) => - Container.GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, filesCollection); + ReadOnlyCollection TestStatic_GetContainers(IDlibDotNet dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection> filePathsCollection) => + GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, filePathsCollection); + static ReadOnlyCollection GetContainers(IDlibDotNet dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection> filePathsCollection) => + Container.GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, filePathsCollection); List TestStatic_GetFilteredDistinctIds(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection readOnlyContainers) => GetFilteredDistinctIds(propertyConfiguration, readOnlyContainers); diff --git a/Shared/Models/Stateless/Methods/IDirectory.cs b/Shared/Models/Stateless/Methods/IDirectory.cs index a4934ab..77d3ff2 100644 --- a/Shared/Models/Stateless/Methods/IDirectory.cs +++ b/Shared/Models/Stateless/Methods/IDirectory.cs @@ -20,24 +20,34 @@ public interface IDirectory static ReadOnlyCollection GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter, bool useCeilingAverage) => XDirectory.GetFilesCollection(directory, directorySearchFilter, fileSearchFilter, useCeilingAverage); + ReadOnlyCollection> TestStatic_GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, string directory, string directorySearchFilter, string fileSearchFilter, bool useCeilingAverage) => + GetFilePathCollections(propertyConfiguration, directory, directorySearchFilter, fileSearchFilter, useCeilingAverage); + static ReadOnlyCollection> GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, string directory, string directorySearchFilter, string fileSearchFilter, bool useCeilingAverage) => + XDirectory.GetFilePathCollections(propertyConfiguration, directory, directorySearchFilter, fileSearchFilter, useCeilingAverage); + void TestStatic_MoveFiles(List files, string find, string replace) => MoveFiles(files, find, replace); static void MoveFiles(List files, string find, string replace) => XDirectory.MoveFiles(files, find, replace); - (string[], List<(FilePath, string)>) TestStatic_GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection filesCollection, string[] directories, Action? tick) => - GetToDoCollection(propertyConfiguration, filesCollection, directories, tick); - static (string[], List<(FilePath, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection filesCollection, string[] directories, Action? tick) => - XDirectory.GetToDoCollection(propertyConfiguration, copyDuplicates: false, ifCanUseId: true, filesCollection, directories, tick); + (string[], List<(FilePath, string)>) TestStatic_GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection> filePathsCollection, string[] directories, Action? tick) => + GetToDoCollection(propertyConfiguration, filePathsCollection, directories, tick); + static (string[], List<(FilePath, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection> filePathsCollection, string[] directories, Action? tick) => + XDirectory.GetToDoCollection(propertyConfiguration, copyDuplicates: false, ifCanUseId: true, filePathsCollection, directories, tick); - (string[], List<(FilePath, string)>) TestStatic_GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection filesCollection, string[] directories, Action? tick) => - GetToDoCollection(propertyConfiguration, copyDuplicates, ifCanUseId, filesCollection, directories, tick); - static (string[], List<(FilePath, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection filesCollection, string[] directories, Action? tick) => - XDirectory.GetToDoCollection(propertyConfiguration, copyDuplicates, ifCanUseId, filesCollection, directories, tick); + (string[], List<(FilePath, string)>) TestStatic_GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection> filePathsCollection, string[] directories, Action? tick) => + GetToDoCollection(propertyConfiguration, copyDuplicates, ifCanUseId, filePathsCollection, directories, tick); + static (string[], List<(FilePath, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection> filePathsCollection, string[] directories, Action? tick) => + XDirectory.GetToDoCollection(propertyConfiguration, copyDuplicates, ifCanUseId, filePathsCollection, directories, tick); List TestStatic_CopyOrMove(List<(FilePath, string)> toDoCollection, bool move, bool moveBack, Action? tick) => CopyOrMove(toDoCollection, move, moveBack, tick); static List CopyOrMove(List<(FilePath, string)> toDoCollection, bool move, bool moveBack, Action? tick) => XDirectory.CopyOrMove(toDoCollection, move, moveBack, tick); + ReadOnlyCollection> TestStatic_GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection filesCollection) => + GetFilePathCollections(propertyConfiguration, filesCollection); + static ReadOnlyCollection> GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection filesCollection) => + XDirectory.GetFilePathCollections(propertyConfiguration, filesCollection); + } \ No newline at end of file diff --git a/Shared/Models/Stateless/Methods/XDirectory.cs b/Shared/Models/Stateless/Methods/XDirectory.cs index 0b3f49a..90b8901 100644 --- a/Shared/Models/Stateless/Methods/XDirectory.cs +++ b/Shared/Models/Stateless/Methods/XDirectory.cs @@ -54,6 +54,14 @@ internal abstract partial class XDirectory return new(results); } + internal static ReadOnlyCollection> GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, string directory, string directorySearchFilter, string fileSearchFilter, bool useCeilingAverage) + { + ReadOnlyCollection> results; + ReadOnlyCollection filesCollection = GetFilesCollection(directory, directorySearchFilter, fileSearchFilter, useCeilingAverage); + results = IDirectory.GetFilePathCollections(propertyConfiguration, filesCollection); + return results; + } + internal static IReadOnlyDictionary> GetFilesKeyValuePairs(ReadOnlyCollection filesCollection) { Dictionary> results = []; @@ -76,6 +84,26 @@ internal abstract partial class XDirectory return results; } + internal static IReadOnlyDictionary> GetFilesKeyValuePairs(ReadOnlyCollection> filePathsCollection) + { + Dictionary> results = []; + List? collection; + foreach (ReadOnlyCollection filePaths in filePathsCollection) + { + foreach (FilePath filePath in filePaths) + { + if (!results.TryGetValue(filePath.Name, out collection)) + { + results.Add(filePath.Name, []); + if (!results.TryGetValue(filePath.Name, out collection)) + throw new Exception(); + } + collection.Add(filePath.FullName); + } + } + return results; + } + internal static int LookForAbandoned(ReadOnlyCollection jsonFilesCollection, IReadOnlyDictionary> fileNamesToFiles, string extension) { string fileName; @@ -147,41 +175,37 @@ internal abstract partial class XDirectory return result; } - internal static List GetFiles(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection filesCollection, IReadOnlyDictionary> fileNamesToFiles, string extension, IReadOnlyDictionary> compareFileNamesToFiles) + internal static List GetFiles(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection> filePathsCollection, IReadOnlyDictionary> fileNamesToFiles, string extension, IReadOnlyDictionary> compareFileNamesToFiles) { List results = []; string? match; - string fileName; bool uniqueFileName; - string fileExtension; List? collection; bool? isNotUniqueAndNeedsReview; - foreach (string[] files in filesCollection) + foreach (ReadOnlyCollection filePaths in filePathsCollection) { - foreach (string file in files) + foreach (FilePath filePath in filePaths) { isNotUniqueAndNeedsReview = null; - fileName = Path.GetFileName(file); - fileExtension = Path.GetExtension(file); - if (propertyConfiguration.IgnoreExtensions.Contains(fileExtension)) + if (propertyConfiguration.IgnoreExtensions.Contains(filePath.ExtensionLowered)) continue; - if (!fileNamesToFiles.TryGetValue(fileName, out collection)) + if (!fileNamesToFiles.TryGetValue(filePath.Name, out collection)) throw new Exception(); uniqueFileName = collection.Count == 1; if (!uniqueFileName) - isNotUniqueAndNeedsReview = GetIsNotUniqueAndNeedsReview(file, collection); - if (!compareFileNamesToFiles.TryGetValue(string.Concat(fileName, extension), out collection)) - results.Add(new(file, uniqueFileName, isNotUniqueAndNeedsReview, [], null)); + isNotUniqueAndNeedsReview = GetIsNotUniqueAndNeedsReview(filePath.FullName, collection); + if (!compareFileNamesToFiles.TryGetValue(string.Concat(filePath.Name, extension), out collection)) + results.Add(new(filePath.FullName, uniqueFileName, isNotUniqueAndNeedsReview, [], null)); else { if (collection.Count == 0) - results.Add(new(file, uniqueFileName, isNotUniqueAndNeedsReview, collection, null)); + results.Add(new(filePath.FullName, uniqueFileName, isNotUniqueAndNeedsReview, collection, null)); else if (uniqueFileName && collection.Count == 1) - results.Add(new(file, uniqueFileName, isNotUniqueAndNeedsReview, collection, collection.First())); + results.Add(new(filePath.FullName, uniqueFileName, isNotUniqueAndNeedsReview, collection, collection.First())); else { - match = GetMatch(file, collection); - results.Add(new(file, uniqueFileName, isNotUniqueAndNeedsReview, collection, match)); + match = GetMatch(filePath.FullName, collection); + results.Add(new(filePath.FullName, uniqueFileName, isNotUniqueAndNeedsReview, collection, match)); } } } @@ -272,24 +296,38 @@ internal abstract partial class XDirectory } } - private static FilePath[] GetSortedRecords(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection filesCollection) + private static FilePath[] GetSortedRecords(ReadOnlyCollection> filePathsCollection) { List results = []; - FilePath filePath; - Models.FileHolder fileHolder; - foreach (string[] files in filesCollection) + foreach (ReadOnlyCollection filePaths in filePathsCollection) { - foreach (string file in files) - { - fileHolder = IFileHolder.Get(file); - filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null); + foreach (FilePath filePath in filePaths) results.Add(filePath); - } } return (from l in results orderby l.CreationTicks, l.FullName.Length descending select l).ToArray(); } - internal static (string[], List<(FilePath, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection filesCollection, string[] directories, Action? tick) + internal static ReadOnlyCollection> GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyCollection filesCollection) + { + List> results = []; + FilePath filePath; + List filePaths; + Models.FileHolder fileHolder; + foreach (string[] files in filesCollection) + { + filePaths = []; + foreach (string file in files) + { + fileHolder = IFileHolder.Get(file); + filePath = FilePath.Get(propertyConfiguration, fileHolder, index: null); + filePaths.Add(filePath); + } + results.Add(new(filePaths)); + } + return new(results); + } + + internal static (string[], List<(FilePath, string)>) GetToDoCollection(Properties.IPropertyConfiguration propertyConfiguration, bool copyDuplicates, bool ifCanUseId, ReadOnlyCollection> filePathsCollection, string[] directories, Action? tick) { List<(FilePath, string)> results = []; string paddedId; @@ -307,7 +345,7 @@ internal abstract partial class XDirectory List distinct = []; Models.FileHolder fileHolder; List distinctDirectories = []; - FilePath[] sortedRecords = GetSortedRecords(propertyConfiguration, filesCollection); + FilePath[] sortedRecords = GetSortedRecords(filePathsCollection); bool isOffsetDeterministicHashCode = IId.IsOffsetDeterministicHashCode(propertyConfiguration); for (int i = 0; i < sortedRecords.Length; i++) { diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index fef1ee7..b41db13 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -33,8 +33,8 @@ - - + + diff --git a/TestsWithFaceRecognitionDotNet/TestsWithFaceRecognitionDotNet.csproj b/TestsWithFaceRecognitionDotNet/TestsWithFaceRecognitionDotNet.csproj index 1b656f4..b6ddb75 100644 --- a/TestsWithFaceRecognitionDotNet/TestsWithFaceRecognitionDotNet.csproj +++ b/TestsWithFaceRecognitionDotNet/TestsWithFaceRecognitionDotNet.csproj @@ -32,8 +32,8 @@ - - + +