From e3c951e54a1d0ff27ba4ccfbfae9f642afa45e3b Mon Sep 17 00:00:00 2001 From: Mike Phares Date: Sat, 24 Dec 2022 10:34:09 -0700 Subject: [PATCH] Delete-By-Distinct --- .vscode/launch.json | 20 +- Compare/.vscode/launch.json | 2 +- Date-Group/.vscode/launch.json | 2 +- Delete-By-Distinct/.vscode/format-report.json | 1 + Delete-By-Distinct/.vscode/launch.json | 32 +++ Delete-By-Distinct/.vscode/settings.json | 14 + Delete-By-Distinct/.vscode/tasks.json | 42 +++ Delete-By-Distinct/Delete-By-Distinct.csproj | 62 +++++ Delete-By-Distinct/DeleteByDistinct.cs | 105 ++++++++ Delete-By-Distinct/Models/AppSettings.cs | 31 +++ .../Models/Binder/AppSettings.cs | 48 ++++ .../Stateless/SerilogExtensionMethods.cs | 10 + Delete-By-Distinct/Program.cs | 70 +++++ .../appsettings.Development.json | 243 ++++++++++++++++++ Delete-By-Distinct/appsettings.json | 117 +++++++++ Delete-By-Relative/.vscode/launch.json | 4 +- Delete-By-Relative/.vscode/tasks.json | 6 +- Drag-Drop/.vscode/launch.json | 2 +- Duplicate-Search/.vscode/launch.json | 2 +- Instance/.vscode/launch.json | 2 +- Instance/DlibDotNet.cs | 6 +- Instance/appsettings.Development.json | 12 +- Instance/appsettings.json | 2 +- Not-Copy-Copy/.vscode/launch.json | 2 +- PrepareForOld/.vscode/launch.json | 2 +- Shared/Models/Stateless/Methods/IPath.cs | 5 + Shared/Models/Stateless/Methods/XPath.cs | 29 ++- View-by-Distance-MKLink-Console.sln | 6 + 28 files changed, 843 insertions(+), 36 deletions(-) create mode 100644 Delete-By-Distinct/.vscode/format-report.json create mode 100644 Delete-By-Distinct/.vscode/launch.json create mode 100644 Delete-By-Distinct/.vscode/settings.json create mode 100644 Delete-By-Distinct/.vscode/tasks.json create mode 100644 Delete-By-Distinct/Delete-By-Distinct.csproj create mode 100644 Delete-By-Distinct/DeleteByDistinct.cs create mode 100644 Delete-By-Distinct/Models/AppSettings.cs create mode 100644 Delete-By-Distinct/Models/Binder/AppSettings.cs create mode 100644 Delete-By-Distinct/Models/Stateless/SerilogExtensionMethods.cs create mode 100644 Delete-By-Distinct/Program.cs create mode 100644 Delete-By-Distinct/appsettings.Development.json create mode 100644 Delete-By-Distinct/appsettings.json diff --git a/.vscode/launch.json b/.vscode/launch.json index aab5ce1..8d7dd5f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -57,6 +57,23 @@ "stopAtEntry": false, "requireExactSource": false }, + { + "name": "Delete-By-Distinct", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + "program": "${workspaceFolder}/Delete-By-Distinct/bin/Debug/net7.0/win-x64/Delete-By-Distinct.dll", + "args": [ + "s" + ], + "env": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "cwd": "${workspaceFolder}", + "console": "externalTerminal", + "stopAtEntry": false, + "requireExactSource": false + }, { "name": "Delete-By-Relative", "type": "coreclr", @@ -144,6 +161,7 @@ } ] } +// https://www.amazon.com/photos/ // "AmazonUsername": "phares36@gmail.com", // "AmazonPassword": "JlPhgtv@63", // Keep creating the .json file the same way @@ -297,5 +315,5 @@ // Distance face files date time? // If not Hog and Original image size resize face // New json file with known locations at original image size -// Add person to metadata when saving to SaveResizedImagesByPersonKeyFormattedForOutputResolutions maybe SaveMappedForOutputResolutions +// Add person to metadata when saving to SaveFilteredOriginalImagesFromJLinksForOutputResolutions maybe SaveMappedForOutputResolutions // GetFaceLocations \ No newline at end of file diff --git a/Compare/.vscode/launch.json b/Compare/.vscode/launch.json index e9e82d7..9c35c41 100644 --- a/Compare/.vscode/launch.json +++ b/Compare/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "preLaunchTask": "build", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/bin/Debug/net6.0/win-x64/Compare.dll", + "program": "${workspaceFolder}/bin/Debug/net7.0/win-x64/Compare.dll", "args": [ "s" ], diff --git a/Date-Group/.vscode/launch.json b/Date-Group/.vscode/launch.json index 0368280..cd224aa 100644 --- a/Date-Group/.vscode/launch.json +++ b/Date-Group/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "preLaunchTask": "build", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/bin/Debug/net6.0/win-x64/Date-Group.dll", + "program": "${workspaceFolder}/bin/Debug/net7.0/win-x64/Date-Group.dll", "args": [], "env": { "ASPNETCORE_ENVIRONMENT": "Development", diff --git a/Delete-By-Distinct/.vscode/format-report.json b/Delete-By-Distinct/.vscode/format-report.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/Delete-By-Distinct/.vscode/format-report.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/Delete-By-Distinct/.vscode/launch.json b/Delete-By-Distinct/.vscode/launch.json new file mode 100644 index 0000000..3ca5915 --- /dev/null +++ b/Delete-By-Distinct/.vscode/launch.json @@ -0,0 +1,32 @@ +{ + "version": "0.2.0", + "configurations": [ + { + // Use IntelliSense to find out which attributes exist for C# debugging + // Use hover for the description of the existing attributes + // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md + "name": ".NET Core Launch (console)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + // If you have changed target frameworks, make sure to update the program path. + "program": "${workspaceFolder}/bin/Debug/net7.0/win-x64/Delete-By-Distinct.dll", + "args": [ + "s" + ], + "env": { + "ASPNETCORE_ENVIRONMENT": "Development", + }, + "cwd": "${workspaceFolder}", + // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console + "console": "externalTerminal", + "stopAtEntry": false + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach", + "processName": "Delete-By-Distinct" + } + ] +} \ No newline at end of file diff --git a/Delete-By-Distinct/.vscode/settings.json b/Delete-By-Distinct/.vscode/settings.json new file mode 100644 index 0000000..768342e --- /dev/null +++ b/Delete-By-Distinct/.vscode/settings.json @@ -0,0 +1,14 @@ +{ + "cSpell.words": [ + "Barrick", + "bcdfghjklmnpqrstvwxyz", + "Beichler", + "Bohdi", + "Dlib", + "exif", + "nosj", + "Phares", + "Serilog", + "Vericruz" + ] +} \ No newline at end of file diff --git a/Delete-By-Distinct/.vscode/tasks.json b/Delete-By-Distinct/.vscode/tasks.json new file mode 100644 index 0000000..4cbf769 --- /dev/null +++ b/Delete-By-Distinct/.vscode/tasks.json @@ -0,0 +1,42 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/Delete-By-Distinct.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/Delete-By-Distinct.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "${workspaceFolder}/Delete-By-Distinct.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/Delete-By-Distinct/Delete-By-Distinct.csproj b/Delete-By-Distinct/Delete-By-Distinct.csproj new file mode 100644 index 0000000..5c85d13 --- /dev/null +++ b/Delete-By-Distinct/Delete-By-Distinct.csproj @@ -0,0 +1,62 @@ + + + enable + 10.0 + enable + Exe + win-x64 + net7.0 + + + Phares.View.by.Distance.Delete.By.Distinct + false + 6.0.100.1 + Mike Phares + Phares + true + snupkg + + + true + true + true + + + Windows + + + OSX + + + Linux + + + + + + + + + + + + + + + + + + + + + + + + + Always + + + Always + + + \ No newline at end of file diff --git a/Delete-By-Distinct/DeleteByDistinct.cs b/Delete-By-Distinct/DeleteByDistinct.cs new file mode 100644 index 0000000..fb26110 --- /dev/null +++ b/Delete-By-Distinct/DeleteByDistinct.cs @@ -0,0 +1,105 @@ +using Microsoft.Extensions.Configuration; +using Phares.Shared; +using Serilog; +using ShellProgressBar; +using View_by_Distance.Delete.By.Distinct.Models; +using View_by_Distance.Property.Models; +using View_by_Distance.Shared.Models.Methods; + +namespace View_by_Distance.Delete.By.Distinct; + +public class DeleteByDistinct +{ + + public DeleteByDistinct(List args, IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, AppSettings appSettings, string workingDirectory, bool isSilent, IConsole console) + { + if (isSilent) + { } + if (console is null) + { } + string searchPattern = "*"; + long ticks = DateTime.Now.Ticks; + ILogger? log = Log.ForContext(); + Dictionary>> fileSizeToCollection = new(); + Configuration configuration = Property.Models.Binder.Configuration.Get(isEnvironment, configurationRoot); + ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; + configuration.Update(); + log.Information(configuration.RootDirectory); + Work(searchPattern, ticks, log, configuration.RootDirectory, nameof(configuration.RootDirectory), options, fileSizeToCollection); + Work(searchPattern, ticks, log, appSettings.CompareRootDirectory, nameof(appSettings.CompareRootDirectory), options, fileSizeToCollection); + } + + private static void Work(string searchPattern, long ticks, ILogger log, string directory, string variable, ProgressBarOptions options, Dictionary>> fileSizeToCollection) + { + string message; + string checkName; + string deleteLog; + int totalSeconds; + FileInfo fileInfo; + ProgressBar progressBar; + List? fileNames; + List deletedFiles = new(); + List deletedDirectories = new(); + Dictionary>? fileTicksToNames; + log.Information($"Gathering files from <{directory}>"); + (string directory, string[] files)[] leftCollection = Shared.Models.Stateless.Methods.IFileHolder.GetFiles(directory, searchPattern).ToArray(); + totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); + message = $") Looking for duplicates from <{directory}> - {totalSeconds} total second(s)"; + progressBar = new(leftCollection.Length, message, options); + foreach ((_, string[] files) in leftCollection) + { + progressBar.Tick(); + foreach (string file in files) + { + fileInfo = new(file); + if (!fileSizeToCollection.TryGetValue(fileInfo.Length, out fileTicksToNames)) + { + fileSizeToCollection.Add(fileInfo.Length, new()); + if (!fileSizeToCollection.TryGetValue(fileInfo.Length, out fileTicksToNames)) + throw new Exception(); + } + if (!fileTicksToNames.TryGetValue(fileInfo.LastWriteTime.Ticks, out fileNames)) + { + fileTicksToNames.Add(fileInfo.LastWriteTime.Ticks, new()); + if (!fileTicksToNames.TryGetValue(fileInfo.LastWriteTime.Ticks, out fileNames)) + throw new Exception(); + } + checkName = fileInfo.Name.ToLower(); + if (fileNames.Contains(checkName)) + deletedFiles.Add(file); + else + fileNames.Add(checkName); + } + } + deleteLog = $"{ticks}-{variable}-Files.lsv"; + File.WriteAllLines(Path.Combine(directory, deleteLog), deletedFiles); + if (deletedFiles.Any()) + { + log.Information($"Ready to delete {deletedFiles.Count} from {variable} file(s)? See <{deleteLog}>"); + for (int y = 0; y < int.MaxValue; y++) + { + log.Information("Press \"Y\" key to delete file(s) or close console to not delete files"); + if (Console.ReadKey().Key == ConsoleKey.Y) + break; + } + log.Information(". . ."); + foreach (string file in deletedFiles) + File.Delete(file); + totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); + message = $") Looking for empty directories from <{directory}> - {totalSeconds} total second(s)"; + progressBar.Dispose(); + progressBar = new(4, message, options); + for (int i = 1; i < 5; i++) + { + progressBar.Tick(); + List check = new(); + Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(directory, check); + if (!check.Any()) + break; + deletedDirectories.AddRange(check); + } + deleteLog = $"{ticks}-{variable}-Directories.lsv"; + File.WriteAllLines(Path.Combine(directory, deleteLog), deletedDirectories.Distinct()); + } + } +} \ No newline at end of file diff --git a/Delete-By-Distinct/Models/AppSettings.cs b/Delete-By-Distinct/Models/AppSettings.cs new file mode 100644 index 0000000..bce0f71 --- /dev/null +++ b/Delete-By-Distinct/Models/AppSettings.cs @@ -0,0 +1,31 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace View_by_Distance.Delete.By.Distinct.Models; + +public class AppSettings +{ + + public string Company { init; get; } + public string CompareRootDirectory { init; get; } + public int MaxDegreeOfParallelism { init; get; } + public string OutputExtension { init; get; } + public string WorkingDirectoryName { init; get; } + + [JsonConstructor] + public AppSettings(string company, string compareRootDirectory, int maxDegreeOfParallelism, string outputExtension, string workingDirectoryName) + { + Company = company; + CompareRootDirectory = compareRootDirectory; + MaxDegreeOfParallelism = maxDegreeOfParallelism; + OutputExtension = outputExtension; + WorkingDirectoryName = workingDirectoryName; + } + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); + return result; + } + +} \ No newline at end of file diff --git a/Delete-By-Distinct/Models/Binder/AppSettings.cs b/Delete-By-Distinct/Models/Binder/AppSettings.cs new file mode 100644 index 0000000..5826fc4 --- /dev/null +++ b/Delete-By-Distinct/Models/Binder/AppSettings.cs @@ -0,0 +1,48 @@ +using Microsoft.Extensions.Configuration; +using System.Text.Json; + +namespace View_by_Distance.Delete.By.Distinct.Models.Binder; + +public class AppSettings +{ + +#nullable disable + + public string Company { get; set; } + public string CompareRootDirectory { get; set; } + public int? MaxDegreeOfParallelism { get; set; } + public string OutputExtension { get; set; } + public string WorkingDirectoryName { get; set; } + +#nullable restore + + public override string ToString() + { + string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true }); + return result; + } + + private static Models.AppSettings Get(AppSettings? appSettings) + { + Models.AppSettings result; + if (appSettings?.MaxDegreeOfParallelism is null) + throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism)); + result = new( + appSettings.Company, + appSettings.CompareRootDirectory, + appSettings.MaxDegreeOfParallelism.Value, + appSettings.OutputExtension, + appSettings.WorkingDirectoryName + ); + return result; + } + + public static Models.AppSettings Get(IConfigurationRoot configurationRoot) + { + Models.AppSettings result; + AppSettings? appSettings = configurationRoot.Get(); + result = Get(appSettings); + return result; + } + +} \ No newline at end of file diff --git a/Delete-By-Distinct/Models/Stateless/SerilogExtensionMethods.cs b/Delete-By-Distinct/Models/Stateless/SerilogExtensionMethods.cs new file mode 100644 index 0000000..38c52da --- /dev/null +++ b/Delete-By-Distinct/Models/Stateless/SerilogExtensionMethods.cs @@ -0,0 +1,10 @@ +namespace View_by_Distance.Delete.By.Distinct.Models.Stateless; + +public static class SerilogExtensionMethods +{ + + internal static void Warn(this Serilog.ILogger log, string messageTemplate) => log.Warning(messageTemplate); + + internal static void Info(this Serilog.ILogger log, string messageTemplate) => log.Information(messageTemplate); + +} \ No newline at end of file diff --git a/Delete-By-Distinct/Program.cs b/Delete-By-Distinct/Program.cs new file mode 100644 index 0000000..61be4b9 --- /dev/null +++ b/Delete-By-Distinct/Program.cs @@ -0,0 +1,70 @@ +using Microsoft.Extensions.Configuration; +using Phares.Shared; +using Serilog; +using System.Diagnostics; +using System.Reflection; +using View_by_Distance.Delete.By.Distinct.Models; +using View_by_Distance.Shared.Models.Stateless.Methods; + +namespace View_by_Distance.Delete.By.Distinct; + +public class Program +{ + + public static void Secondary(List args) + { + LoggerConfiguration loggerConfiguration = new(); + Assembly assembly = Assembly.GetExecutingAssembly(); + bool debuggerWasAttachedAtLineZero = Debugger.IsAttached || assembly.Location.Contains(@"\bin\Debug"); + IsEnvironment isEnvironment = new(processesCount: null, nullASPNetCoreEnvironmentIsDevelopment: debuggerWasAttachedAtLineZero, nullASPNetCoreEnvironmentIsProduction: !debuggerWasAttachedAtLineZero); + IConfigurationBuilder configurationBuilder = new ConfigurationBuilder() + .AddEnvironmentVariables() + .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) + .AddJsonFile(isEnvironment.AppSettingsFileName, optional: false, reloadOnChange: true); + IConfigurationRoot configurationRoot = configurationBuilder.Build(); + AppSettings appSettings = Models.Binder.AppSettings.Get(configurationRoot); + if (appSettings.MaxDegreeOfParallelism > Environment.ProcessorCount) + throw new Exception("MaxDegreeOfParallelism must be =< Environment.ProcessorCount!"); + if (string.IsNullOrEmpty(appSettings.WorkingDirectoryName)) + throw new Exception("Working directory name must have a value!"); + string workingDirectory = IWorkingDirectory.GetWorkingDirectory(assembly.GetName().Name, appSettings.WorkingDirectoryName); + Environment.SetEnvironmentVariable(nameof(workingDirectory), workingDirectory); + _ = ConfigurationLoggerConfigurationExtensions.Configuration(loggerConfiguration.ReadFrom, configurationRoot); + Log.Logger = loggerConfiguration.CreateLogger(); + ILogger log = Log.ForContext(); + int silentIndex = args.IndexOf("s"); + if (silentIndex > -1) + args.RemoveAt(silentIndex); + try + { + if (args is null) + throw new Exception("args is null!"); + Shared.Models.Console console = new(); + _ = new DeleteByDistinct(args, isEnvironment, configurationRoot, appSettings, workingDirectory, silentIndex > -1, console); + } + catch (Exception ex) + { + log.Fatal(string.Concat(ex.Message, Environment.NewLine, ex.StackTrace)); + } + finally + { + Log.CloseAndFlush(); + } + if (silentIndex > -1) + log.Debug("Done. Bye"); + else + { + log.Debug("Done. Press 'Enter' to end"); + _ = Console.ReadLine(); + } + } + + public static void Main(string[] args) + { + if (args is not null) + Secondary(args.ToList()); + else + Secondary(new List()); + } + +} \ No newline at end of file diff --git a/Delete-By-Distinct/appsettings.Development.json b/Delete-By-Distinct/appsettings.Development.json new file mode 100644 index 0000000..4c4884f --- /dev/null +++ b/Delete-By-Distinct/appsettings.Development.json @@ -0,0 +1,243 @@ +{ + "xCompareRootDirectory": "", + "CompareRootDirectory": "C:/Tmp-x", + "Logging": { + "LogLevel": { + "Log4netProvider": "Debug" + } + }, + "MaxDegreeOfParallelism": 6, + "Serilog": { + "MinimumLevel": "Debug" + }, + "Windows": { + "Configuration": { + "xRootDirectory": "C:/Tmp-x", + "RootDirectory": "D:/Tmp/Phares/Compare/Not-Copy-Copy-4d49b68", + "VerifyToSeason": [ + ". 2000", + ". 2001", + ". 2002", + ". 2003", + ". 2004", + ". 2005", + ". 2006", + ". 2007", + ". 2008", + ". 2009", + ". 2010", + ". 2011", + ". 2012", + ". 2013", + ". 2014", + ". 2015", + ". 2016", + ". 2017", + ". 2018", + ". 2019", + ". 2020", + ". 2021", + ". 2022", + ". 2023", + ". 2024", + ". 2025", + ". 2026", + ". 2027", + ". 2028", + ". 2029", + "=2000.0 Winter", + "=2002.1 Spring", + "=2002.4 Winter", + "=2003.0 Winter", + "=2003.1 Spring", + "=2003.3 Fall", + "=2003.4 Winter", + "=2004.0 Winter", + "=2005.1 Spring", + "=2005.2 Summer", + "=2005.3 Fall", + "=2005.4 Winter", + "=2006.0 Winter", + "=2006.1 Spring", + "=2006.3 Fall", + "=2007.0 Winter", + "=2007.2 Summer Logan Michael", + "=2007.2 Summer", + "=2007.3 Fall Logan Michael", + "=2007.4 Winter Logan Michael", + "=2008.0 Winter Logan Michael", + "=2008.1 Spring Logan Michael", + "=2008.2 Summer Logan Michael", + "=2008.2 Summer", + "=2008.3 Fall Logan Michael", + "=2009.0 Winter Logan Michael", + "=2009.0 Winter", + "=2009.1 Spring Logan Michael", + "=2009.1 Spring", + "=2009.2 Summer Logan Michael", + "=2009.2 Summer", + "=2009.3 Fall Logan Michael", + "=2009.3 Fall", + "=2009.4 Winter Logan Michael", + "=2009.4 Winter", + "=2010.0 Winter Logan Michael", + "=2010.0 Winter", + "=2010.1 Spring Logan Michael", + "=2010.1 Spring", + "=2010.2 Summer", + "=2010.3 Fall Logan Michael", + "=2010.3 Fall", + "=2010.4 Winter", + "=2011.0 Winter", + "=2011.1 Spring", + "=2011.2 Summer", + "=2011.3 Fall", + "=2011.4 Winter", + "=2012.0 Winter Chelsea 2012", + "=2012.0 Winter Chelsea", + "=2012.0 Winter", + "=2012.1 Spring Chelsea", + "=2012.1 Spring", + "=2012.2 Summer Chelsea", + "=2012.2 Summer", + "=2012.3 Fall Chelsea", + "=2012.3 Fall", + "=2012.4 Winter Chelsea", + "=2012.4 Winter", + "=2013.0 Winter Chelsea 2013", + "=2013.0 Winter Chelsea", + "=2013.0 Winter", + "=2013.1 Spring", + "=2013.2 Summer Chelsea", + "=2013.2 Summer", + "=2013.3 Fall Chelsea", + "=2013.3 Fall", + "=2013.4 Winter", + "=2014.0 Winter", + "=2014.1 Spring", + "=2014.2 Summer", + "=2014.3 Fall", + "=2014.4 Winter", + "=2015.0 Winter", + "=2015.1 Spring", + "=2015.2 Summer", + "=2015.3 Fall", + "=2015.4 Winter", + "=2016.0 Winter", + "=2016.1 Spring", + "=2016.2 Summer", + "=2016.3 Fall", + "=2016.4 Winter", + "=2017.1 Spring", + "=2017.2 Summer", + "=2017.3 Fall", + "=2017.4 Winter", + "=2018.0 Winter", + "=2018.1 Spring", + "=2018.3 Fall", + "=2018.4 Winter", + "=2019.0 Winter", + "=2019.1 Spring", + "=2019.2 Summer", + "=2019.3 Fall", + "=2019.4 Winter", + "=2020.0 Winter", + "=2020.1 Spring", + "=2020.2 Summer", + "=2020.3 Fall", + "=2020.4 Winter", + "=2021.1 Spring", + "=2021.2 Summer", + "=2021.3 Fall", + "=2021.4 Winter", + "=2022.0 Winter", + "=2022.1 Spring", + "Anthem 2015", + "April 2010", + "April 2013", + "December 2006", + "December 2010", + "Fall 2005", + "Fall 2015", + "Fall 2016", + "Fall 2017", + "Fall 2018", + "Fall 2019", + "Fall 2020", + "Fall 2021", + "February 2010", + "January 2015", + "July 2010", + "June 2010", + "Kids 2005", + "March 2013", + "May 2010", + "May 2011", + "May 2013", + "October 2005", + "October 2014", + "Spring 2013", + "Spring 2014", + "Spring 2016", + "Spring 2018", + "Spring 2019", + "Spring 2020", + "Summer 2011", + "Summer 2012", + "Summer 2013", + "Summer 2014", + "Summer 2015", + "Summer 2016", + "Summer 2017", + "Summer 2018", + "Summer 2020", + "Summer 2021", + "Winter 2015", + "Winter 2016", + "Winter 2017", + "Winter 2018", + "Winter 2019-2020", + "Winter 2020", + "zzz =2005.0 Winter Tracy Pictures", + "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.0 Winter 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" + ] + } + } +} \ No newline at end of file diff --git a/Delete-By-Distinct/appsettings.json b/Delete-By-Distinct/appsettings.json new file mode 100644 index 0000000..ec3e650 --- /dev/null +++ b/Delete-By-Distinct/appsettings.json @@ -0,0 +1,117 @@ +{ + "CompareRootDirectory": "", + "Company": "Mike Phares", + "Linux": {}, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Log4netProvider": "Debug", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "MaxDegreeOfParallelism": 6, + "Serilog": { + "Using": [ + "Serilog.Sinks.Console", + "Serilog.Sinks.File" + ], + "MinimumLevel": "Information", + "WriteTo": [ + { + "Name": "Debug", + "Args": { + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}" + } + }, + { + "Name": "Console", + "Args": { + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}" + } + }, + { + "Name": "File", + "Args": { + "path": "%workingDirectory% - Log/log-.txt", + "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] ({SourceContext}.{MethodName}) ({InstanceId}) ({RemoteIpAddress}) {Message}{NewLine}{Exception}", + "rollingInterval": "Hour" + } + } + ], + "Enrich": [ + "FromLogContext", + "WithMachineName", + "WithThreadId" + ], + "Properties": { + "Application": "Sample" + } + }, + "WorkingDirectoryName": "PharesApps", + "Windows": { + "Configuration": { + "DateGroup": "2022-12-21", + "DiffPropertyDirectory": "", + "FileNameDirectorySeparator": ".Z.", + "ForcePropertyLastWriteTimeToCreationTime": false, + "MaxImagesInDirectoryForTopLevelFirstPass": 10, + "OutputExtension": ".jpg", + "Pattern": "[^ABCDEFGHIJKLMNOPQRSTUVWXYZbcdfghjklmnpqrstvwxyz0-9]", + "PopulatePropertyId": true, + "PropertiesChangedForProperty": false, + "ResultAllInOne": "_ _ _", + "ResultCollection": "[]", + "ResultContent": "()", + "ResultSingleton": "{}", + "RootDirectory": "C:/Tmp/Phares/Compare/Images-4d49b68", + "WriteBitmapDataBytes": false, + "IgnoreExtensions": [ + ".gif", + ".GIF" + ], + "ValidImageFormatExtensions": [ + ".bmp", + ".BMP", + ".gif", + ".GIF", + ".jpeg", + ".JPEG", + ".jpg", + ".JPG", + ".png", + ".PNG", + ".tiff", + ".TIFF" + ], + "ValidMetadataExtensions": [ + ".3gp", + ".3GP", + ".avi", + ".AVI", + ".bmp", + ".BMP", + ".gif", + ".GIF", + ".ico", + ".ICO", + ".jpeg", + ".JPEG", + ".jpg", + ".JPG", + ".m4v", + ".M4V", + ".mov", + ".MOV", + ".mp4", + ".MP4", + ".mta", + ".MTA", + ".png", + ".PNG", + ".tiff", + ".TIFF" + ] + } + } +} \ No newline at end of file diff --git a/Delete-By-Relative/.vscode/launch.json b/Delete-By-Relative/.vscode/launch.json index f7b185a..8f19010 100644 --- a/Delete-By-Relative/.vscode/launch.json +++ b/Delete-By-Relative/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "preLaunchTask": "build", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/bin/Debug/net6.0/win-x64/Duplicate-Search.dll", + "program": "${workspaceFolder}/bin/Debug/net7.0/win-x64/Delete-By-Relative.dll", "args": [ "s" ], @@ -26,7 +26,7 @@ "name": ".NET Core Attach", "type": "coreclr", "request": "attach", - "processName": "Duplicate-Search" + "processName": "Delete-By-Relative" } ] } \ No newline at end of file diff --git a/Delete-By-Relative/.vscode/tasks.json b/Delete-By-Relative/.vscode/tasks.json index 3c2eb55..8b79e33 100644 --- a/Delete-By-Relative/.vscode/tasks.json +++ b/Delete-By-Relative/.vscode/tasks.json @@ -7,7 +7,7 @@ "type": "process", "args": [ "build", - "${workspaceFolder}/Duplicate-Search.csproj", + "${workspaceFolder}/Delete-By-Relative.csproj", "/property:GenerateFullPaths=true", "/consoleloggerparameters:NoSummary" ], @@ -19,7 +19,7 @@ "type": "process", "args": [ "publish", - "${workspaceFolder}/Duplicate-Search.csproj", + "${workspaceFolder}/Delete-By-Relative.csproj", "/property:GenerateFullPaths=true", "/consoleloggerparameters:NoSummary" ], @@ -32,7 +32,7 @@ "args": [ "watch", "run", - "${workspaceFolder}/Duplicate-Search.csproj", + "${workspaceFolder}/Delete-By-Relative.csproj", "/property:GenerateFullPaths=true", "/consoleloggerparameters:NoSummary" ], diff --git a/Drag-Drop/.vscode/launch.json b/Drag-Drop/.vscode/launch.json index 5926784..05425f5 100644 --- a/Drag-Drop/.vscode/launch.json +++ b/Drag-Drop/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "preLaunchTask": "build", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/bin/Debug/net6.0-windows/win-x64/Drag-Drop.dll", + "program": "${workspaceFolder}/bin/Debug/net7.0-windows/win-x64/Drag-Drop.dll", "args": [], "cwd": "${workspaceFolder}", // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console diff --git a/Duplicate-Search/.vscode/launch.json b/Duplicate-Search/.vscode/launch.json index f7b185a..f97bf52 100644 --- a/Duplicate-Search/.vscode/launch.json +++ b/Duplicate-Search/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "preLaunchTask": "build", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/bin/Debug/net6.0/win-x64/Duplicate-Search.dll", + "program": "${workspaceFolder}/bin/Debug/net7.0/win-x64/Duplicate-Search.dll", "args": [ "s" ], diff --git a/Instance/.vscode/launch.json b/Instance/.vscode/launch.json index 548fdc2..6cede9d 100644 --- a/Instance/.vscode/launch.json +++ b/Instance/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "preLaunchTask": "build", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/bin/x64/Debug/net6.0/win-x64/Instance.dll", + "program": "${workspaceFolder}/bin/x64/Debug/net7.0/win-x64/Instance.dll", "args": [ "s" ], diff --git a/Instance/DlibDotNet.cs b/Instance/DlibDotNet.cs index bdb5276..327d417 100644 --- a/Instance/DlibDotNet.cs +++ b/Instance/DlibDotNet.cs @@ -294,7 +294,7 @@ public partial class DlibDotNet Dictionary imageResizeKeyValuePairs; List> subFileTuples = new(); List> metadataCollection; - Dictionary> relativeLocations; + // Dictionary> relativeLocations; if (item.Property is not null && item.Property.Id is not null && !item.Any()) { property = item.Property; @@ -364,7 +364,7 @@ public partial class DlibDotNet int outputResolutionHeight = outputResolutionCollection[1]; int outputResolutionOrientation = outputResolutionCollection[2]; faces = _Faces.GetFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation); - relativeLocations = _Faces.GetRelativeLocations(outputResolution, dResultsDateGroupDirectory, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, original, imageResizeKeyValuePairs, faces); + // relativeLocations = _Faces.GetRelativeLocations(outputResolution, dResultsDateGroupDirectory, subFileTuples, parseExceptions, property, mappingFromItem, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, original, imageResizeKeyValuePairs, faces); if (_AppSettings.MaxDegreeOfParallelism < 2) ticks = LogDelta(ticks, nameof(D_Face.GetFaces)); bool anyFacesSaved = _Faces.SaveFaces(dResultsFullGroupDirectory, subFileTuples, parseExceptions, mappingFromItem, facesDirectory, faces); @@ -896,7 +896,7 @@ public partial class DlibDotNet MapLogicSupport.SaveFaceDistances(_Configuration.PropertyConfiguration, sortingContainers); if (totalNotMapped > 0) { - bool saveNullPerson = true; // !personKeyToCount.Any(); + bool saveNullPerson = !personKeyToCount.Any() || _Configuration.RangeDistanceTolerance[1] < (_Configuration.RangeDistanceTolerance[2] * .5); int updated = mapLogic.UpdateFromSortingContainers(sortingContainers, saveNullPerson); List saveContainers = mapLogic.GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedRectangleToMapping, useFiltersCounter, saveNullPerson); mapLogic.SaveContainers(totalNotMapped, updated, saveContainers); diff --git a/Instance/appsettings.Development.json b/Instance/appsettings.Development.json index 7d3ae17..ac16728 100644 --- a/Instance/appsettings.Development.json +++ b/Instance/appsettings.Development.json @@ -10,10 +10,12 @@ }, "Windows": { "Configuration": { + "DistanceRenameToMatch": false, + "DistanceMoveUnableToMatch": false, "PhotoPrismDirectory": "G:/photo-prism/Not-Copy-Copy-4d49b68/phpMyAdmin/export", - "xRootDirectory": "C:/Tmp/phares/Pictures", - "RootDirectory": "F:/Tmp/Phares/Compare/Not-Copy-Copy-4d49b68", - "xxRootDirectory": "F:/Tmp/Phares/Compare/Images-4d49b68", + "xRootDirectory": "D:/Tmp/phares/Pictures", + "RootDirectory": "E:/Tmp/Phares/Compare/Not-Copy-Copy-4d49b68", + "xxxRootDirectory": "E:/Tmp/Phares/Compare/Images-4d49b68", "xxxxRootDirectory": "F:/Tmp/Phares/Compare/Images-4d49b68/Facebook/=2022.3 Facebook", "JLinks": [ "Julie" @@ -35,7 +37,7 @@ ], "RangeDistanceTolerance": [ 0, - 0.6, + 0.5, 0.6 ], "RangeFaceAreaPermilleTolerance": [ @@ -54,7 +56,7 @@ "SaveFaceLandmarkForOutputResolutions": [], "SaveMappedForOutputResolutions": [], "SaveNotMappedForOutputResolutions": [], - "SaveResizedImagesByPersonKeyFormattedForOutputResolutions": [], + "SaveFilteredOriginalImagesFromJLinksForOutputResolutions": [], "SaveShortcutsForOutputResolutions": [], "IgnoreRelativePaths": [ "3757 W Whitman 2017", diff --git a/Instance/appsettings.json b/Instance/appsettings.json index f7eac00..f06e38f 100644 --- a/Instance/appsettings.json +++ b/Instance/appsettings.json @@ -151,7 +151,7 @@ "SaveFaceLandmarkForOutputResolutions": [], "SaveMappedForOutputResolutions": [], "SaveNotMappedForOutputResolutions": [], - "SaveResizedImagesByPersonKeyFormattedForOutputResolutions": [], + "SaveFilteredOriginalImagesFromJLinksForOutputResolutions": [], "SaveShortcutsForOutputResolutions": [], "IgnoreRelativePaths": [], "MixedYearRelativePaths": [], diff --git a/Not-Copy-Copy/.vscode/launch.json b/Not-Copy-Copy/.vscode/launch.json index 0bcf080..c3363e6 100644 --- a/Not-Copy-Copy/.vscode/launch.json +++ b/Not-Copy-Copy/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "preLaunchTask": "build", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/bin/Debug/net6.0/win-x64/Not-Copy-Copy.dll", + "program": "${workspaceFolder}/bin/Debug/net7.0/win-x64/Not-Copy-Copy.dll", "args": [], "env": { "ASPNETCORE_ENVIRONMENT": "Development", diff --git a/PrepareForOld/.vscode/launch.json b/PrepareForOld/.vscode/launch.json index 7043023..e3b7701 100644 --- a/PrepareForOld/.vscode/launch.json +++ b/PrepareForOld/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "preLaunchTask": "build", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/bin/Debug/net6.0/win-x64/PrepareForOld.dll", + "program": "${workspaceFolder}/bin/Debug/net7.0/win-x64/PrepareForOld.dll", "args": [], "env": { "ASPNETCORE_ENVIRONMENT": "Development", diff --git a/Shared/Models/Stateless/Methods/IPath.cs b/Shared/Models/Stateless/Methods/IPath.cs index c79f8d3..add364f 100644 --- a/Shared/Models/Stateless/Methods/IPath.cs +++ b/Shared/Models/Stateless/Methods/IPath.cs @@ -13,6 +13,11 @@ public interface IPath static bool DeleteEmptyDirectories(string rootDirectory) => XPath.DeleteEmptyDirectories(rootDirectory); + void TestStatic_DeleteEmptyDirectories(string rootDirectory, List deletedDirectories) => + DeleteEmptyDirectories(rootDirectory, deletedDirectories); + static void DeleteEmptyDirectories(string rootDirectory, List deletedDirectories) => + XPath.DeleteEmptyDirectories(rootDirectory, deletedDirectories); + string[] TestStatic_GetDirectoryNames(string directory) => GetDirectoryNames(directory); static string[] GetDirectoryNames(string directory) => diff --git a/Shared/Models/Stateless/Methods/XPath.cs b/Shared/Models/Stateless/Methods/XPath.cs index 986454a..08f17a0 100644 --- a/Shared/Models/Stateless/Methods/XPath.cs +++ b/Shared/Models/Stateless/Methods/XPath.cs @@ -28,9 +28,15 @@ internal abstract class XPath internal static bool DeleteEmptyDirectories(string rootDirectory) { bool result; - if (!Directory.Exists(rootDirectory)) - result = false; - else + List results = new(); + DeleteEmptyDirectories(rootDirectory, results); + result = results.Any(); + return result; + } + + internal static void DeleteEmptyDirectories(string rootDirectory, List deletedDirectories) + { + if (Directory.Exists(rootDirectory)) { string[] files; string[] directories = Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly); @@ -40,26 +46,21 @@ internal abstract class XPath files = Directory.GetFiles(rootDirectory, "*", SearchOption.AllDirectories); if (directories.Length == 0 && files.Length == 0) { - result = true; + deletedDirectories.Add(rootDirectory); Directory.Delete(rootDirectory); } else { - result = false; + List check = new(); foreach (string directory in directories) { - result = DeleteEmptyDirectories(directory); - if (result) - result = DeleteEmptyDirectories(directory); - } - if (files is null) - { - directories = Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly); - result = directories.Length == 0; + DeleteEmptyDirectories(directory, check); + deletedDirectories.AddRange(check); + if (check.Any()) + DeleteEmptyDirectories(directory, deletedDirectories); } } } - return result; } internal static bool WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite, DateTime? updateToWhenMatches) diff --git a/View-by-Distance-MKLink-Console.sln b/View-by-Distance-MKLink-Console.sln index 4eb53a2..bce0251 100644 --- a/View-by-Distance-MKLink-Console.sln +++ b/View-by-Distance-MKLink-Console.sln @@ -41,6 +41,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicate-Search", "Duplica EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Delete-By-Relative", "Delete-By-Relative\Delete-By-Relative.csproj", "{9DFCA595-80AA-4E78-A9AF-5B4AB4D737C4}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Delete-By-Distinct", "Delete-By-Distinct\Delete-By-Distinct.csproj", "{3F00BDD5-75F8-470C-ACED-1A26FDC8D7B3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -126,5 +128,9 @@ Global {9DFCA595-80AA-4E78-A9AF-5B4AB4D737C4}.Debug|Any CPU.Build.0 = Debug|Any CPU {9DFCA595-80AA-4E78-A9AF-5B4AB4D737C4}.Release|Any CPU.ActiveCfg = Release|Any CPU {9DFCA595-80AA-4E78-A9AF-5B4AB4D737C4}.Release|Any CPU.Build.0 = Release|Any CPU + {3F00BDD5-75F8-470C-ACED-1A26FDC8D7B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3F00BDD5-75F8-470C-ACED-1A26FDC8D7B3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3F00BDD5-75F8-470C-ACED-1A26FDC8D7B3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3F00BDD5-75F8-470C-ACED-1A26FDC8D7B3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal