diff --git a/Copy-Distinct/CopyDistinct.cs b/Copy-Distinct/CopyDistinct.cs index e57cc97..e720c03 100644 --- a/Copy-Distinct/CopyDistinct.cs +++ b/Copy-Distinct/CopyDistinct.cs @@ -59,11 +59,12 @@ public class CopyDistinct if (_PropertyConfiguration is null) throw new NullReferenceException(nameof(_PropertyConfiguration)); bool moveBack; + const bool useCeilingAverage = true; const string fileSearchFilter = "*"; const string directorySearchFilter = "*"; string copyTo = Path.GetFullPath(_AppSettings.CopyTo); bool move = copyTo == _PropertyConfiguration.RootDirectory; - List filesCollection = Shared.Models.Stateless.Methods.IDirectory.GetFilesCollection(_PropertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter); + List filesCollection = Shared.Models.Stateless.Methods.IDirectory.GetFilesCollection(_PropertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage); bool anyLenFiles = filesCollection.Any(l => l.Any(m => m.EndsWith("len"))); if (!move) moveBack = false; diff --git a/Duplicate-Search/DuplicateSearch.cs b/Duplicate-Search/DuplicateSearch.cs index 53273d8..420c75d 100644 --- a/Duplicate-Search/DuplicateSearch.cs +++ b/Duplicate-Search/DuplicateSearch.cs @@ -139,8 +139,6 @@ public class DuplicateSearch string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}"); (f, containers) = Shared.Models.Stateless.Methods.IContainer.GetContainers(configuration, aPropertySingletonDirectory); } - if (appSettings.SortContainers) - containers = Shared.Models.Stateless.Methods.IContainer.SortContainers(argZeroIsConfigurationRootDirectory, argZero, containers); return containers; } @@ -192,7 +190,7 @@ public class DuplicateSearch if (mappingFromItem is not null) { resizedFileHolder = new(mappingFromItem.ResizedFileHolder.FullName.Replace($"0{duplicates}", $"1{duplicates}")); - collection[0] = new(mappingFromItem.ContainerDateTimes, item.Property.DateTimeDigitized, item.Property.DateTimeOriginal, mappingFromItem.Id, mappingFromItem.ImageFileHolder, mappingFromItem.IsWrongYear, mappingFromItem.MinimumDateTime, item.Property.Model, mappingFromItem.RelativePath, resizedFileHolder); + collection[0] = new(mappingFromItem.ContainerDateTimes, item.Property.DateTimeDigitized, item.Property.DateTimeOriginal, mappingFromItem.Id, mappingFromItem.ImageFileHolder, mappingFromItem.IsWrongYear, item.Property.Keywords, mappingFromItem.MinimumDateTime, item.Property.Model, mappingFromItem.RelativePath, resizedFileHolder); } } resizedFileHolder = new(string.Concat(Path.Combine(destinationRoot, directory), item.RelativePath)); diff --git a/Duplicate-Search/Models/AppSettings.cs b/Duplicate-Search/Models/AppSettings.cs index 2ffb756..16a287b 100644 --- a/Duplicate-Search/Models/AppSettings.cs +++ b/Duplicate-Search/Models/AppSettings.cs @@ -10,18 +10,16 @@ public class AppSettings public bool IndexOnly { init; get; } public int MaxDegreeOfParallelism { init; get; } public string OutputExtension { init; get; } - public bool SortContainers { init; get; } public bool Reverse { init; get; } public string WorkingDirectoryName { init; get; } [JsonConstructor] - public AppSettings(string company, bool indexOnly, int maxDegreeOfParallelism, string outputExtension, bool sortContainers, bool reverse, string workingDirectoryName) + public AppSettings(string company, bool indexOnly, int maxDegreeOfParallelism, string outputExtension, bool reverse, string workingDirectoryName) { Company = company; IndexOnly = indexOnly; MaxDegreeOfParallelism = maxDegreeOfParallelism; OutputExtension = outputExtension; - SortContainers = sortContainers; Reverse = reverse; WorkingDirectoryName = workingDirectoryName; } diff --git a/Duplicate-Search/Models/Binder/AppSettings.cs b/Duplicate-Search/Models/Binder/AppSettings.cs index fe1d2b9..8dcdd62 100644 --- a/Duplicate-Search/Models/Binder/AppSettings.cs +++ b/Duplicate-Search/Models/Binder/AppSettings.cs @@ -12,7 +12,6 @@ public class AppSettings public bool? IndexOnly { get; set; } public int? MaxDegreeOfParallelism { get; set; } public string OutputExtension { get; set; } - public bool? SortContainers { get; set; } public bool? Reverse { get; set; } public string WorkingDirectoryName { get; set; } @@ -31,8 +30,6 @@ public class AppSettings throw new NullReferenceException(nameof(appSettings.IndexOnly)); if (appSettings?.MaxDegreeOfParallelism is null) throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism)); - if (appSettings?.SortContainers is null) - throw new NullReferenceException(nameof(appSettings.SortContainers)); if (appSettings?.Reverse is null) throw new NullReferenceException(nameof(appSettings.Reverse)); result = new( @@ -40,7 +37,6 @@ public class AppSettings appSettings.IndexOnly.Value, appSettings.MaxDegreeOfParallelism.Value, appSettings.OutputExtension, - appSettings.SortContainers.Value, appSettings.Reverse.Value, appSettings.WorkingDirectoryName ); diff --git a/Duplicate-Search/appsettings.Development.json b/Duplicate-Search/appsettings.Development.json index d0abe27..52fff81 100644 --- a/Duplicate-Search/appsettings.Development.json +++ b/Duplicate-Search/appsettings.Development.json @@ -9,119 +9,6 @@ "Serilog": { "MinimumLevel": "Debug" }, - "SortContainers": false, - "IgnoreRelativePaths": [ - "3757 W Whitman 2017", - "501 Playful Meadows 2006", - "501 Playful Meadows 2007", - "501 Playful Meadows 2008", - "501 Playful Meadows 2009", - "501 Playful Meadows 2010", - "501 Playful Meadows 2013", - "501 Playful Meadows 2015", - "6309 Evesham 2003", - "6309 Evesham 2004", - "Crystal's Wedding 2003", - "Danny's Wedding 2009", - "Door images 2019", - "Family Pictures 2006", - "Family Pictures 2007", - "Family Pictures 2011", - "Family Pictures 2013", - "GrandPrix 2004", - "Kids School Pictures 2004", - "Kristy 2002", - "Kristy Parents Wedding 2005", - "Logan Ultrasound 2007", - "Mandy's Dogs 2008", - "Motorcycles 2010", - "Motorcycles 2013", - "Motorcycles 2014", - "Phares Slides", - "Portrait Innovations April 2008", - "Portrait Innovations December 2007", - "Portrait Innovations June 2008", - "Portrait Innovations March 2012", - "The guys house 2000", - "Tracy Pictures 2005", - "Tracy Pictures 2006", - "Tracy Pictures 2007", - "Tracy Pictures 2008", - "Tracy Pictures 2009", - "Tracy Pictures 2010", - "Tracy Pictures 2011", - "Tracy Pictures 2012", - "Tracy Pictures 2013 Jan-July", - "Tracy Pictures 2013 July- Dec", - "Tracy Pictures 2014", - "Tracy Pictures 2015", - "Tracy Took The Kids 2006", - "Tracy's Bday 2012", - "Tracy's Wedding 2002", - "Trip to Colorado 10 2002", - "Trip to Colorado June 2002", - "Tub 2002", - "Vericruz 2011", - "zzz 2005.1 Spring Tracy Pictures", - "zzz 2005.2 Summer Tracy Pictures", - "zzz 2005.3 Fall Tracy Pictures", - "zzz 2005.4 Winter Tracy Pictures", - "zzz 2006.1 Spring Tracy Pictures", - "zzz 2007.0 Winter Tracy Pictures", - "zzz 2007.2 Summer Tracy Pictures", - "zzz 2008.2 Summer Tracy Pictures", - "zzz 2009.0 Winter Tracy Pictures", - "zzz 2009.2 Summer Tracy Pictures", - "zzz 2009.3 Fall Tracy Pictures", - "zzz 2009.4 Winter Tracy Pictures", - "zzz 2010.0 Winter Tracy Pictures", - "zzz 2010.1 Spring Tracy Pictures", - "zzz 2010.2 Summer Tracy Pictures", - "zzz 2010.3 Fall Tracy Pictures", - "zzz 2011.0 Winter Tracy Pictures", - "zzz 2011.1 Spring Tracy Pictures", - "zzz 2011.2 Summer Tracy Pictures", - "zzz 2011.3 Fall Tracy Pictures", - "zzz 2011.4 Winter Tracy Pictures", - "zzz 2012.0 Winter Tracy Pictures", - "zzz 2012.1 Spring Tracy Pictures", - "zzz 2012.2 Summer Tracy Pictures", - "zzz 2012.3 Fall Tracy Pictures", - "zzz 2012.4 Winter Tracy Pictures", - "zzz 2013.0 Winter Tracy Pictures", - "zzz 2013.1 Spring Tracy Pictures", - "zzz 2013.2 Summer Tracy Pictures", - "zzz 2013.3 Fall Tracy Pictures", - "zzz 2013.4 Winter Tracy Pictures", - "zzz 2014.0 Winter Tracy Pictures", - "zzz 2014.1 Spring Tracy Pictures", - "zzz 2014.2 Summer Tracy Pictures", - "zzz 2014.3 Fall Tracy Pictures", - "zzz 2014.4 Winter Tracy Pictures", - "zzz 2015.0 Winter Tracy Pictures", - "zzz Family Pictures", - "zzz Family Pictures", - "zzz Family Pictures", - "zzz Family Pictures", - "zzz GrandPrix", - "zzz Motorcycles", - "zzz Motorcycles", - "zzz Motorcycles", - "zzz Parents Yard", - "zzz Phares Family Pictures", - "zzz Phares Slides ####", - "zzz Portrait Innovations April", - "zzz Portrait Innovations Files", - "zzz Portrait Innovations June", - "zzz Portrait Innovations March", - "zzz Rex Memorial ####", - "zzz Scanned Grandma's Quilt ####", - "zzz Scanned Pictures Of Kids ####", - "zzz Scanned Prints ####", - "zzz Slide in Name Order Originals (622) ####", - "zzz Tub", - "zzz Vericruz" - ], "Windows": { "Configuration": { "xRootDirectory": "F:/Tmp/Phares/Compare/Images-dd514b88", diff --git a/Duplicate-Search/appsettings.json b/Duplicate-Search/appsettings.json index b41cc57..e5b1778 100644 --- a/Duplicate-Search/appsettings.json +++ b/Duplicate-Search/appsettings.json @@ -12,7 +12,6 @@ }, "MaxDegreeOfParallelism": 6, "Reverse": false, - "SortContainers": true, "Serilog": { "Using": [ "Serilog.Sinks.Console", diff --git a/Instance/DlibDotNet.cs b/Instance/DlibDotNet.cs index 62e900c..655816b 100644 --- a/Instance/DlibDotNet.cs +++ b/Instance/DlibDotNet.cs @@ -558,6 +558,7 @@ public partial class DlibDotNet string focusRelativePath = Path.GetFullPath(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, _Configuration.FocusDirectory)); bool? isFocusRelativePath = string.IsNullOrEmpty(_Configuration.FocusDirectory) ? null : container.SourceDirectory.StartsWith(focusRelativePath); string facePartsCollectionDirectory = _Configuration.CopyFacesAndSaveFaceLandmarkForOutputResolutions.Contains(outputResolution) ? _FaceParts.GetFacePartsDirectory(_Configuration.PropertyConfiguration, d2ResultsFullGroupDirectory, item: filteredItems.First(), includeNameWithoutExtension: false) : string.Empty; + bool anyPropertiesChangedForX = _Configuration.PropertyConfiguration.PropertiesChangedForProperty || _Configuration.PropertiesChangedForDistance || _Configuration.PropertiesChangedForFaces || _Configuration.PropertiesChangedForIndex || _Configuration.PropertiesChangedForMetadata || _Configuration.PropertiesChangedForResize; using ProgressBar progressBar = new(filteredItems.Length, message, options); _ = Parallel.For(0, filteredItems.Length, parallelOptions, (i, state) => { @@ -579,7 +580,7 @@ public partial class DlibDotNet containerDateTimes, isFocusRelativePath, facePartsCollectionDirectory); - if (i == 0 || sourceDirectoryChanges.Count > 0) + if (!anyPropertiesChangedForX && (i == 0 || sourceDirectoryChanges.Count > 0)) progressBar.Tick(); } catch (Exception ex) @@ -1131,7 +1132,7 @@ public partial class DlibDotNet ProgressBar progressBar; (cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution); IReadOnlyDictionary fileGroups = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, new string[] { _Configuration.PropertyConfiguration.ResultContent }); - filesCollection = IDirectory.GetFilesCollection(_Configuration.PropertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter); + filesCollection = IDirectory.GetFilesCollection(_Configuration.PropertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage: false); message = $") Selecting for ## pattern directory - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)"; count = filesCollection.Select(l => l.Length).Sum(); filesCollectionCountIsOne = filesCollection.Count == 1; @@ -1174,7 +1175,7 @@ public partial class DlibDotNet if (outputResolution.Any(l => char.IsNumber(l))) continue; (cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution); - filesCollection = IDirectory.GetFilesCollection(Path.Combine(cResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent, _Configuration.PropertyConfiguration.ResultAllInOne), directorySearchFilter, fileSearchFilter); + filesCollection = IDirectory.GetFilesCollection(Path.Combine(cResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent, _Configuration.PropertyConfiguration.ResultAllInOne), directorySearchFilter, fileSearchFilter, useCeilingAverage: true); count = filesCollection.Select(l => l.Length).Sum(); break; } @@ -1194,7 +1195,6 @@ public partial class DlibDotNet fileNameToCollection = !Directory.Exists(fPhotoPrismSingletonDirectory) ? fileNameToCollection = new() : F_PhotoPrism.GetFileNameToCollection(fPhotoPrismSingletonDirectory); B_Metadata metadata = new(_Configuration.PropertyConfiguration, _Configuration.ForceMetadataLastWriteTimeToCreationTime, _Configuration.PropertiesChangedForMetadata, bResultsFullGroupDirectory); mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _Distance, personContainers, ticks, a2PeopleSingletonDirectory, eDistanceContentDirectory); - containers = Shared.Models.Stateless.Methods.IContainer.SortContainers(_ArgZeroIsConfigurationRootDirectory, argZero, containers); FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, t, containers, propertyLogic, metadata, fileNameToCollection, mapLogic); ReadOnlyCollection distinctFilteredItems = Shared.Models.Stateless.Methods.IContainer.GetItems(_Configuration.PropertyConfiguration, new(containers), distinctItems: true, filterItems: true); if (_Configuration.LookForAbandoned) @@ -1233,7 +1233,7 @@ public partial class DlibDotNet && _Exceptions.Count == 0) MapLogic(ticks, new(containers), fPhotoPrismContentDirectory, mapLogic, outputResolution, new(personKeyToIds), distinctFilteredFaces, distinctFilteredMappingCollection); if (_Configuration.SaveRandomForOutputResolutions.Contains(outputResolution) && personKeyToIds.Count > 0 && distinctFilteredMappingCollection.Count > 0) - _Random.Random(_Configuration.PropertyConfiguration, outputResolution, personKeyToIds, distinctFilteredMappingCollection); + _Random.Random(_Configuration.PropertyConfiguration, _Configuration.ValidKeyWordsToIgnoreInRandom, outputResolution, personKeyToIds, distinctFilteredMappingCollection); if (_IsEnvironment.Development) continue; if (!_IsEnvironment.Development) diff --git a/Instance/Models/Binder/Configuration.cs b/Instance/Models/Binder/Configuration.cs index fff91b5..a412abd 100644 --- a/Instance/Models/Binder/Configuration.cs +++ b/Instance/Models/Binder/Configuration.cs @@ -92,6 +92,7 @@ public class Configuration [Display(Name = "Sorting Minimum to use Sigma"), Required] public int? SortingMinimumToUseSigma { get; set; } [Display(Name = "Test Distance Results"), Required] public bool? TestDistanceResults { get; set; } [Display(Name = "Use Filter Tries"), Required] public int? UseFilterTries { get; set; } + [Display(Name = "Valid KeyWords to Ignore in Random"), Required] public string[] ValidKeyWordsToIgnoreInRandom { get; set; } [Display(Name = "Valid Resolutions"), Required] public string[] ValidResolutions { get; set; } #nullable restore @@ -241,6 +242,8 @@ public class Configuration throw new NullReferenceException(nameof(configuration.TestDistanceResults)); if (configuration.UseFilterTries is null) throw new NullReferenceException(nameof(configuration.UseFilterTries)); + if (configuration.ValidKeyWordsToIgnoreInRandom is null) + throw new NullReferenceException(nameof(configuration.ValidKeyWordsToIgnoreInRandom)); if (configuration.ValidResolutions is null) throw new NullReferenceException(nameof(configuration.ValidResolutions)); _ = DateTime.Now.AddDays(-configuration.RangeDaysDeltaTolerance[1]); @@ -324,6 +327,7 @@ public class Configuration configuration.SortingMinimumToUseSigma.Value, configuration.TestDistanceResults.Value, configuration.UseFilterTries.Value, + configuration.ValidKeyWordsToIgnoreInRandom, configuration.ValidResolutions); return result; } diff --git a/Instance/Models/Configuration.cs b/Instance/Models/Configuration.cs index 5760268..628247c 100644 --- a/Instance/Models/Configuration.cs +++ b/Instance/Models/Configuration.cs @@ -89,6 +89,7 @@ public class Configuration public bool TestDistanceResults { init; get; } public int UseFilterTries { init; get; } public string[] ValidResolutions { init; get; } + public string[] ValidKeyWordsToIgnoreInRandom { init; get; } public bool DeletePossibleDuplicates { get; internal set; } [JsonConstructor] @@ -172,6 +173,7 @@ public class Configuration int sortingSigma, bool testDistanceResults, int useFilterTries, + string[] validKeyWordsToIgnoreInRandom, string[] validResolutions) { _PropertyConfiguration = propertyConfiguration; @@ -254,6 +256,7 @@ public class Configuration SortingMinimumToUseSigma = sortingSigma; TestDistanceResults = testDistanceResults; UseFilterTries = useFilterTries; + ValidKeyWordsToIgnoreInRandom = validKeyWordsToIgnoreInRandom; ValidResolutions = validResolutions; } diff --git a/Instance/Models/_F_Random.cs b/Instance/Models/_F_Random.cs index ff77d28..2ec2a16 100644 --- a/Instance/Models/_F_Random.cs +++ b/Instance/Models/_F_Random.cs @@ -59,7 +59,7 @@ internal class F_Random return results; } - internal void Random(Property.Models.Configuration configuration, string outputResolution, Dictionary> personKeyToIds, ReadOnlyCollection mappingCollection) + internal void Random(Property.Models.Configuration configuration, string[] validKeyWordsToIgnoreInRandom, string outputResolution, Dictionary> personKeyToIds, ReadOnlyCollection mappingCollection) { string key; string json; @@ -79,6 +79,8 @@ internal class F_Random { if (distinctCollection.Contains(mapping.MappingFromItem.Id)) continue; + if (mapping.MappingFromItem.Keywords is not null && mapping.MappingFromItem.Keywords.Any(l => validKeyWordsToIgnoreInRandom.Contains(l))) + continue; if (mapping.MappingFromItem.ImageFileHolder.DirectoryName is null) continue; relativePaths.Add(mapping.MappingFromItem.RelativePath); diff --git a/Map/Models/MapLogic.cs b/Map/Models/MapLogic.cs index b91023e..ca79a78 100644 --- a/Map/Models/MapLogic.cs +++ b/Map/Models/MapLogic.cs @@ -10,9 +10,12 @@ using WindowsShortcutFactory; namespace View_by_Distance.Map.Models; -public class MapLogic : Shared.Models.Methods.IMapLogic +public partial class MapLogic : Shared.Models.Methods.IMapLogic { + [GeneratedRegex("[\\\\,\\/,\\:,\\*,\\?,\\\",\\<,\\>,\\|]")] + private static partial Regex FileSystemSafe(); + private readonly long _Ticks; private readonly Serilog.ILogger? _Log; private readonly Configuration? _Configuration; @@ -21,7 +24,6 @@ public class MapLogic : Shared.Models.Methods.IMapLogic private readonly List _NotMappedPersonContainers; private readonly ReadOnlyDictionary> _SkipCollection; private readonly ReadOnlyDictionary> _SkipNotSkipCollection; - private readonly ReadOnlyDictionary _PersonKeyToPersonContainer; private readonly Shared.Models.Properties.IPropertyConfiguration _PropertyConfiguration; private readonly ReadOnlyDictionary>> _IdToLocationContainers; private readonly ReadOnlyDictionary>> _IdThenWholePercentagesToPersonContainers; @@ -38,7 +40,6 @@ public class MapLogic : Shared.Models.Methods.IMapLogic List notMappedPersonContainers = new(); Dictionary> skipCollection = new(); Dictionary> skipNotSkipCollection = new(); - Dictionary personKeyToPersonContainer = new(); List> locationContainers = new(); string? rootDirectoryParent = Path.GetDirectoryName(propertyConfiguration.RootDirectory); string eDistanceContentTicksDirectory = Path.Combine(eDistanceContentDirectory, $"({ticks})"); @@ -76,13 +77,12 @@ public class MapLogic : Shared.Models.Methods.IMapLogic ReadOnlyCollection personKeyFormattedIdThenWholePercentagesCollection = Stateless.MapLogic.GetPersonKeyFormattedIdThenWholePercentages(configuration, ticks, records); int unableToMatchCount = records.Count - personKeyFormattedIdThenWholePercentagesCollection.Count; if (lossCount != 0 || unableToMatchCount != 0) - { if (lossCount != 0 || unableToMatchCount != 0) { } - } // { Dictionary personKeyToCount = new(); + Dictionary personKeyToPersonContainer = new(); Dictionary personKeyFormattedToPersonContainer = new(); Dictionary> personKeyToPersonContainerCollection = new(); List<(Stateless.MapLogic.PersonKeyFormattedIdThenWholePercentages, PersonContainer)> possiblyNewPersonDisplayDirectoryNamesAndPersonContainer = new(); @@ -98,12 +98,12 @@ public class MapLogic : Shared.Models.Methods.IMapLogic readOnlyPersonKeyFormattedToPersonContainer = new(personKeyFormattedToPersonContainer); readOnlyPersonKeyToPersonContainerCollection = new(personKeyToPersonContainerCollection); readOnlyPossiblyNewPersonDisplayDirectoryNamesAndPersonContainer = new(possiblyNewPersonDisplayDirectoryNamesAndPersonContainer); + Stateless.MapLogic.SetPersonKeyToPersonContainer(configuration, + personContainers, + readOnlyPersonKeyToCount, + personKeyToPersonContainer, + readOnlyPersonKeyToPersonContainerCollection); } - Stateless.MapLogic.SetPersonKeyToPersonContainer(configuration, - personContainers, - readOnlyPersonKeyToCount, - personKeyToPersonContainer, - readOnlyPersonKeyToPersonContainerCollection); Stateless.MapLogic.PossiblyRebuildPersonContainers(configuration, ticks, a2PeopleSingletonDirectory, @@ -118,7 +118,6 @@ public class MapLogic : Shared.Models.Methods.IMapLogic readOnlyPersonKeyToCount)); } _PersonKeyToCount = readOnlyPersonKeyToCount; - _PersonKeyToPersonContainer = new(personKeyToPersonContainer); _EDistanceContentTicksDirectory = eDistanceContentTicksDirectory; _SkipCollection = Stateless.MapLogic.ConvertSkip(skipCollection); Stateless.MapLogic.CheckCollection(propertyConfiguration, rootDirectoryParent); @@ -159,9 +158,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic PersonBirthday personBirthday; List shouldMove = new(); foreach (KeyValuePair>> idToCollection in _IdThenWholePercentagesToPersonContainers) - { foreach (KeyValuePair> wholePercentagesToPersonContainers in idToCollection.Value) - { foreach (PersonContainer personContainer in wholePercentagesToPersonContainers.Value) { if (personContainer.Key is null || personContainer.Birthdays is null || personContainer.Birthdays.Length == 0) @@ -180,8 +177,6 @@ public class MapLogic : Shared.Models.Methods.IMapLogic continue; collection.Add(idToCollection.Key); } - } - } if (shouldMove.Count > 0) throw new Exception(string.Join(Environment.NewLine, shouldMove)); return results; @@ -227,12 +222,10 @@ public class MapLogic : Shared.Models.Methods.IMapLogic personKey = personBirthday.Value.Ticks; mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, mapping.MappingFromItem); if (locationContainersFiles is null) - { if (mapping.MappingFromPerson is null || mapping.MappingFromPerson.LocationContainersFiles.Count == 0) locationContainersFiles = new(Array.Empty()); else locationContainersFiles = mapping.MappingFromPerson.LocationContainersFiles; - } mapping.UpdateMappingFromPerson(locationContainersFiles, personContainer.ApproximateYears, personContainer.DisplayDirectoryName, personBirthday, mappingSegmentB); } } @@ -317,7 +310,6 @@ public class MapLogic : Shared.Models.Methods.IMapLogic File.SetAttributes(checkFile, FileAttributes.Hidden); } if (updated is null) - { foreach (SaveContainer saveContainer in saveContainers) { if (string.IsNullOrEmpty(saveContainer.Directory) || string.IsNullOrEmpty(saveContainer.CheckFile) || saveContainer.ResizedFileHolder is null || !saveContainer.ResizedFileHolder.Exists) @@ -330,7 +322,6 @@ public class MapLogic : Shared.Models.Methods.IMapLogic if (saveContainer.MakeAllHidden) File.SetAttributes(checkFile, FileAttributes.Hidden); } - } foreach (SaveContainer saveContainer in saveContainers) { if (string.IsNullOrEmpty(saveContainer.Directory) || string.IsNullOrEmpty(saveContainer.ShortcutFile) || saveContainer.ResizedFileHolder is null || !saveContainer.ResizedFileHolder.Exists) @@ -524,26 +515,24 @@ public class MapLogic : Shared.Models.Methods.IMapLogic saveContainer = new(checkFile, directory, faceFileHolder); } else - { if (saveIndividually) - { - facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.MappingFromItem); - facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}")); - (saveContainer, SaveContainer? extraSaveContainer) = Stateless.MapLogic.GetContainers(_Configuration.FacesFileNameExtension, _Configuration.FacePartsFileNameExtension, directory, faceFileHolder, facePartsFileHolder, mapping); - if (extraSaveContainer is not null) - results.Add(extraSaveContainer); - } - else - { - facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.MappingFromItem); - shortcutFile = Path.Combine(personDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.lnk"); - checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}"); - hiddenFaceFileHolder = new(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}")); - facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}")); - saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, mapping.MappingFromItem.ResizedFileHolder, shortcutFile); - if (!isByMapping && mapping.By is not null && mapping.MappingFromPerson?.LocationContainersFiles.Count > 0 && IPerson.IsDefaultName(mapping.MappingFromPerson)) - results.Add(new(Path.GetDirectoryName(personDirectory) ?? personDirectory, mapping.MappingFromPerson.LocationContainersFiles[0])); - } + { + facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.MappingFromItem); + facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}")); + (saveContainer, SaveContainer? extraSaveContainer) = Stateless.MapLogic.GetContainers(_Configuration.FacesFileNameExtension, _Configuration.FacePartsFileNameExtension, directory, faceFileHolder, facePartsFileHolder, mapping); + if (extraSaveContainer is not null) + results.Add(extraSaveContainer); + } + else + { + facePartsDirectory = Stateless.MapLogic.GetFacePartsDirectory(_PropertyConfiguration, d2FacePartsContentDirectory, mapping.MappingFromItem); + shortcutFile = Path.Combine(personDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}.lnk"); + checkFile = Path.Combine(directory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}"); + hiddenFaceFileHolder = new(Path.Combine(facesDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacesHiddenFileNameExtension}")); + facePartsFileHolder = new(Path.Combine(facePartsDirectory, $"{mapping.MappingFromLocation.DeterministicHashCodeKey}{mapping.MappingFromItem.ImageFileHolder.ExtensionLowered}{_Configuration.FacePartsFileNameExtension}")); + saveContainer = new(checkFile, directory, faceFileHolder, hiddenFaceFileHolder, facePartsFileHolder, mapping.MappingFromItem.ResizedFileHolder, shortcutFile); + if (!isByMapping && mapping.By is not null && mapping.MappingFromPerson?.LocationContainersFiles.Count > 0 && IPerson.IsDefaultName(mapping.MappingFromPerson)) + results.Add(new(Path.GetDirectoryName(personDirectory) ?? personDirectory, mapping.MappingFromPerson.LocationContainersFiles[0])); } results.Add(saveContainer); if (!isBySorting || mapping.SortingContainer is null || keyMapping is null) @@ -939,7 +928,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic if (!string.IsNullOrEmpty(mapping.MappingFromItem.Model) && !string.IsNullOrEmpty(mapping.MappingFromItem.Model.Trim())) { // Remove-Item -LiteralPath "\\?\D:\Tmp\a\EX-Z70 " - directory = Path.Combine($"{eDistanceContentDirectory}---", "Model Shortcuts", Regex.Replace(mapping.MappingFromItem.Model.Trim(), @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]", "_"), directoryName); + directory = Path.Combine($"{eDistanceContentDirectory}---", "Model Shortcuts", FileSystemSafe().Replace(mapping.MappingFromItem.Model.Trim(), "_"), directoryName); fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}.lnk"); results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, dateTime, fileName, description, MakeAllHidden: false)); } @@ -1152,13 +1141,9 @@ public class MapLogic : Shared.Models.Methods.IMapLogic ReadOnlyCollection? personContainers; result = _SkipCollection.TryGetValue(id, out wholePercentagesCollection) && wholePercentagesCollection.Contains(wholePercentages); if (!result && wholePercentagesToPersonContainers is not null) - { if (wholePercentagesToPersonContainers.TryGetValue(wholePercentages, out personContainers)) - { if (!ignoreXMatches || !personContainers.Any(l => IPerson.IsDefaultName(l))) result = true; - } - } return result; } @@ -1229,7 +1214,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic foreach (string directory in directories) { directoryName = Path.GetFileName(directory); - if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4)) + if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4) continue; Stateless.MapLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName); } @@ -1237,7 +1222,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic foreach (string directory in directories) { directoryName = Path.GetFileName(directory); - if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4)) + if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4) continue; Stateless.MapLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName); } @@ -1245,7 +1230,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic foreach (string directory in directories) { directoryName = Path.GetFileName(directory); - if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4)) + if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4) continue; Stateless.MapLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName); } diff --git a/Map/Models/Stateless/MapLogic.cs b/Map/Models/Stateless/MapLogic.cs index 4251b3f..3c1fc86 100644 --- a/Map/Models/Stateless/MapLogic.cs +++ b/Map/Models/Stateless/MapLogic.cs @@ -820,7 +820,7 @@ internal abstract class MapLogic results.Add(new(ticksDirectory, ticksDirectoryName, new(directoryTicks), new DateTime(directoryDateTime.Year, directoryDateTime.Month, directoryDateTime.Day + 1), totalDays)); lastDirectoryTicks = directoryTicks; } - string[] compare = (from l in results where l.TotalDays is not null and < 3.95f select l.Directory).ToArray(); + string[] compare = (from l in results where l.DirectoryDateTime.Second != 0 && l.TotalDays is not null and < 3.95f select l.Directory).ToArray(); if (compare.Length > 0) throw new Exception($"Please Consolidate <{string.Join(Environment.NewLine, compare)}>"); return results; diff --git a/Metadata-Query/MetadataQuery.cs b/Metadata-Query/MetadataQuery.cs index 7f36eb5..0ec4cee 100644 --- a/Metadata-Query/MetadataQuery.cs +++ b/Metadata-Query/MetadataQuery.cs @@ -65,11 +65,12 @@ public class MetadataQuery string fileName; ProgressBar progressBar; const string fileSearchFilter = "*"; + const bool useCeilingAverage = true; const string directorySearchFilter = "*"; Dictionary>>? dictionary; List<(string FileName, string Count, string TagGroup, string TagIdName, string Value)> collection = new(); ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; - List filesCollection = Shared.Models.Stateless.Methods.IDirectory.GetFilesCollection(_PropertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter); + List filesCollection = Shared.Models.Stateless.Methods.IDirectory.GetFilesCollection(_PropertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage); foreach (string[] files in filesCollection) { if (!files.Any()) diff --git a/Mirror-Length/MirrorLength.cs b/Mirror-Length/MirrorLength.cs index cad6380..446a22a 100644 --- a/Mirror-Length/MirrorLength.cs +++ b/Mirror-Length/MirrorLength.cs @@ -207,9 +207,10 @@ public class MirrorLength if (!collectionForMarkDown.Any()) { ProgressBar progressBar; + const bool useCeilingAverage = true; const string fileSearchFilter = "*"; const string directorySearchFilter = "*"; - List filesCollection = Shared.Models.Stateless.Methods.IDirectory.GetFilesCollection(_PropertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter); + List filesCollection = Shared.Models.Stateless.Methods.IDirectory.GetFilesCollection(_PropertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage); ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; progressBar = new(filesCollection.Count, message, options); List<(string, string, DateTime, long)[]> collection = GetToDoCollection(progressBar, filesCollection); diff --git a/Property/Models/A_Property.cs b/Property/Models/A_Property.cs index 9d01508..4108f8e 100644 --- a/Property/Models/A_Property.cs +++ b/Property/Models/A_Property.cs @@ -23,7 +23,6 @@ public class A_Property private readonly List _AngleBracketCollection; private readonly IPropertyConfiguration _PropertyConfiguration; private readonly IReadOnlyDictionary _FileGroups; - private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions; public A_Property(int maxDegreeOfParallelism, Configuration propertyConfiguration, string outputExtension, bool reverse, string aResultsFullGroupDirectory) { @@ -36,7 +35,6 @@ public class A_Property _AngleBracketCollection = new List(); _PropertyConfiguration = propertyConfiguration; _MaxDegreeOfParallelism = maxDegreeOfParallelism; - _WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true }; _FileGroups = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(propertyConfiguration, aResultsFullGroupDirectory, new string[] { propertyConfiguration.ResultSingleton }); } @@ -150,7 +148,7 @@ public class A_Property { id ??= item.ImageFileHolder.Id; (_, _, result) = Stateless.Property.GetProperty(populateId, metadata, item.ImageFileHolder, result, isIgnoreExtension, item.IsValidImageFormatExtension, id, _ASCIIEncoding); - json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions); + json = JsonSerializer.Serialize(result, PropertyGenerationContext.Default.Property); if (populateId && Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true)) { File.SetCreationTime(fileInfo.FullName, result.LastWriteTime); @@ -166,7 +164,7 @@ public class A_Property } else if (hasWrongYearProperty) { - json = JsonSerializer.Serialize(result, _WriteIndentedJsonSerializerOptions); + json = JsonSerializer.Serialize(result, PropertyGenerationContext.Default.Property); if (Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches: true, compareBeforeWrite: true)) { File.SetCreationTime(fileInfo.FullName, result.LastWriteTime); diff --git a/Property/Models/Stateless/Property.cs b/Property/Models/Stateless/Property.cs index de4c435..990747e 100644 --- a/Property/Models/Stateless/Property.cs +++ b/Property/Models/Stateless/Property.cs @@ -213,9 +213,9 @@ internal class Property string? model = null; DateTime?[] dateTimes; string dateTimeFormat; - string[]? tags = null; DateTime checkDateTime; DateTime? dateTime = null; + string[]? keywords = null; PropertyItem? propertyItem; string? orientation = null; DateTime? gpsDateStamp = null; @@ -341,9 +341,9 @@ internal class Property if (propertyItem?.Value is not null) { if (propertyItem.Type == 2) - tags = asciiEncoding.GetString(propertyItem.Value).Trim('\0', ' ').Split(';'); + keywords = asciiEncoding.GetString(propertyItem.Value).Trim('\0', ' ').Split(';'); else if (propertyItem.Type == 1) - tags = Encoding.Unicode.GetString(propertyItem.Value).Trim('\0', ' ').Split(';'); + keywords = Encoding.Unicode.GetString(propertyItem.Value).Trim('\0', ' ').Split(';'); } } message = null; @@ -381,9 +381,9 @@ internal class Property if (fileHolder.LastWriteTime is null && property?.LastWriteTime is null) throw new NullReferenceException(nameof(fileHolder.LastWriteTime)); if (fileHolder.CreationTime is not null && fileHolder.LastWriteTime is not null) - result = new(fileHolder.CreationTime.Value, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginalByLogic, fileLength, gpsDateStamp, height, id, fileHolder.LastWriteTime.Value, make, model, orientation, tags, width); + result = new(fileHolder.CreationTime.Value, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginalByLogic, fileLength, gpsDateStamp, height, id, keywords, fileHolder.LastWriteTime.Value, make, model, orientation, width); else if (property is not null) - result = new(property.CreationTime, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginalByLogic, fileLength, gpsDateStamp, height, id, property.LastWriteTime, make, model, orientation, tags, width); + result = new(property.CreationTime, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginalByLogic, fileLength, gpsDateStamp, height, id, keywords, property.LastWriteTime, make, model, orientation, width); else throw new NullReferenceException(nameof(property)); return (message, dateTimesByLogic.ToArray(), result); diff --git a/Rename/Rename.cs b/Rename/Rename.cs index 3dd1b16..ad991bf 100644 --- a/Rename/Rename.cs +++ b/Rename/Rename.cs @@ -346,13 +346,14 @@ public class Rename List records = new(); const string fileSearchFilter = "*"; int offset = IDirectory.GetOffset(); + const bool useCeilingAverage = false; const string directorySearchFilter = "*"; List distinctDirectories = new(); B_Metadata metadata = new(_PropertyConfiguration); List<(FileHolder, string, string)> toDoCollection = new(); List<(FileHolder, string)> verifiedToDoCollection = new(); ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; - List filesCollection = IDirectory.GetFilesCollection(_PropertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter); + List filesCollection = IDirectory.GetFilesCollection(_PropertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage); int count = filesCollection.Select(l => l.Length).Sum(); foreach (string[] files in filesCollection) { diff --git a/Set-Created-Date/SetCreatedDate.cs b/Set-Created-Date/SetCreatedDate.cs index c4b5ff4..887fe60 100644 --- a/Set-Created-Date/SetCreatedDate.cs +++ b/Set-Created-Date/SetCreatedDate.cs @@ -145,10 +145,11 @@ public class SetCreatedDate List results = new(); ProgressBar progressBar; ConsoleKey? consoleKey = null; + const bool useCeilingAverage = true; const string fileSearchFilter = "*"; string message = nameof(SetCreatedDate); const string directorySearchFilter = "*"; - List filesCollection = Shared.Models.Stateless.Methods.IDirectory.GetFilesCollection(_PropertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter); + List filesCollection = Shared.Models.Stateless.Methods.IDirectory.GetFilesCollection(_PropertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage); int count = filesCollection.Select(l => l.Length).Sum(); ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; progressBar = new(count, message, options); diff --git a/Shared/Models/MappingFromFilter.cs b/Shared/Models/MappingFromFilter.cs index 7acf4f3..781a4b5 100644 --- a/Shared/Models/MappingFromFilter.cs +++ b/Shared/Models/MappingFromFilter.cs @@ -3,29 +3,23 @@ using System.Text.Json.Serialization; namespace View_by_Distance.Shared.Models; -public class MappingFromFilter : Properties.IMappingFromFilter +public record MappingFromFilter(bool? IsFocusModel, + bool? IsFocusPerson, + bool? IsFocusRelativePath, + bool? InSkipCollection, + bool? IsUsed) { - public bool? IsFocusModel { init; get; } - public bool? IsFocusPerson { init; get; } - public bool? IsFocusRelativePath { init; get; } - public bool? InSkipCollection { init; get; } - public bool? IsUsed { init; get; } - - [JsonConstructor] - public MappingFromFilter(bool? isFocusModel, bool? isFocusPerson, bool? isFocusRelativePath, bool? inSkipCollection, bool? isUsed) - { - IsFocusModel = isFocusModel; - IsFocusPerson = isFocusPerson; - IsFocusRelativePath = isFocusRelativePath; - InSkipCollection = inSkipCollection; - IsUsed = isUsed; - } - public override string ToString() { - string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); + string result = JsonSerializer.Serialize(this, MappingFromFilterGenerationContext.Default.MappingFromFilter); return result; } +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(MappingFromFilter))] +public partial class MappingFromFilterGenerationContext : JsonSerializerContext +{ } \ No newline at end of file diff --git a/Shared/Models/MappingFromItem.cs b/Shared/Models/MappingFromItem.cs index eece6ae..a767ac1 100644 --- a/Shared/Models/MappingFromItem.cs +++ b/Shared/Models/MappingFromItem.cs @@ -3,38 +3,22 @@ using System.Text.Json.Serialization; namespace View_by_Distance.Shared.Models; -public class MappingFromItem : Properties.IMappingFromItem +public record MappingFromItem(DateTime[] ContainerDateTimes, + DateTime? DateTimeDigitized, + DateTime? DateTimeOriginal, + int Id, + FileHolder ImageFileHolder, + bool? IsWrongYear, + string[]? Keywords, + DateTime MinimumDateTime, + string? Model, + string RelativePath, + FileHolder ResizedFileHolder) { - public DateTime[] ContainerDateTimes { init; get; } - public DateTime? DateTimeDigitized { init; get; } - public DateTime? DateTimeOriginal { init; get; } - public int Id { init; get; } - public FileHolder ImageFileHolder { init; get; } - public bool? IsWrongYear { init; get; } - public DateTime MinimumDateTime { init; get; } - public string? Model { init; get; } - public string RelativePath { init; get; } - public FileHolder ResizedFileHolder { init; get; } - - [JsonConstructor] - public MappingFromItem(DateTime[] containerDateTimes, DateTime? dateTimeDigitized, DateTime? dateTimeOriginal, int id, FileHolder imageFileHolder, bool? isWrongYear, DateTime minimumDateTime, string? model, string relativePath, FileHolder resizedFileHolder) - { - ContainerDateTimes = containerDateTimes; - DateTimeDigitized = dateTimeDigitized; - DateTimeOriginal = dateTimeOriginal; - Id = id; - ImageFileHolder = imageFileHolder; - IsWrongYear = isWrongYear; - MinimumDateTime = minimumDateTime; - Model = model; - RelativePath = relativePath; - ResizedFileHolder = resizedFileHolder; - } - public override string ToString() { - string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); + string result = JsonSerializer.Serialize(this, MappingFromItemGenerationContext.Default.MappingFromItem); return result; } @@ -51,8 +35,14 @@ public class MappingFromItem : Properties.IMappingFromItem List dateTimes = item.Property.GetDateTimes(); DateTime minimumDateTime = Stateless.Methods.IProperty.GetMinimumDateTime(item.Property); (bool? isWrongYear, _) = Stateless.Methods.IProperty.IsWrongYear(item.ImageFileHolder, item.Property.DateTimeOriginal, dateTimes); - result = new(containerDateTimes, item.Property.DateTimeDigitized, item.Property.DateTimeOriginal, item.Property.Id.Value, item.ImageFileHolder, isWrongYear, minimumDateTime, item.Property.Model, item.RelativePath, resizedFileHolder); + result = new(containerDateTimes, item.Property.DateTimeDigitized, item.Property.DateTimeOriginal, item.Property.Id.Value, item.ImageFileHolder, isWrongYear, item.Property.Keywords, minimumDateTime, item.Property.Model, item.RelativePath, resizedFileHolder); return result; } +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(MappingFromItem))] +public partial class MappingFromItemGenerationContext : JsonSerializerContext +{ } \ No newline at end of file diff --git a/Shared/Models/MappingFromLocation.cs b/Shared/Models/MappingFromLocation.cs index 60f72df..275eabc 100644 --- a/Shared/Models/MappingFromLocation.cs +++ b/Shared/Models/MappingFromLocation.cs @@ -3,31 +3,24 @@ using System.Text.Json.Serialization; namespace View_by_Distance.Shared.Models; -public class MappingFromLocation : Properties.IMappingFromLocation +public record MappingFromLocation(int AreaPermyriad, + int ConfidencePercent, + string DeterministicHashCodeKey, + int? Eyeα, + bool? EyeReview, + int WholePercentages) { - public int AreaPermyriad { init; get; } - public int ConfidencePercent { init; get; } - public string DeterministicHashCodeKey { init; get; } - public int? Eyeα { init; get; } - public bool? EyeReview { init; get; } - public int WholePercentages { init; get; } - - [JsonConstructor] - public MappingFromLocation(int areaPermyriad, int confidencePercent, string deterministicHashCodeKey, int? eyeα, bool? eyeReview, int wholePercentages) - { - AreaPermyriad = areaPermyriad; - ConfidencePercent = confidencePercent; - DeterministicHashCodeKey = deterministicHashCodeKey; - Eyeα = eyeα; - EyeReview = eyeReview; - WholePercentages = wholePercentages; - } - public override string ToString() { - string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); + string result = JsonSerializer.Serialize(this, MappingFromLocationGenerationContext.Default.MappingFromLocation); return result; } +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(MappingFromLocation))] +public partial class MappingFromLocationGenerationContext : JsonSerializerContext +{ } \ No newline at end of file diff --git a/Shared/Models/MappingFromPerson.cs b/Shared/Models/MappingFromPerson.cs index fd72d27..2606220 100644 --- a/Shared/Models/MappingFromPerson.cs +++ b/Shared/Models/MappingFromPerson.cs @@ -4,29 +4,23 @@ using System.Text.Json.Serialization; namespace View_by_Distance.Shared.Models; -public class MappingFromPerson : Properties.IMappingFromPerson +public record MappingFromPerson(int? ApproximateYears, + string DisplayDirectoryName, + ReadOnlyCollection LocationContainersFiles, + PersonBirthday PersonBirthday, + string SegmentB) { - public int? ApproximateYears { init; get; } - public string DisplayDirectoryName { init; get; } - public ReadOnlyCollection LocationContainersFiles { init; get; } - public PersonBirthday PersonBirthday { init; get; } - public string SegmentB { init; get; } - - [JsonConstructor] - public MappingFromPerson(int? approximateYears, string displayDirectoryName, ReadOnlyCollection locationContainersFiles, PersonBirthday personBirthday, string segmentB) - { - ApproximateYears = approximateYears; - DisplayDirectoryName = displayDirectoryName; - LocationContainersFiles = locationContainersFiles; - PersonBirthday = personBirthday; - SegmentB = segmentB; - } - public override string ToString() { - string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); + string result = JsonSerializer.Serialize(this, MappingFromPersonGenerationContext.Default.MappingFromPerson); return result; } +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(MappingFromPerson))] +public partial class MappingFromPersonGenerationContext : JsonSerializerContext +{ } \ No newline at end of file diff --git a/Shared/Models/MappingFromPhotoPrism.cs b/Shared/Models/MappingFromPhotoPrism.cs index 8ab4468..ea10edc 100644 --- a/Shared/Models/MappingFromPhotoPrism.cs +++ b/Shared/Models/MappingFromPhotoPrism.cs @@ -1,18 +1,22 @@ +using System.Text.Json; using System.Text.Json.Serialization; namespace View_by_Distance.Shared.Models; -public class MappingFromPhotoPrism : Properties.IMappingFromPhotoPrism +public record MappingFromPhotoPrism(DatabaseFile DatabaseFile, + List Markers) { - public DatabaseFile DatabaseFile { init; get; } - public List Markers { init; get; } - - [JsonConstructor] - public MappingFromPhotoPrism(DatabaseFile databaseFile, List markers) + public override string ToString() { - DatabaseFile = databaseFile; - Markers = markers; + string result = JsonSerializer.Serialize(this, MappingFromPhotoPrismGenerationContext.Default.MappingFromPhotoPrism); + return result; } +} + +[JsonSourceGenerationOptions(WriteIndented = true)] +[JsonSerializable(typeof(MappingFromPhotoPrism))] +public partial class MappingFromPhotoPrismGenerationContext : JsonSerializerContext +{ } \ No newline at end of file diff --git a/Shared/Models/Properties/IMappingFromFilter.cs b/Shared/Models/Properties/IMappingFromFilter.cs deleted file mode 100644 index 2a6ab3b..0000000 --- a/Shared/Models/Properties/IMappingFromFilter.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace View_by_Distance.Shared.Models.Properties; - -public interface IMappingFromFilter -{ - - public bool? IsFocusModel { init; get; } - public bool? IsFocusPerson { init; get; } - public bool? IsFocusRelativePath { init; get; } - public bool? InSkipCollection { init; get; } - public bool? IsUsed { init; get; } - -} \ No newline at end of file diff --git a/Shared/Models/Properties/IMappingFromItem.cs b/Shared/Models/Properties/IMappingFromItem.cs deleted file mode 100644 index cf109e1..0000000 --- a/Shared/Models/Properties/IMappingFromItem.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace View_by_Distance.Shared.Models.Properties; - -public interface IMappingFromItem -{ - - public DateTime[] ContainerDateTimes { init; get; } - public DateTime? DateTimeDigitized { init; get; } - public DateTime? DateTimeOriginal { init; get; } - public int Id { init; get; } - public FileHolder ImageFileHolder { init; get; } - public bool? IsWrongYear { init; get; } - public DateTime MinimumDateTime { init; get; } - public string? Model { init; get; } - public string RelativePath { init; get; } - public FileHolder ResizedFileHolder { init; get; } - -} \ No newline at end of file diff --git a/Shared/Models/Properties/IMappingFromLocation.cs b/Shared/Models/Properties/IMappingFromLocation.cs deleted file mode 100644 index a7e8af7..0000000 --- a/Shared/Models/Properties/IMappingFromLocation.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace View_by_Distance.Shared.Models.Properties; - -public interface IMappingFromLocation -{ - - public int AreaPermyriad { init; get; } - public int ConfidencePercent { init; get; } - public string DeterministicHashCodeKey { init; get; } - public int? Eyeα { init; get; } - public bool? EyeReview { init; get; } - public int WholePercentages { init; get; } - -} \ No newline at end of file diff --git a/Shared/Models/Properties/IMappingFromPerson.cs b/Shared/Models/Properties/IMappingFromPerson.cs deleted file mode 100644 index 4e9c718..0000000 --- a/Shared/Models/Properties/IMappingFromPerson.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Collections.ObjectModel; - -namespace View_by_Distance.Shared.Models.Properties; - -public interface IMappingFromPerson -{ - - public int? ApproximateYears { init; get; } - public string DisplayDirectoryName { init; get; } - public ReadOnlyCollection LocationContainersFiles { init; get; } - public PersonBirthday PersonBirthday { init; get; } - public string SegmentB { init; get; } - -} \ No newline at end of file diff --git a/Shared/Models/Properties/IMappingFromPhotoPrism.cs b/Shared/Models/Properties/IMappingFromPhotoPrism.cs deleted file mode 100644 index 958f79f..0000000 --- a/Shared/Models/Properties/IMappingFromPhotoPrism.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace View_by_Distance.Shared.Models.Properties; - -public interface IMappingFromPhotoPrism -{ - - public DatabaseFile DatabaseFile { init; get; } - public List Markers { init; get; } - -} \ No newline at end of file diff --git a/Shared/Models/Property.cs b/Shared/Models/Property.cs index c827227..bc423c9 100644 --- a/Shared/Models/Property.cs +++ b/Shared/Models/Property.cs @@ -12,11 +12,11 @@ public record Property(DateTime CreationTime, DateTime? GPSDateStamp, int? Height, int? Id, + string[]? Keywords, DateTime LastWriteTime, string? Make, string? Model, string? Orientation, - string[]? Tags, int? Width) { @@ -32,6 +32,6 @@ public record Property(DateTime CreationTime, [JsonSourceGenerationOptions(WriteIndented = true)] [JsonSerializable(typeof(Property))] -internal partial class PropertyGenerationContext : JsonSerializerContext +public partial class PropertyGenerationContext : JsonSerializerContext { } \ No newline at end of file diff --git a/Shared/Models/Stateless/Methods/Container.cs b/Shared/Models/Stateless/Methods/Container.cs index 57577d4..78df7bc 100644 --- a/Shared/Models/Stateless/Methods/Container.cs +++ b/Shared/Models/Stateless/Methods/Container.cs @@ -38,26 +38,10 @@ internal abstract class Container return results.ToArray(); } - internal static Models.Container[] SortContainers(bool argZeroIsConfigurationRootDirectory, string argZero, Models.Container[] containers) - { - List results = new(); - for (int i = 1; i < 3; i++) - { - foreach (Models.Container container in containers) - { - if (container.Items.Count == 0) - continue; - if (!argZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero)) - continue; - results.Add(container); - } - } - return results.ToArray(); - } - internal static List GetFilePairs(Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string extension, string aPropertySingletonDirectory, List filesCollection) { int renamed; + const bool useCeilingAverage = true; List? filePairs = null; List? jsonFilesCollection = null; IReadOnlyDictionary>? compareFileNamesToFiles = null; @@ -65,7 +49,7 @@ internal abstract class Container for (int i = 0; i < int.MaxValue; i++) { renamed = 0; - jsonFilesCollection = IDirectory.GetFilesCollection(aPropertySingletonDirectory, directorySearchFilter, extension); + jsonFilesCollection = IDirectory.GetFilesCollection(aPropertySingletonDirectory, directorySearchFilter, extension, useCeilingAverage); compareFileNamesToFiles = IDirectory.GetFilesKeyValuePairs(jsonFilesCollection); renamed += IDirectory.LookForAbandoned(jsonFilesCollection, fileNamesToFiles, extension); filePairs = IDirectory.GetFiles(filesCollection, fileNamesToFiles, extension, compareFileNamesToFiles); @@ -197,9 +181,10 @@ internal abstract class Container { int count; Models.Container[] results; + const bool useCeilingAverage = true; const string fileSearchFilter = "*"; const string directorySearchFilter = "*"; - List filesCollection = IDirectory.GetFilesCollection(propertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter); + List filesCollection = IDirectory.GetFilesCollection(propertyConfiguration.RootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage); (count, results) = GetContainers(propertyConfiguration, aPropertySingletonDirectory, directorySearchFilter, filesCollection); return (count, results); } diff --git a/Shared/Models/Stateless/Methods/IContainer.cs b/Shared/Models/Stateless/Methods/IContainer.cs index 095d5d0..fea54da 100644 --- a/Shared/Models/Stateless/Methods/IContainer.cs +++ b/Shared/Models/Stateless/Methods/IContainer.cs @@ -15,11 +15,6 @@ public interface IContainer static Models.Item[] GetFilterItems(Properties.IPropertyConfiguration propertyConfiguration, Models.Container container) => Container.GetFilterItems(propertyConfiguration, container); - Models.Container[] TestStatic_SortContainers(bool argZeroIsConfigurationRootDirectory, string argZero, Models.Container[] containers) => - SortContainers(argZeroIsConfigurationRootDirectory, argZero, containers); - static Models.Container[] SortContainers(bool argZeroIsConfigurationRootDirectory, string argZero, Models.Container[] containers) => - Container.SortContainers(argZeroIsConfigurationRootDirectory, argZero, containers); - List TestStatic_GetFilePairs(Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string extension, string aPropertySingletonDirectory, List filesCollection) => Container.GetFilePairs(propertyConfiguration, directorySearchFilter, extension, aPropertySingletonDirectory, filesCollection); static List GetFilePairs(Properties.IPropertyConfiguration propertyConfiguration, string directorySearchFilter, string extension, string aPropertySingletonDirectory, List filesCollection) => diff --git a/Shared/Models/Stateless/Methods/IDirectory.cs b/Shared/Models/Stateless/Methods/IDirectory.cs index aa1df22..67c2e12 100644 --- a/Shared/Models/Stateless/Methods/IDirectory.cs +++ b/Shared/Models/Stateless/Methods/IDirectory.cs @@ -39,10 +39,10 @@ public interface IDirectory static bool NameWithoutExtensionIsPaddedIdFormat(Models.FileHolder fileHolder, int sortOrderOnlyLengthIndex) => NameWithoutExtensionIsPaddedIdFormat(fileHolder.NameWithoutExtension, sortOrderOnlyLengthIndex); - List TestStatic_GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter) => - GetFilesCollection(directory, directorySearchFilter, fileSearchFilter); - static List GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter) => - XDirectory.GetFilesCollection(directory, directorySearchFilter, fileSearchFilter); + List TestStatic_GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter, bool useCeilingAverage) => + GetFilesCollection(directory, directorySearchFilter, fileSearchFilter, useCeilingAverage); + static List GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter, bool useCeilingAverage) => + XDirectory.GetFilesCollection(directory, directorySearchFilter, fileSearchFilter, useCeilingAverage); IReadOnlyDictionary> TestStatic_GetFilesKeyValuePairs(List filesCollection) => GetFilesKeyValuePairs(filesCollection); diff --git a/Shared/Models/Stateless/Methods/XDirectory.cs b/Shared/Models/Stateless/Methods/XDirectory.cs index 6da3463..af16d46 100644 --- a/Shared/Models/Stateless/Methods/XDirectory.cs +++ b/Shared/Models/Stateless/Methods/XDirectory.cs @@ -30,7 +30,7 @@ internal abstract partial class XDirectory return results; } - internal static List GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter) + internal static List GetFilesCollection(string directory, string directorySearchFilter, string fileSearchFilter, bool useCeilingAverage) { List results = new(); if (!fileSearchFilter.Contains('*')) @@ -47,7 +47,8 @@ internal abstract partial class XDirectory { continue; } } int ceilingAverage = directory[^1] == '_' || !results.Any() ? 0 : GetCeilingAverage(results); - results = GetFilesCollection(results, ceilingAverage); + if (useCeilingAverage) + results = GetFilesCollection(results, ceilingAverage); return results; }