diff --git a/Date-Group/DateGroup.cs b/Date-Group/DateGroup.cs index 190b892..3c1adc8 100644 --- a/Date-Group/DateGroup.cs +++ b/Date-Group/DateGroup.cs @@ -4,6 +4,7 @@ using System.Globalization; using System.Text; using View_by_Distance.Date.Group.Models; using View_by_Distance.Property.Models; +using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models.Methods; using WindowsShortcutFactory; @@ -58,7 +59,7 @@ public class DateGroup _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(propertyConfiguration.RootDirectory); if (true || appSettings.MaxDegreeOfParallelism < 2) ticks = LogDelta(ticks, nameof(Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories)); - (int j, int f, int t, Shared.Models.Container[] containers) = Property.Models.Stateless.Container.GetContainers(propertyConfiguration, propertyLogic); + (int j, int f, int t, Container[] containers) = Property.Models.Stateless.Container.GetContainers(propertyConfiguration, propertyLogic); if (propertyLogic.ExceptionsDirectories.Any()) throw new Exception(); if (propertyConfiguration.PopulatePropertyId && (configuration.ByCreateDateShortcut.Value || configuration.ByHash.Value) && Shared.Models.Stateless.Methods.IProperty.Any(containers)) @@ -144,9 +145,9 @@ public class DateGroup return result; } - private List<(long MinimumDateTimeTicks, string Source, string[] Destination)> GetMoveFileCollection(string destinationDirectory, string topDirectory, Shared.Models.Item[] filteredItems) + private List<(Item Item, long LastWriteTimeTicks, long MinimumDateTimeTicks, string[] Destination)> GetMoveFileCollection(string destinationDirectory, string topDirectory, Item[] filteredItems) { - List<(long MinimumDateTimeTicks, string Source, string[] Destination)> results = new(); + List<(Item Item, long LastWriteTimeTicks, long MinimumDateTimeTicks, string[] Destination)> results = new(); if (_Configuration.ByCreateDateShortcut is null) throw new NullReferenceException(nameof(_Configuration.ByCreateDateShortcut)); if (_Configuration.ByDay is null) @@ -214,9 +215,9 @@ public class DateGroup } if (matches is null) matches = Array.Empty(); - foreach (Shared.Models.Item item in filteredItems) + foreach (Item item in filteredItems) { - if (item.Property?.Id is null || item.ImageFileHolder is null) + if (item.ImageFileHolder is null || item.Property is null || (_Configuration.PropertyConfiguration.PopulatePropertyId && item.Property.Id is null)) continue; directoryNames.Clear(); destinationCollection = new(); @@ -224,12 +225,17 @@ public class DateGroup minimumDateTime = Shared.Models.Stateless.Methods.IProperty.GetMinimumDateTime(item.Property); day = minimumDateTime.Value.ToString("MM-dd"); month = minimumDateTime.Value.ToString("MMMM"); - (isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder, minimumDateTime); - if (isWrongYear is null) + if (item.Property.Id is null) + { flag = '#'; + isWrongYear = null; + } else { - if (isWrongYear.Value) + (isWrongYear, _) = item.Property.IsWrongYear(item.ImageFileHolder, minimumDateTime); + if (isWrongYear is null) + flag = '#'; + else if (isWrongYear.Value) flag = '~'; else { @@ -265,7 +271,7 @@ public class DateGroup { _ = destinationDirectoryName.Append(topDirectoryName); if (_Configuration.BySeason.Value) - directoryNames.AddRange(new string[] { $"{destinationDirectoryName} {year}", $"{year} {seasonName}" }); + directoryNames.AddRange(new string[] { $"{destinationDirectoryName} {year} {seasonName}" }); else if (_Configuration.ByDay.Value) directoryNames.AddRange(new string[] { $"{destinationDirectoryName} {year}", $"{weekOfYear}) {year}-{day}" }); else if (_Configuration.ByWeek.Value) @@ -299,7 +305,7 @@ public class DateGroup destinationCollection.Add(destinationDirectory); destinationCollection.AddRange(directoryNames); destinationCollection.Add(fileName); - results.Add(new(minimumDateTime.Value.Ticks, item.ImageFileHolder.FullName, destinationCollection.ToArray())); + results.Add(new(item, item.Property.LastWriteTime.Ticks, minimumDateTime.Value.Ticks, destinationCollection.ToArray())); } return results; } @@ -313,10 +319,10 @@ public class DateGroup return result; } - private static Shared.Models.Item[] GetFilterItems(Shared.Models.Container container) + private static Item[] GetFilterItems(Container container) { - List results = new(); - foreach (Shared.Models.Item item in container.Items) + List results = new(); + foreach (Item item in container.Items) { if (item.ImageFileHolder is not null && (item.Abandoned is null || !item.Abandoned.Value) @@ -326,18 +332,18 @@ public class DateGroup return results.ToArray(); } - private (long MinimumDateTimeTicks, string Source, string[] Destination)[] GetFileMoveCollectionAll(Property.Models.Configuration configuration, Shared.Models.Container[] containers, string destinationRoot) + private (Item Item, long LastWriteTimeTicks, long MinimumDateTimeTicks, string[] Destination)[] GetFileMoveCollectionAll(Property.Models.Configuration configuration, Container[] containers, string destinationRoot) { - (long MinimumDateTimeTicks, string Source, string[] Destination)[] results; + (Item Item, long LastWriteTimeTicks, long MinimumDateTimeTicks, string[] Destination)[] results; if (_Configuration.KeepFullPath is null) throw new NullReferenceException(nameof(_Configuration.KeepFullPath)); string? topDirectory; string? checkDirectory; string destinationDirectory; - Shared.Models.Item[] filteredItems; - List<(long MinimumDateTimeTicks, string Source, string[] Destination)> fileMoveCollection = new(); - List<(long MinimumDateTimeTicks, string Source, string[] Destination)> fileMoveCollectionDirectory; - foreach (Shared.Models.Container container in containers) + Item[] filteredItems; + List<(Item Item, long LastWriteTimeTicks, long MinimumDateTimeTicks, string[] Destination)> fileMoveCollection = new(); + List<(Item Item, long LastWriteTimeTicks, long MinimumDateTimeTicks, string[] Destination)> fileMoveCollectionDirectory; + foreach (Container container in containers) { if (!container.Items.Any()) continue; @@ -363,62 +369,92 @@ public class DateGroup fileMoveCollectionDirectory = GetMoveFileCollection(destinationDirectory, topDirectory, filteredItems); fileMoveCollection.AddRange(fileMoveCollectionDirectory); } - results = (from l in fileMoveCollection orderby l.MinimumDateTimeTicks descending select l).ToArray(); + results = (from l in fileMoveCollection orderby l.MinimumDateTimeTicks descending, l.LastWriteTimeTicks descending select l).ToArray(); return results; } - private void MoveFiles(Property.Models.Configuration configuration, Shared.Models.Container[] containers) + private void MoveFiles(Property.Models.Configuration configuration, Container[] containers) { if (_Log is null) throw new NullReferenceException(nameof(_Log)); if (_Configuration.ByHash is null) throw new NullReferenceException(nameof(_Configuration.ByHash)); + bool hasDuplicate; + string fullFileName; string directoryName; - List distinct = new(); + WindowsShortcut windowsShortcut; string duplicate = "-Duplicate"; + List filesDistinct = new(); + List filesDuplicate = new(); + List directoriesDistinct = new(); string destinationRoot = Property.Models.Stateless.IResult.GetResultsGroupDirectory(configuration, "Z) Moved"); - (long MinimumDateTimeTicks, string Source, string[] Destination)[] fileMoveCollectionAll = GetFileMoveCollectionAll(configuration, containers, destinationRoot); - foreach ((long _, string source, string[] destination) in fileMoveCollectionAll) + (Item Item, long LastWriteTimeTicks, long MinimumDateTimeTicks, string[] Destination)[] fileMoveCollectionAll = GetFileMoveCollectionAll(configuration, containers, destinationRoot); + foreach ((Item item, long lastWriteTimeTicks, long minimumDateTimeTicks, string[] destination) in fileMoveCollectionAll) { - directoryName = Path.Combine(destination.Take(destination.Length - 1).ToArray()); - if (distinct.Contains(directoryName)) + if (item.ImageFileHolder is null) continue; - distinct.Add(directoryName); + fullFileName = Path.Combine(destination); + if (filesDistinct.Contains(fullFileName)) + filesDuplicate.Add(fullFileName); + filesDistinct.Add(fullFileName); + directoryName = Path.Combine(destination.Take(destination.Length - 1).ToArray()); + if (directoriesDistinct.Contains(directoryName)) + continue; + directoriesDistinct.Add(directoryName); if (!Directory.Exists(directoryName)) _ = Directory.CreateDirectory(directoryName); if (_Configuration.ByHash.Value) { - if (!Directory.Exists(string.Concat(directoryName, duplicate))) - _ = Directory.CreateDirectory(string.Concat(directoryName, duplicate)); + if (!Directory.Exists(string.Concat(directoryName, duplicate, " I"))) + _ = Directory.CreateDirectory(string.Concat(directoryName, duplicate, " I")); + if (!Directory.Exists(string.Concat(directoryName, duplicate, " II"))) + _ = Directory.CreateDirectory(string.Concat(directoryName, duplicate, " II")); } } _Log.Information("Ready to move files?"); for (int y = 0; y < int.MaxValue; y++) { _Log.Information("Press \"Y\" key to move file(s) or close console to not move files"); - if (Console.ReadKey().Key == ConsoleKey.Y) + if (System.Console.ReadKey().Key == ConsoleKey.Y) break; } _Log.Information(". . ."); int moved = 0; - string fullFileName; - foreach ((long _, string source, string[] destination) in fileMoveCollectionAll) + foreach ((Item item, long lastWriteTimeTicks, long minimumDateTimeTicks, string[] destination) in fileMoveCollectionAll) { + if (item.ImageFileHolder is null) + continue; fullFileName = Path.Combine(destination); + hasDuplicate = filesDuplicate.Contains(fullFileName); + if (hasDuplicate) + { + destination[1] = string.Concat(destination[1], duplicate, " I"); + fullFileName = Path.Combine(destination); + } if (File.Exists(fullFileName)) { if (!_Configuration.ByHash.Value) continue; else { - destination[1] = string.Concat(destination[1], duplicate); + destination[1] = string.Concat(destination[1], "I"); fullFileName = Path.Combine(destination); if (File.Exists(fullFileName)) continue; } } - File.Move(source, fullFileName); + File.Move(item.ImageFileHolder.FullName, fullFileName); moved += 1; + if (hasDuplicate) + { + try + { + windowsShortcut = new() { Path = item.ImageFileHolder.DirectoryName, Description = item.ImageFileHolder.Name }; + windowsShortcut.Save(string.Concat(fullFileName, ".lnk")); + windowsShortcut.Dispose(); + } + catch (Exception) { } + } } if (_Configuration.ByHash.Value) _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(destinationRoot); @@ -426,18 +462,20 @@ public class DateGroup for (int y = 0; y < int.MaxValue; y++) { _Log.Information("Press \"Y\" key to move file(s) back or close console to leave them moved"); - if (Console.ReadKey().Key == ConsoleKey.Y) + if (System.Console.ReadKey().Key == ConsoleKey.Y) break; } _Log.Information(". . ."); - foreach ((long _, string source, string[] destination) in fileMoveCollectionAll) + foreach ((Item item, long lastWriteTimeTicks, long minimumDateTimeTicks, string[] destination) in fileMoveCollectionAll) { + if (item.ImageFileHolder is null) + continue; fullFileName = Path.Combine(destination); - if (File.Exists(source)) + if (File.Exists(item.ImageFileHolder.FullName)) continue; if (!File.Exists(fullFileName)) continue; - File.Move(fullFileName, source); + File.Move(fullFileName, item.ImageFileHolder.FullName); moved += 1; } _Log.Information($"Done moving back {moved} file(s)"); @@ -445,7 +483,7 @@ public class DateGroup _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(configuration.RootDirectory); } - private static void CreateDateShortcut(Property.Models.Configuration configuration, Shared.Models.Container[] containers) + private static void CreateDateShortcut(Property.Models.Configuration configuration, Container[] containers) { string path; string fileName; @@ -453,14 +491,14 @@ public class DateGroup int selectedTotal; const int minimum = 3; List dateTimes; + List selectedItems; DateTime? minimumDateTime; const int maximumHours = 24; string? relativePathDirectory; WindowsShortcut windowsShortcut; TimeSpan threeStandardDeviationHigh; - List selectedItems; string aPropertyContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "()"); - foreach (Shared.Models.Container container in containers) + foreach (Container container in containers) { if (!container.Items.Any()) continue; @@ -472,7 +510,7 @@ public class DateGroup { (i, dateTimes, selectedItems) = Shared.Models.Stateless.Methods.IProperty.Get(container, threeStandardDeviationHigh, i); selectedTotal += selectedItems.Count; - foreach (Shared.Models.Item item in selectedItems) + foreach (Item item in selectedItems) { if (item.Property is null) continue; diff --git a/Drag-Drop/Program.cs b/Drag-Drop/Program.cs index 6e7a467..adb1e2d 100644 --- a/Drag-Drop/Program.cs +++ b/Drag-Drop/Program.cs @@ -75,5 +75,5 @@ static class Program } return results; } - + } \ No newline at end of file diff --git a/Instance/Models/_G_Index.cs b/Instance/Models/_G_Index.cs index e5d039d..a3b3df0 100644 --- a/Instance/Models/_G_Index.cs +++ b/Instance/Models/_G_Index.cs @@ -142,7 +142,7 @@ public class G_Index : Shared.Models.Properties.IIndex, IIndex internal void SetIndex(Property.Models.Configuration configuration, string outputResolution) { - Dictionary>> filePropertiesKeyValuePairs = new(); + Dictionary>> filePropertiesKeyValuePairs = new(); FileInfo fileInfo; G_Index indexInfo; string parentCheck; diff --git a/Property/Models/A_Property.cs b/Property/Models/A_Property.cs index fef37c0..343a99e 100644 --- a/Property/Models/A_Property.cs +++ b/Property/Models/A_Property.cs @@ -635,9 +635,18 @@ public class A_Property Shared.Models.Property result; if (item.ImageFileHolder is null) throw new NullReferenceException(nameof(item.ImageFileHolder)); + bool angleBracketCollectionAny = AngleBracketCollection.Any(); + if (!angleBracketCollectionAny) + { + if (item.ImageFileHolder.DirectoryName is null) + throw new NullReferenceException(nameof(item.ImageFileHolder.DirectoryName)); + SetAngleBracketCollection(item.ImageFileHolder.DirectoryName); + } bool isValidMetadataExtensions = _Configuration.ValidMetadataExtensions.Contains(item.ImageFileHolder.ExtensionLowered); bool isIgnoreExtension = item.ValidImageFormatExtension && _Configuration.IgnoreExtensions.Contains(item.ImageFileHolder.ExtensionLowered); result = GetPropertyOfPrivate(item, sourceDirectoryFileTuples, parseExceptions, isIgnoreExtension, isValidMetadataExtensions); + if (!angleBracketCollectionAny) + AngleBracketCollection.Clear(); return result; } diff --git a/Property/Models/Stateless/Container.cs b/Property/Models/Stateless/Container.cs index 6021ac2..7b8d1dc 100644 --- a/Property/Models/Stateless/Container.cs +++ b/Property/Models/Stateless/Container.cs @@ -147,7 +147,20 @@ public class Container return results; } - private static (int, Shared.Models.Container[]) GetContainers(Configuration configuration, string aPropertySingletonDirectory, List<(int, string, FileHolder[])> fileHolderGroupCollection, List<(int, string, List<(string, Shared.Models.Property?)>)> collectionFromJson) + private static Item GetNewItem(Configuration configuration, A_Property propertyLogic, string relativePath, FileHolder sourceDirectoryFileHolder) + { + Item result; + List parseExceptions = new(); + Shared.Models.Property? property = null; + List> subFileTuples = new(); + bool isValidImageFormatExtension = configuration.ValidImageFormatExtensions.Contains(sourceDirectoryFileHolder.ExtensionLowered); + Item item = new(sourceDirectoryFileHolder.FullName, relativePath, sourceDirectoryFileHolder, isValidImageFormatExtension, property, null, null); + property = propertyLogic.GetProperty(item, subFileTuples, parseExceptions); + result = new(sourceDirectoryFileHolder.FullName, relativePath, sourceDirectoryFileHolder, isValidImageFormatExtension, property, null, null); + return result; + } + + private static (int, Shared.Models.Container[]) GetContainers(Configuration configuration, A_Property propertyLogic, string aPropertySingletonDirectory, List<(int, string, FileHolder[])> fileHolderGroupCollection, List<(int, string, List<(string, Shared.Models.Property?)>)> collectionFromJson) { int result = 0; Shared.Models.Container[] results; @@ -235,8 +248,7 @@ public class Container throw new Exception(); if (sourceDirectoryFileHolder.ExtensionLowered is ".json") continue; - isValidImageFormatExtension = configuration.ValidImageFormatExtensions.Contains(sourceDirectoryFileHolder.ExtensionLowered); - item = new(sourceDirectoryFileHolder.FullName, relativePath, sourceDirectoryFileHolder, isValidImageFormatExtension, null, null, null); + item = GetNewItem(configuration, propertyLogic, relativePath, sourceDirectoryFileHolder); items.Add(item); } if (sourceDirectory == configuration.RootDirectory || items.Any()) @@ -275,7 +287,7 @@ public class Container (int j, jsonCollection) = GetJsonGroupCollection(configuration, propertyLogic, aPropertySingletonDirectory); (int f, fileHolderGroupCollection) = GetFileHolderGroupCollection(configuration, propertyLogic, searchPattern, topDirectories); collectionFromJson = GetCollection(aPropertySingletonDirectory, jsonCollection); - (int t, results) = GetContainers(configuration, aPropertySingletonDirectory, fileHolderGroupCollection, collectionFromJson); + (int t, results) = GetContainers(configuration, propertyLogic, aPropertySingletonDirectory, fileHolderGroupCollection, collectionFromJson); return (j, f, t, results); } diff --git a/Tests/UnitTestCalculations.cs b/Tests/UnitTestCalculations.cs index 5a6adbc..4da7ba5 100644 --- a/Tests/UnitTestCalculations.cs +++ b/Tests/UnitTestCalculations.cs @@ -206,7 +206,7 @@ public class UnitTestCalculations [TestMethod] public void TestAreaPermille() { - int faceAreaPermille=1000; + int faceAreaPermille = 1000; Location location; double confidence = 0.1D; int areaPermille, left, top, right, bottom, width, height;