diff --git a/.vscode/launch.json b/.vscode/launch.json index bbf2db0..1dcf421 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,7 +10,7 @@ "name": "Compare", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "buildSolution", "program": "${workspaceFolder}/Compare/bin/Debug/net9.0/win-x64/Compare.dll", "args": [ "s" @@ -27,7 +27,7 @@ "name": "Copy-Distinct", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "buildSolution", "program": "${workspaceFolder}/Copy-Distinct/bin/Debug/net9.0/win-x64/Copy-Distinct.dll", "args": [], "env": { @@ -42,7 +42,7 @@ "name": "Duplicate-Search", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "buildSolution", "program": "${workspaceFolder}/Duplicate-Search/bin/Debug/net9.0/win-x64/Duplicate-Search.dll", "args": [ "s" @@ -59,7 +59,7 @@ "name": "Date-Group", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "buildSolution", "program": "${workspaceFolder}/Date-Group/bin/Debug/net9.0/win-x64/Date-Group.dll", "args": [ "s" @@ -76,7 +76,7 @@ "name": "Delete-By-Distinct", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "buildSolution", "program": "${workspaceFolder}/Delete-By-Distinct/bin/Debug/net9.0/win-x64/Delete-By-Distinct.dll", "args": [ "s" @@ -93,7 +93,7 @@ "name": "Delete-By-Relative", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "buildSolution", "program": "${workspaceFolder}/Delete-By-Relative/bin/Debug/net9.0/win-x64/Delete-By-Relative.dll", "args": [ "s" @@ -110,7 +110,7 @@ "name": "Drag-Drop", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "buildSolution", "program": "${workspaceFolder}/Drag-Drop/bin/Debug/net9.0-windows/win-x64/Drag-Drop.dll", "args": [ "s" @@ -127,7 +127,7 @@ "name": "Drag-Drop-Explorer", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "buildSolution", "program": "${workspaceFolder}/Drag-Drop-Explorer/bin/Debug/net9.0-windows/win-x64/Drag-Drop-Explorer.dll", "args": [ "s" @@ -144,7 +144,7 @@ "name": "Drag-Drop-Move", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "buildSolution", "program": "${workspaceFolder}/Drag-Drop-Move/bin/Debug/net9.0-windows/win-x64/Drag-Drop-Move.dll", "args": [ "s" @@ -161,7 +161,7 @@ "name": "Drag-Drop-Set-Property-Item", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "buildSolution", "program": "${workspaceFolder}/Drag-Drop-Set-Property-Item/bin/Debug/net9.0-windows/win-x64/Drag-Drop-Set-Property-Item.dll", "args": [ "s" @@ -178,7 +178,7 @@ "name": "Instance", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "buildInstance", "program": "${workspaceFolder}/Instance/bin/Debug/net9.0/win-x64/Instance.dll", "args": [ "s" @@ -195,7 +195,7 @@ "name": "Mirror-Length", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "buildSolution", "program": "${workspaceFolder}/Mirror-Length/bin/Debug/net9.0/win-x64/Mirror-Length.dll", "args": [], "env": { @@ -210,7 +210,7 @@ "name": "Metadata-Query", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "buildSolution", "program": "${workspaceFolder}/Metadata-Query/bin/Debug/net9.0/win-x64/Metadata-Query.dll", "args": [ "s" @@ -227,7 +227,7 @@ "name": "Move-By-Id", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "buildSolution", "program": "${workspaceFolder}/Move-By-Id/bin/Debug/net9.0/win-x64/Move-By-Id.dll", "args": [ "s" @@ -244,7 +244,7 @@ "name": "Not-Copy-Copy", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "buildSolution", "program": "${workspaceFolder}/Not-Copy-Copy/bin/Debug/net9.0/win-x64/Not-Copy-Copy.dll", "args": [ "s" @@ -261,7 +261,7 @@ "name": "Offset-Date-Time-Original", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "buildSolution", "program": "${workspaceFolder}/Offset-Date-Time-Original/bin/Debug/net9.0/win-x64/Offset-Date-Time-Original.dll", "args": [ "s" @@ -278,7 +278,7 @@ "name": "PrepareForOld", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "buildSolution", "program": "${workspaceFolder}/PrepareForOld/bin/Debug/net9.0/win-x64/PrepareForOld.dll", "args": [ "s" @@ -295,7 +295,7 @@ "name": "Person", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "buildSolution", "program": "${workspaceFolder}/Person/bin/Debug/net9.0/Person.dll", "args": [ "s" @@ -312,7 +312,7 @@ "name": "Rename", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "buildSolution", "program": "${workspaceFolder}/Rename/bin/Debug/net9.0/win-x64/Rename.dll", "args": [ "s" @@ -329,7 +329,7 @@ "name": "Set-Created-Date", "type": "coreclr", "request": "launch", - "preLaunchTask": "build", + "preLaunchTask": "buildSolution", "program": "${workspaceFolder}/Set-Created-Date/bin/Debug/net9.0/win-x64/Set-Created-Date.dll", "args": [ "s" diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 501194d..ad3cef8 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -53,7 +53,7 @@ "problemMatcher": "$msCompile" }, { - "label": "build", + "label": "buildSolution", "command": "dotnet", "type": "process", "args": [ @@ -63,6 +63,22 @@ "/consoleloggerparameters:NoSummary" ], "problemMatcher": "$msCompile" + }, + { + "label": "buildInstance", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/Instance/Instance.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary", + "/property:WarningLevel=0", + "--verbosity", + "quiet", + "--no-restore" + ], + "problemMatcher": "$msCompile" } ] } \ No newline at end of file diff --git a/Duplicate-Search/DuplicateSearch.cs b/Duplicate-Search/DuplicateSearch.cs index 5fa649d..2ac2c2f 100644 --- a/Duplicate-Search/DuplicateSearch.cs +++ b/Duplicate-Search/DuplicateSearch.cs @@ -189,7 +189,7 @@ public class DuplicateSearch if (mappingFromItem is not null) { resizedFileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(mappingFromItem.ResizedFileHolder.FullName.Replace($"0{duplicates}", $"1{duplicates}")); - collection[0] = new(mappingFromItem.ContainerDateTimes, item.Property.DateTimeDigitized, item.Property.DateTimeOriginal, mappingFromItem.Id, mappingFromItem.FilePath, mappingFromItem.IsWrongYear, item.Property.Keywords ?? [], mappingFromItem.MinimumDateTime, item.Property.Model, mappingFromItem.RelativePath, resizedFileHolder); + collection[0] = new(mappingFromItem.ContainerDateTimes, item.Property.DateTimeDigitized, item.Property.DateTimeOriginal, mappingFromItem.Id, mappingFromItem.IsArchive, mappingFromItem.FilePath, mappingFromItem.IsWrongYear, item.Property.Keywords ?? [], mappingFromItem.MinimumDateTime, item.Property.Model, mappingFromItem.RelativePath, resizedFileHolder); } } resizedFileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(string.Concat(Path.Combine(destinationRoot, directory), item.RelativePath)); diff --git a/Instance/DlibDotNet.cs b/Instance/DlibDotNet.cs index 82488a7..c9f6e29 100644 --- a/Instance/DlibDotNet.cs +++ b/Instance/DlibDotNet.cs @@ -254,31 +254,6 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable throw new Exception("Configuration has SaveSortingWithoutPerson and FocusDirectory!"); } - private ReadOnlyCollection GetNotNineCollection(ReadOnlyCollection> filePathsCollection) - { - List results = []; - FileInfo fileInfo; - FileHolder fileHolder; - FilePath checkFilePath; - foreach (ReadOnlyCollection filePaths in filePathsCollection) - { - foreach (FilePath filePath in filePaths) - { - if (!filePath.FullName.Contains(" !9")) - continue; - fileInfo = new(filePath.FullName); - fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(fileInfo); - if (!fileInfo.Attributes.HasFlag(FileAttributes.Hidden)) - File.SetAttributes(fileHolder.FullName, FileAttributes.Hidden); - checkFilePath = FilePath.Get(_Configuration.PropertyConfiguration, fileHolder, index: null); - if (checkFilePath.Id is null) - continue; - results.Add(checkFilePath.Id.Value); - } - } - return new(results); - } - private static void DeleteContinueFiles(ReadOnlyCollection personContainers) { foreach (PersonContainer personContainer in personContainers) @@ -337,9 +312,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable const string directorySearchFilter = "*"; string? filesCollectionRootDirectory = null; bool configurationOutputResolutionsHas = false; - ReadOnlyCollection readOnlyContainers; - ReadOnlyCollection? notNineCollection = null; ReadOnlyDictionary> personKeyToIds; + ReadOnlyDictionary? splatNineIdentifiers = null; ReadOnlyCollection>? filePathsCollection = null; bool runToDoCollectionFirst = GetRunToDoCollectionFirst(_Configuration, ticks); (aResultsFullGroupDirectory, bResultsFullGroupDirectory) = GetResultsFullGroupDirectories(); @@ -361,8 +335,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable if (!runToDoCollectionFirst) break; (filesCollectionRootDirectory, filePathsCollection, filesCollectionCountIsOne) = GetFilesCollectionThenCopyOrMove(ticks, fileSearchFilter, directorySearchFilter, options, outputResolution); - SaveDistinctIds(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, filePathsCollection); - notNineCollection = GetNotNineCollection(filePathsCollection); + splatNineIdentifiers = GetSplatNineIdentifiersAndHideSplatNine(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, filePathsCollection); break; } fPhotoPrismContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(F_PhotoPrism), _Configuration.PropertyConfiguration.ResultContent); @@ -396,7 +369,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable continue; (cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution); filesCollectionRootDirectory = Path.Combine(cResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent); - filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, filesCollectionRootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage: true); + filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, directorySearchFilter, fileSearchFilter, filesCollectionRootDirectory, useCeilingAverage: true); break; } } @@ -408,7 +381,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable int count = filePathsCollection.Select(l => l.Count).Sum(); 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); + ReadOnlyCollection readOnlyContainers = Shared.Models.Stateless.Methods.IContainer.GetContainers(this, _Configuration.PropertyConfiguration, aPropertySingletonDirectory, filesCollectionRootDirectory, splatNineIdentifiers, filePathsCollection); _ProgressBar.Dispose(); mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _Distance, personContainers, ticks, a2PeopleContentDirectory, a2PeopleSingletonDirectory, eDistanceContentDirectory); DeleteContinueFiles(personContainers); @@ -455,8 +428,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable && _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution) && _Exceptions.Count == 0) MapLogic(ticks, readOnlyContainers, fPhotoPrismContentDirectory, mapLogic, outputResolution, new(personKeyToIds), distinctValidImageFaces, distinctValidImageMappingCollection); - if (runToDoCollectionFirst && _Configuration.SaveRandomForOutputResolutions.Contains(outputResolution) && personKeyToIds.Count > 0 && distinctValidImageMappingCollection.Count > 0) - _Random.Random(_Configuration.PropertyConfiguration, _Configuration.ImmichAssetsFile, _Configuration.RadomUseBirthdayMinimum, _Configuration.ValidKeyWordsToIgnoreInRandom, personKeyToIds, notNineCollection, distinctValidImageMappingCollection); + if (runToDoCollectionFirst && _Configuration.SaveRandomForOutputResolutions.Contains(outputResolution) && personKeyToIds.Count > 0 && splatNineIdentifiers is not null && distinctValidImageMappingCollection.Count > 0) + _Random.Random(_Configuration.PropertyConfiguration, _Configuration.ImmichAssetsFile, _Configuration.ImmichOwnerId, _Configuration.ImmichRoot, _Configuration.RadomUseBirthdayMinimum, _Configuration.ValidKeyWordsToIgnoreInRandom, personKeyToIds, splatNineIdentifiers, distinctValidImageMappingCollection); if (_IsEnvironment.Development) continue; if (!_IsEnvironment.Development) @@ -569,7 +542,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable isValidImageFormatExtension = _Configuration.PropertyConfiguration.ValidImageFormatExtensions.Contains(extensionLowered); fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(sourceDirectoryFile); filePath = FilePath.Get(_Configuration.PropertyConfiguration, fileHolder, index: null); - _ = new Item(filePath, fileHolder, relativePath, isValidImageFormatExtension); + _ = Item.Get(filePath, fileHolder, relativePath, isValidImageFormatExtension); // container.Items.Add(item); } _Logger?.LogInformation(". . ."); @@ -663,10 +636,11 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable } } - private static ReadOnlyDictionary> GetKeyValuePairs(ReadOnlyCollection> filePathsCollection) + private static ReadOnlyDictionary> GetKeyValuePairs(ReadOnlyCollection> filePathsCollection) { - Dictionary> results = []; + Dictionary> results = []; List? collection; + Dictionary> keyValuePairs = []; foreach (ReadOnlyCollection filePaths in filePathsCollection) { if (filePaths.Count == 0) @@ -675,45 +649,69 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable { if (filePath.Id is null) continue; - if (!results.TryGetValue(filePath.Id.Value, out collection)) + if (!keyValuePairs.TryGetValue(filePath.Id.Value, out collection)) { - results.Add(filePath.Id.Value, []); - if (!results.TryGetValue(filePath.Id.Value, out collection)) + keyValuePairs.Add(filePath.Id.Value, []); + if (!keyValuePairs.TryGetValue(filePath.Id.Value, out collection)) throw new Exception(); } collection.Add(filePath); } } + foreach (KeyValuePair> keyValuePair in keyValuePairs) + results.Add(keyValuePair.Key, new(keyValuePair.Value)); return new(results); } - private static void SaveDistinctIds(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, ReadOnlyCollection> filePathsCollection) + private static ReadOnlyDictionary GetSplatNineIdentifiersAndHideSplatNine(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, ReadOnlyCollection> filePathsCollection) { - ReadOnlyDictionary> keyValuePairs = GetKeyValuePairs(filePathsCollection); + Dictionary results = []; + ReadOnlyDictionary> keyValuePairs = GetKeyValuePairs(filePathsCollection); if (keyValuePairs.Count > 0) { + string json; string paddedId; + FileInfo fileInfo; FilePath filePath; + FileHolder fileHolder; Identifier identifier; string[] directoryNames; + List distinct = []; List identifiers = []; string rootDirectory = propertyConfiguration.RootDirectory.Replace('\\', '/'); string bMetadataCollectionDirectory = Path.Combine(bResultsFullGroupDirectory, propertyConfiguration.ResultCollection); if (!Directory.Exists(bMetadataCollectionDirectory)) _ = Directory.CreateDirectory(bMetadataCollectionDirectory); - foreach (KeyValuePair> keyValuePair in keyValuePairs) + foreach (KeyValuePair> keyValuePair in keyValuePairs) { - filePath = keyValuePair.Value[0]; - if (filePath.Id is null) - continue; - directoryNames = keyValuePair.Value.Select(l => l.DirectoryFullPath.Replace('\\', '/')).ToArray(); - paddedId = IId.GetPaddedId(propertyConfiguration, filePath.Id.Value, filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal, index: null); - identifier = new(directoryNames, filePath.HasDateTimeOriginal, filePath.Id.Value, filePath.Length, paddedId, filePath.LastWriteTicks); - identifiers.Add(identifier); + for (int i = 0; i < keyValuePair.Value.Count; i++) + { + filePath = keyValuePair.Value[0]; + if (filePath.Id is null) + continue; + directoryNames = keyValuePair.Value.Select(l => l.DirectoryFullPath.Replace('\\', '/')).ToArray(); + paddedId = IId.GetPaddedId(propertyConfiguration, filePath.Id.Value, filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal, index: null); + identifier = new(directoryNames, filePath.ExtensionLowered, filePath.HasDateTimeOriginal, filePath.Id.Value, filePath.Length, paddedId, filePath.LastWriteTicks); + if (i == 0) + identifiers.Add(identifier); + if (!filePath.FullName.Contains(" !9")) + continue; + fileInfo = new(filePath.FullName); + fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(fileInfo); + if (!fileInfo.Attributes.HasFlag(FileAttributes.Hidden)) + File.SetAttributes(fileHolder.FullName, FileAttributes.Hidden); + if (distinct.Contains(keyValuePair.Key)) + continue; + distinct.Add(keyValuePair.Key); + results.Add(keyValuePair.Key, identifier); + } } - string json = JsonSerializer.Serialize((from l in identifiers orderby l.DirectoryNames.Length descending, l.Id select l).ToArray(), IdentifierCollectionSourceGenerationContext.Default.IdentifierArray); + json = JsonSerializer.Serialize(results.Values.ToArray(), IdentifierCollectionSourceGenerationContext.Default.IdentifierArray); + _ = Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(bMetadataCollectionDirectory, "!9.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null); + json = JsonSerializer.Serialize((from l in identifiers orderby l.DirectoryNames.Length descending, l.Id select l).ToArray(), IdentifierCollectionSourceGenerationContext.Default.IdentifierArray); _ = Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(bMetadataCollectionDirectory, ".json"), json.Replace(rootDirectory, string.Empty), updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null); } + return new(results); } private ReadOnlyCollection GetMappings(Property.Models.Configuration propertyConfiguration, string eDistanceContentDirectory, ReadOnlyCollection readOnlyContainers, MapLogic mapLogic, bool distinctItems) @@ -1053,7 +1051,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation); mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson); } - mapping = new(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection); + mapping = Mapping.Get(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection); notMapped += mapLogic.UpdateMappingFromPerson(wholePercentagesToPersonContainers, mapping); face.SetMapping(mapping); } @@ -1113,7 +1111,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable bool? canReMap = Map.Models.Stateless.Methods.IMapLogic.CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation); bool? isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation); MappingFromFilterPost mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson); - result = new(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection: null); + result = Mapping.Get(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection: null); int notMapped = mapLogic.UpdateMappingFromPerson(wholePercentagesToPersonContainers, result); return (result, notMapped); } @@ -1494,7 +1492,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable string filesCollectionRootDirectory = _Configuration.PropertyConfiguration.RootDirectory; (string cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution); IReadOnlyDictionary> fileGroups = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, [_Configuration.PropertyConfiguration.ResultContent, _Configuration.PropertyConfiguration.ResultContentCollection]); - ReadOnlyCollection> filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, filesCollectionRootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage: false); + ReadOnlyCollection> filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, directorySearchFilter, fileSearchFilter, filesCollectionRootDirectory, 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)"; diff --git a/Instance/Models/Binder/Configuration.cs b/Instance/Models/Binder/Configuration.cs index 8c03e89..dba3be4 100644 --- a/Instance/Models/Binder/Configuration.cs +++ b/Instance/Models/Binder/Configuration.cs @@ -27,6 +27,8 @@ public class Configuration public bool? ForceResizeLastWriteTimeToCreationTime { get; set; } public string? GenealogicalDataCommunicationFile { get; set; } public string? ImmichAssetsFile { get; set; } + public string? ImmichOwnerId { get; set; } + public string? ImmichRoot { get; set; } public string[]? IgnoreExtensions { get; set; } public string[]? JLinks { get; set; } public string? LinkedAlpha { get; set; } @@ -147,6 +149,8 @@ public class Configuration if (configuration?.ForceResizeLastWriteTimeToCreationTime is null) throw new NullReferenceException(nameof(configuration.ForceResizeLastWriteTimeToCreationTime)); if (configuration?.GenealogicalDataCommunicationFile is null) throw new NullReferenceException(nameof(configuration.GenealogicalDataCommunicationFile)); if (configuration?.ImmichAssetsFile is null) throw new NullReferenceException(nameof(configuration.ImmichAssetsFile)); + if (configuration?.ImmichOwnerId is null) throw new NullReferenceException(nameof(configuration.ImmichOwnerId)); + if (configuration?.ImmichRoot is null) throw new NullReferenceException(nameof(configuration.ImmichRoot)); // if (configuration?.IgnoreExtensions is null) throw new NullReferenceException(nameof(configuration.IgnoreExtensions)); // if (configuration?.JLinks is null) throw new NullReferenceException(nameof(configuration.JLinks)); // if (configuration?.LinkedAlpha is null) throw new NullReferenceException(nameof(configuration.LinkedAlpha)); @@ -239,6 +243,8 @@ public class Configuration configuration.ForceResizeLastWriteTimeToCreationTime.Value, configuration.GenealogicalDataCommunicationFile, configuration.ImmichAssetsFile, + configuration.ImmichOwnerId, + configuration.ImmichRoot, configuration.IgnoreExtensions ?? [], configuration.JLinks ?? [], configuration.LinkedAlpha, diff --git a/Instance/Models/Configuration.cs b/Instance/Models/Configuration.cs index 45ff305..71ddcb4 100644 --- a/Instance/Models/Configuration.cs +++ b/Instance/Models/Configuration.cs @@ -21,6 +21,8 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration, bool ForceResizeLastWriteTimeToCreationTime, string GenealogicalDataCommunicationFile, string ImmichAssetsFile, + string ImmichOwnerId, + string ImmichRoot, string[] IgnoreExtensions, string[] JLinks, string? LinkedAlpha, diff --git a/Instance/Models/Identifier.cs b/Instance/Models/Identifier.cs deleted file mode 100644 index 5832659..0000000 --- a/Instance/Models/Identifier.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace View_by_Distance.Instance.Models; - -internal sealed record Identifier(string[] DirectoryNames, - bool? HasDateTimeOriginal, - int Id, - long Length, - string PaddedId, - long Ticks) -{ - - public override string ToString() - { - string result = JsonSerializer.Serialize(this, IdentifierSourceGenerationContext.Default.Identifier); - return result; - } - -} - -[JsonSourceGenerationOptions(WriteIndented = true)] -[JsonSerializable(typeof(Identifier))] -internal partial class IdentifierSourceGenerationContext : JsonSerializerContext -{ -} - -[JsonSourceGenerationOptions(WriteIndented = true)] -[JsonSerializable(typeof(Identifier[]))] -internal partial class IdentifierCollectionSourceGenerationContext : JsonSerializerContext -{ -} \ No newline at end of file diff --git a/Instance/Models/_F_Random.cs b/Instance/Models/_F_Random.cs index b4bf61e..82bf031 100644 --- a/Instance/Models/_F_Random.cs +++ b/Instance/Models/_F_Random.cs @@ -25,7 +25,7 @@ internal class F_Random return result; } - private static ReadOnlyDictionary> GetDayToRelativePaths(ReadOnlyCollection distinctValidImageMappingCollection, string dateFormat, Dictionary immichAssets, ReadOnlyDictionary> idToPersonKeys) + private static ReadOnlyDictionary> GetDayToRelativePaths(ReadOnlyCollection distinctValidImageMappingCollection, string dateFormat, string immichOwnerId, string immichRoot, Dictionary immichAssets, ReadOnlyDictionary> idToPersonKeys) { Dictionary> results = []; string key; @@ -56,9 +56,11 @@ internal class F_Random relativePaths.Add(mapping.MappingFromItem.RelativePath); else { - if (!immichAssets.TryGetValue(mapping.MappingFromItem.RelativePath, out immichAsset)) + if (!immichAssets.TryGetValue($"{immichRoot}{mapping.MappingFromItem.RelativePath}", out immichAsset)) continue; - relativePaths.Add(immichAsset.PreviewPath); + if (!immichAsset.Path.Contains(immichOwnerId)) + continue; + relativePaths.Add(immichAsset.Path.Split(immichOwnerId)[1]); } } return new(results); @@ -80,7 +82,7 @@ internal class F_Random return results; } - internal void Random(Property.Models.Configuration configuration, string immichAssetsFile, int radomUseBirthdayMinimum, string[] validKeyWordsToIgnoreInRandom, ReadOnlyDictionary> personKeyToIds, ReadOnlyCollection? notNineCollection, ReadOnlyCollection distinctValidImageMappingCollection) + internal void Random(Property.Models.Configuration configuration, string immichAssetsFile, string immichOwnerId, string immichRoot, int radomUseBirthdayMinimum, string[] validKeyWordsToIgnoreInRandom, ReadOnlyDictionary> personKeyToIds, ReadOnlyDictionary splatNineIdentifiers, ReadOnlyCollection distinctValidImageMappingCollection) { string key; string json; @@ -93,8 +95,9 @@ internal class F_Random List distinctCollection = []; DateTime dateTime = new(2024, 1, 1); //Leap year Dictionary immichAssets = GetImmichAssets(immichAssetsFile); + int[] splatNineIdentifiersKeys = splatNineIdentifiers.Select(l => l.Key).ToArray(); ReadOnlyDictionary> idToPersonKeys = Map.Models.Stateless.Methods.IMapLogic.GetIdToPersonKeys(personKeyToIds); - ReadOnlyDictionary> dayToRelativePaths = GetDayToRelativePaths(distinctValidImageMappingCollection, dateFormat, immichAssets, idToPersonKeys); + ReadOnlyDictionary> dayToRelativePaths = GetDayToRelativePaths(distinctValidImageMappingCollection, dateFormat, immichOwnerId, immichRoot, immichAssets, idToPersonKeys); string fRandomCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(F_Random), "[]"); string[] files = Directory.GetFiles(fRandomCollectionDirectory, "*", SearchOption.TopDirectoryOnly); foreach (string file in files) @@ -102,11 +105,13 @@ internal class F_Random bool immichAssetsCountIsZero = immichAssets.Count == 0; foreach (Mapping mapping in distinctValidImageMappingCollection) { + if (mapping.MappingFromItem.IsArchive is not null && mapping.MappingFromItem.IsArchive.Value) + continue; if (distinctCollection.Contains(mapping.MappingFromItem.Id)) continue; if (mapping.MappingFromItem.FilePath.DirectoryFullPath is null) continue; - if (notNineCollection is not null && notNineCollection.Contains(mapping.MappingFromItem.Id)) + if (!splatNineIdentifiersKeys.Contains(mapping.MappingFromItem.Id)) continue; if (mapping.MappingFromItem.Keywords is not null && mapping.MappingFromItem.Keywords.Any(l => validKeyWordsToIgnoreInRandom.Contains(l))) continue; @@ -114,9 +119,11 @@ internal class F_Random relativePaths.Add(mapping.MappingFromItem.RelativePath); else { - if (!immichAssets.TryGetValue(mapping.MappingFromItem.RelativePath, out immichAsset)) + if (!immichAssets.TryGetValue($"{immichRoot}{mapping.MappingFromItem.RelativePath}", out immichAsset)) continue; - relativePaths.Add(immichAsset.PreviewPath); + if (!immichAsset.Path.Contains(immichOwnerId)) + continue; + relativePaths.Add(immichAsset.Path.Split(immichOwnerId)[1]); } distinctCollection.Add(mapping.MappingFromItem.Id); } diff --git a/Shared/Models/Identifier.cs b/Shared/Models/Identifier.cs new file mode 100644 index 0000000..aa2cbe1 --- /dev/null +++ b/Shared/Models/Identifier.cs @@ -0,0 +1,33 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace View_by_Distance.Shared.Models; + +public sealed record Identifier(string[] DirectoryNames, + string Extension, + bool? HasDateTimeOriginal, + int Id, + long Length, + string PaddedId, + long Ticks) +{ + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, IdentifierSourceGenerationContext.Default.Identifier); + return result; + } + +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(Identifier))] +public partial class IdentifierSourceGenerationContext : JsonSerializerContext +{ +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(Identifier[]))] +public partial class IdentifierCollectionSourceGenerationContext : JsonSerializerContext +{ +} \ No newline at end of file diff --git a/Shared/Models/ImmichAsset.cs b/Shared/Models/ImmichAsset.cs index f652c75..d934da0 100644 --- a/Shared/Models/ImmichAsset.cs +++ b/Shared/Models/ImmichAsset.cs @@ -5,11 +5,33 @@ namespace View_by_Distance.Shared.Models; public record ImmichAsset([property: JsonPropertyName("id")] string Id, [property: JsonPropertyName("deviceAssetId")] string DeviceAssetId, + // [property: JsonPropertyName("ownerId")] string OwnerId, + // [property: JsonPropertyName("deviceId")] string DeviceId, + // [property: JsonPropertyName("type")] string Type, [property: JsonPropertyName("originalPath")] string OriginalPath, - [property: JsonPropertyName("previewPath")] string PreviewPath, - [property: JsonPropertyName("isFavorite")] bool IsFavorite, - [property: JsonPropertyName("thumbnailPath")] string ThumbnailPath, - [property: JsonPropertyName("thumbhash")] string Thumbhash) + // [property: JsonPropertyName("fileCreatedAt")] DateTime FileCreatedAt, + // [property: JsonPropertyName("fileModifiedAt")] DateTime FileModifiedAt, + // [property: JsonPropertyName("isFavorite")] bool IsFavorite, + // [property: JsonPropertyName("duration")] string? Duration, + // [property: JsonPropertyName("encodedVideoPath")] string EncodedVideoPath, + // [property: JsonPropertyName("checksum")] string Checksum, + // [property: JsonPropertyName("isVisible")] bool IsVisible, + // [property: JsonPropertyName("livePhotoVideoId")] object? LivePhotoVideoId, + // [property: JsonPropertyName("updatedAt")] DateTime UpdatedAt, + // [property: JsonPropertyName("createdAt")] DateTime CreatedAt, + // [property: JsonPropertyName("isArchived")] bool IsArchived, + [property: JsonPropertyName("originalFileName")] string OriginalFileName, + // [property: JsonPropertyName("sidecarPath")] object? SidecarPath, + // [property: JsonPropertyName("thumbhash")] string Thumbhash, + // [property: JsonPropertyName("isOffline")] bool IsOffline, + // [property: JsonPropertyName("libraryId")] string LibraryId, + // [property: JsonPropertyName("isExternal")] bool IsExternal, + // [property: JsonPropertyName("deletedAt")] object? DeletedAt, + // [property: JsonPropertyName("localDateTime")] DateTime LocalDateTime, + // [property: JsonPropertyName("stackId")]? object? StackId, + [property: JsonPropertyName("duplicateId")] string? DuplicateId, + // [property: JsonPropertyName("status")] string Status, + [property: JsonPropertyName("path")] string Path) { public override string ToString() diff --git a/Shared/Models/Item.cs b/Shared/Models/Item.cs index 11069ce..e07f9af 100644 --- a/Shared/Models/Item.cs +++ b/Shared/Models/Item.cs @@ -9,6 +9,7 @@ public class Item : Properties.IItem protected List _Faces; protected readonly bool? _FileSizeChanged; protected readonly FilePath _FilePath; + protected bool? _IsArchive; protected bool? _IsNotUniqueAndNeedsReview; protected bool _IsUniqueFileName; protected bool _IsValidImageFormatExtension; @@ -21,6 +22,7 @@ public class Item : Properties.IItem public List Faces => _Faces; public bool? FileSizeChanged => _FileSizeChanged; public FilePath FilePath => _FilePath; + public bool? IsArchive => _IsArchive; public bool? IsNotUniqueAndNeedsReview => _IsNotUniqueAndNeedsReview; public bool IsUniqueFileName => _IsUniqueFileName; public bool IsValidImageFormatExtension => _IsValidImageFormatExtension; @@ -32,11 +34,12 @@ public class Item : Properties.IItem public FileHolder SourceDirectoryFileHolder => _SourceDirectoryFileHolder; [JsonConstructor] - public Item(List faces, FilePath filePath, bool? fileSizeChanged, bool? isNotUniqueAndNeedsReview, bool isUniqueFileName, bool isValidImageFormatExtension, bool? lastWriteTimeChanged, bool? moved, Property? property, string relativePath, FileHolder? resizedFileHolder, FileHolder sourceDirectoryFileHolder) + public Item(List faces, FilePath filePath, bool? fileSizeChanged, bool? isArchive, bool? isNotUniqueAndNeedsReview, bool isUniqueFileName, bool isValidImageFormatExtension, bool? lastWriteTimeChanged, bool? moved, Property? property, string relativePath, FileHolder? resizedFileHolder, FileHolder sourceDirectoryFileHolder) { _Faces = faces; _FilePath = filePath; _FileSizeChanged = fileSizeChanged; + _IsArchive = isArchive; _IsNotUniqueAndNeedsReview = isNotUniqueAndNeedsReview; _IsUniqueFileName = isUniqueFileName; _IsValidImageFormatExtension = isValidImageFormatExtension; @@ -48,18 +51,19 @@ public class Item : Properties.IItem _SourceDirectoryFileHolder = sourceDirectoryFileHolder; } - public Item(FilePath filePath, FileHolder sourceDirectoryFileHolder, string relativePath, bool? isNotUniqueAndNeedsReview, bool isUniqueFileName, bool isValidImageFormatExtension, Property? property, bool? abandoned, bool? fileSizeChanged, bool? lastWriteTimeChanged) : - this([], filePath, fileSizeChanged, isNotUniqueAndNeedsReview, isUniqueFileName, isValidImageFormatExtension, lastWriteTimeChanged, null, property, relativePath, null, sourceDirectoryFileHolder) + public static Item Get(FilePath filePath, FileHolder sourceDirectoryFileHolder, string relativePath, bool? isArchive, bool? isNotUniqueAndNeedsReview, bool isUniqueFileName, bool isValidImageFormatExtension, Property? property, bool? abandoned, bool? fileSizeChanged, bool? lastWriteTimeChanged) { + Item result; if (relativePath.EndsWith(".json")) throw new ArgumentException("Can not be a *.json file!"); - if (filePath is not null && filePath.ExtensionLowered is ".json") + if (filePath.ExtensionLowered is ".json") throw new ArgumentException("Can not be a *.json file!"); + result = new([], filePath, fileSizeChanged, isArchive, isNotUniqueAndNeedsReview, isUniqueFileName, isValidImageFormatExtension, lastWriteTimeChanged, null, property, relativePath, null, sourceDirectoryFileHolder); + return result; } - public Item(FilePath filePath, FileHolder sourceDirectoryFileHolder, string relativePath, bool isValidImageFormatExtension) : - this(filePath, sourceDirectoryFileHolder, relativePath, null, false, isValidImageFormatExtension, null, null, null, null) - { } + public static Item Get(FilePath filePath, FileHolder sourceDirectoryFileHolder, string relativePath, bool isValidImageFormatExtension) => + Get(filePath, sourceDirectoryFileHolder, relativePath, null, null, false, isValidImageFormatExtension, null, null, null, null); public override string ToString() { diff --git a/Shared/Models/Mapping.cs b/Shared/Models/Mapping.cs index 4efc725..debcd3f 100644 --- a/Shared/Models/Mapping.cs +++ b/Shared/Models/Mapping.cs @@ -36,9 +36,8 @@ public class Mapping : Properties.IMapping _SortingContainer = sortingContainer; } - public Mapping(FilePath filePath, MappingFromFilterPost mappingFromFilterPost, MappingFromFilterPre mappingFromFilterPre, MappingFromItem mappingFromItem, MappingFromLocation? mappingFromLocation, List? mappingFromPhotoPrismCollection) : - this(null, filePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, null, mappingFromPhotoPrismCollection, null, null) - { } + public static Mapping Get(FilePath filePath, MappingFromFilterPost mappingFromFilterPost, MappingFromFilterPre mappingFromFilterPre, MappingFromItem mappingFromItem, MappingFromLocation? mappingFromLocation, List? mappingFromPhotoPrismCollection) => + new(null, filePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, null, mappingFromPhotoPrismCollection, null, null); public override string ToString() { diff --git a/Shared/Models/MappingFromItem.cs b/Shared/Models/MappingFromItem.cs index 680d6f8..884d08e 100644 --- a/Shared/Models/MappingFromItem.cs +++ b/Shared/Models/MappingFromItem.cs @@ -7,6 +7,7 @@ public record MappingFromItem(DateTime[] ContainerDateTimes, DateTime? DateTimeDigitized, DateTime? DateTimeOriginal, int Id, + bool? IsArchive, FilePath FilePath, bool? IsWrongYear, string[] Keywords, @@ -35,7 +36,7 @@ public record MappingFromItem(DateTime[] ContainerDateTimes, List dateTimes = item.Property.GetDateTimes(); DateTime minimumDateTime = Stateless.Methods.IProperty.GetMinimumDateTime(item.Property); (bool? isWrongYear, _) = Stateless.Methods.IProperty.IsWrongYear(item.FilePath, item.Property.DateTimeOriginal, dateTimes); - result = new(containerDateTimes, item.Property.DateTimeDigitized, item.Property.DateTimeOriginal, item.Property.Id.Value, item.FilePath, isWrongYear, item.Property.Keywords ?? [], minimumDateTime, item.Property.Model, item.RelativePath, resizedFileHolder); + result = new(containerDateTimes, item.Property.DateTimeDigitized, item.Property.DateTimeOriginal, item.Property.Id.Value, item.IsArchive, item.FilePath, isWrongYear, item.Property.Keywords ?? [], minimumDateTime, item.Property.Model, item.RelativePath, resizedFileHolder); return result; } diff --git a/Shared/Models/Properties/IItem.cs b/Shared/Models/Properties/IItem.cs index ee6564c..0eff1e7 100644 --- a/Shared/Models/Properties/IItem.cs +++ b/Shared/Models/Properties/IItem.cs @@ -6,6 +6,7 @@ public interface IItem public bool? FileSizeChanged { get; } public List Faces { get; } public FilePath FilePath { get; } + public bool? IsArchive { get; } public bool? IsNotUniqueAndNeedsReview { get; } public bool IsUniqueFileName { get; } public bool IsValidImageFormatExtension { get; } diff --git a/Shared/Models/Stateless/Methods/Container.cs b/Shared/Models/Stateless/Methods/Container.cs index 4f8ad93..2455d53 100644 --- a/Shared/Models/Stateless/Methods/Container.cs +++ b/Shared/Models/Stateless/Methods/Container.cs @@ -71,7 +71,7 @@ internal abstract class Container return result; } - private static void ParallelFor(IDlibDotNet? dlibDotNet, 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, ReadOnlyDictionary? splatNineIdentifiers, Models.FilePair filePair, List results) { dlibDotNet?.Tick(); bool abandoned = false; @@ -82,6 +82,7 @@ internal abstract class Container bool? fileSizeChanged = property is not null ? property.FileSize != filePath.Length : null; bool isValidImageFormatExtension = propertyConfiguration.ValidImageFormatExtensions.Contains(filePath.ExtensionLowered); bool? shouldIgnore = property is null || property.Keywords is null ? null : propertyConfiguration.IgnoreRulesKeyWords.Any(l => property.Keywords.Contains(l)); + bool? isArchive = filePath.Id is null || splatNineIdentifiers is null ? null : splatNineIdentifiers.TryGetValue(filePath.Id.Value, out Identifier? identifier); if (shouldIgnore is not null) { if (shouldIgnore.Value) @@ -115,12 +116,12 @@ internal abstract class Container File.SetCreationTime(sourceDirectoryFileHolder.FullName, new(filePath.LastWriteTicks)); File.SetLastWriteTime(sourceDirectoryFileHolder.FullName, sourceDirectoryFileHolder.LastWriteTime.Value); } - Models.Item item = new(filePath, sourceDirectoryFileHolder, relativePath, filePair.IsNotUniqueAndNeedsReview, filePair.IsUnique, isValidImageFormatExtension, property, abandoned, fileSizeChanged, lastWriteTimeChanged); + Models.Item item = Models.Item.Get(filePath, sourceDirectoryFileHolder, relativePath, isArchive, filePair.IsNotUniqueAndNeedsReview, filePair.IsUnique, isValidImageFormatExtension, property, abandoned, fileSizeChanged, lastWriteTimeChanged); lock (results) results.Add(new(filePair.IsUnique, filePair.Collection, filePath, item)); } - private static List GetFilePairs(IDlibDotNet? dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection> filePathsCollection, string directorySearchFilter) + private static List GetFilePairs(IDlibDotNet? dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyDictionary? splatNineIdentifiers, ReadOnlyCollection> filePathsCollection, string directorySearchFilter) { List results = []; const string extension = ".json"; @@ -128,11 +129,11 @@ internal abstract class Container int filesCollectionDirectoryLength = filesCollectionDirectory.Length; ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = maxDegreeOfParallelism }; 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)); + _ = Parallel.For(0, filePairs.Count, parallelOptions, (i, state) => ParallelFor(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, extension, filesCollectionDirectoryLength, splatNineIdentifiers, filePairs[i], results)); return results; } - private static (int, Models.Container[]) GetContainers(IDlibDotNet? dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection> filePathsCollection, string directorySearchFilter) + private static (int, Models.Container[]) GetContainers(IDlibDotNet? dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyDictionary? splatNineIdentifiers, ReadOnlyCollection> filePathsCollection, string directorySearchFilter) { List results = []; string directory; @@ -156,7 +157,7 @@ internal abstract class Container throw new Exception(); } } - List filePairs = GetFilePairs(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, filePathsCollection, directorySearchFilter); + List filePairs = GetFilePairs(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, splatNineIdentifiers, filePathsCollection, directorySearchFilter); foreach (FilePair filePair in filePairs) { if (!directoryToItems.TryGetValue(filePair.FilePath.DirectoryFullPath, out items)) @@ -177,15 +178,15 @@ internal abstract class Container return (filePairs.Count, results.ToArray()); } - internal static ReadOnlyCollection GetContainers(IDlibDotNet dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyCollection> filePathsCollection) + internal static ReadOnlyCollection GetContainers(IDlibDotNet dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyDictionary? splatNineIdentifiers, ReadOnlyCollection> filePathsCollection) { Models.Container[] results; const string directorySearchFilter = "*"; - (_, results) = GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, filePathsCollection, directorySearchFilter); + (_, results) = GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, splatNineIdentifiers, filePathsCollection, directorySearchFilter); return new(results); } - internal static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory) + internal static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyDictionary? splatNineIdentifiers, string aPropertySingletonDirectory) { int count; Models.Container[] results; @@ -195,7 +196,7 @@ internal abstract class Container const string directorySearchFilter = "*"; ReadOnlyCollection filesCollection = IDirectory.GetFilesCollection(propertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage); ReadOnlyCollection> filePathsCollection = IDirectory.GetFilePathCollections(propertyConfiguration, filesCollection); - (count, results) = GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, propertyConfiguration.RootDirectory, filePathsCollection, directorySearchFilter); + (count, results) = GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, propertyConfiguration.RootDirectory, splatNineIdentifiers, filePathsCollection, directorySearchFilter); return (count, results); } diff --git a/Shared/Models/Stateless/Methods/IContainer.cs b/Shared/Models/Stateless/Methods/IContainer.cs index f727e3c..ddf82e2 100644 --- a/Shared/Models/Stateless/Methods/IContainer.cs +++ b/Shared/Models/Stateless/Methods/IContainer.cs @@ -18,12 +18,17 @@ public interface IContainer (int, Models.Container[]) TestStatic_GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory) => GetContainers(propertyConfiguration, aPropertySingletonDirectory); static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory) => - Container.GetContainers(propertyConfiguration, aPropertySingletonDirectory); + GetContainers(propertyConfiguration, null, aPropertySingletonDirectory); - 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); + (int, Models.Container[]) TestStatic_GetContainers(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyDictionary? splatNineIdentifiers, string aPropertySingletonDirectory) => + GetContainers(propertyConfiguration, splatNineIdentifiers, aPropertySingletonDirectory); + static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, ReadOnlyDictionary? splatNineIdentifiers, string aPropertySingletonDirectory) => + Container.GetContainers(propertyConfiguration, splatNineIdentifiers, aPropertySingletonDirectory); + + ReadOnlyCollection TestStatic_GetContainers(IDlibDotNet dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyDictionary? splatNineIdentifiers, ReadOnlyCollection> filePathsCollection) => + GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, splatNineIdentifiers, filePathsCollection); + static ReadOnlyCollection GetContainers(IDlibDotNet dlibDotNet, Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory, string filesCollectionDirectory, ReadOnlyDictionary? splatNineIdentifiers, ReadOnlyCollection> filePathsCollection) => + Container.GetContainers(dlibDotNet, propertyConfiguration, aPropertySingletonDirectory, filesCollectionDirectory, splatNineIdentifiers, 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 fde7b29..6f02146 100644 --- a/Shared/Models/Stateless/Methods/IDirectory.cs +++ b/Shared/Models/Stateless/Methods/IDirectory.cs @@ -20,10 +20,10 @@ 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); + ReadOnlyCollection> TestStatic_GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string fileSearchFilter, string directory, bool useCeilingAverage) => + GetFilePathCollections(propertyConfiguration, directorySearchFilter, fileSearchFilter, directory, useCeilingAverage); + static ReadOnlyCollection> GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string fileSearchFilter, string directory, bool useCeilingAverage) => + XDirectory.GetFilePathCollections(propertyConfiguration, directorySearchFilter, fileSearchFilter, directory, useCeilingAverage); void TestStatic_MoveFiles(List files, string find, string replace) => MoveFiles(files, find, replace); diff --git a/Shared/Models/Stateless/Methods/XDirectory.cs b/Shared/Models/Stateless/Methods/XDirectory.cs index 531f29d..60397af 100644 --- a/Shared/Models/Stateless/Methods/XDirectory.cs +++ b/Shared/Models/Stateless/Methods/XDirectory.cs @@ -54,7 +54,7 @@ internal abstract partial class XDirectory return new(results); } - internal static ReadOnlyCollection> GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, string directory, string directorySearchFilter, string fileSearchFilter, bool useCeilingAverage) + internal static ReadOnlyCollection> GetFilePathCollections(Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string fileSearchFilter, string directory, bool useCeilingAverage) { ReadOnlyCollection> results; ReadOnlyCollection filesCollection = GetFilesCollection(directory, directorySearchFilter, fileSearchFilter, useCeilingAverage); diff --git a/Tests/UnitTestResize.cs b/Tests/UnitTestResize.cs index 81e895a..a938053 100644 --- a/Tests/UnitTestResize.cs +++ b/Tests/UnitTestResize.cs @@ -130,6 +130,7 @@ public class UnitTestResize string sourceDirectoryName = "Mike iCloud Have Date Taken 2022 !9"; Item item; bool reverse = false; + bool isArchive = false; FileHolder resizedFileHolder; List parseExceptions = []; Shared.Models.Property? property = null; @@ -165,7 +166,7 @@ public class UnitTestResize resize.SetAngleBracketCollection(cResultsFullGroupDirectory, sourceDirectory); resize.Update(cResultsFullGroupDirectory); blurHasher.Update(cResultsFullGroupDirectory); - item = new(filePath, sourceDirectoryFileHolder, relativePath, isNotUniqueAndNeedsReview, isUniqueFileName, isValidImageFormatExtension, property, false, false, false); + item = Item.Get(filePath, sourceDirectoryFileHolder, relativePath, isArchive, isNotUniqueAndNeedsReview, isUniqueFileName, isValidImageFormatExtension, property, false, false, false); if (item.Property is null) { property = propertyLogic.GetProperty(metadata, item, subFileTuples, parseExceptions); diff --git a/TestsWithFaceRecognitionDotNet/UnitTestFace.cs b/TestsWithFaceRecognitionDotNet/UnitTestFace.cs index 0239063..26d7743 100644 --- a/TestsWithFaceRecognitionDotNet/UnitTestFace.cs +++ b/TestsWithFaceRecognitionDotNet/UnitTestFace.cs @@ -203,6 +203,7 @@ public class UnitTestFace string sourceDirectoryName = "Facebook/2023.2 Summer Facebook"; Item item; bool reverse = false; + bool isArchive = false; FileHolder resizedFileHolder; List parseExceptions = []; Shared.Models.Property? property = null; @@ -238,7 +239,7 @@ public class UnitTestFace resize.SetAngleBracketCollection(cResultsFullGroupDirectory, sourceDirectory); resize.Update(cResultsFullGroupDirectory); blurHasher.Update(cResultsFullGroupDirectory); - item = new(filePath, sourceDirectoryFileHolder, relativePath, isNotUniqueAndNeedsReview, isUniqueFileName, isValidImageFormatExtension, property, false, false, false); + item = Item.Get(filePath, sourceDirectoryFileHolder, relativePath, isArchive, isNotUniqueAndNeedsReview, isUniqueFileName, isValidImageFormatExtension, property, false, false, false); if (item.Property is null) { property = propertyLogic.GetProperty(metadata, item, subFileTuples, parseExceptions);