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) { } 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); bool compareIsPopulatedAndNotTheSame = !string.IsNullOrEmpty(appSettings.CompareRootDirectory) && appSettings.CompareRootDirectory != configuration.RootDirectory; Work(appSettings, ticks, log, configuration.RootDirectory, nameof(configuration.RootDirectory), options, fileSizeToCollection, logOnly: compareIsPopulatedAndNotTheSame); if (compareIsPopulatedAndNotTheSame) Work(appSettings, ticks, log, appSettings.CompareRootDirectory, nameof(appSettings.CompareRootDirectory), options, fileSizeToCollection, logOnly: false); _ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(appSettings.CompareRootDirectory); } private static void Work(AppSettings appSettings, long ticks, ILogger log, string directory, string variable, ProgressBarOptions options, Dictionary>> fileSizeToCollection, bool logOnly) { string message; long checkTicks; long checkLength; string checkName; string deleteLog; int totalSeconds; FileInfo fileInfo; ProgressBar progressBar; List? fileNames; ConsoleKey? consoleKey = null; List deletedFiles = new(); List deletedDirectories = new(); Dictionary>? fileTicksToNames; log.Information($"Gathering {appSettings.SearchPattern} files from <{directory}>"); (string directory, string[] files)[] leftCollection = Shared.Models.Stateless.Methods.IFileHolder.GetFiles(directory, appSettings.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) { if (file.EndsWith(".id") || file.Contains("Rename")) continue; fileInfo = new(file); if (fileInfo.Length < 100) continue; if (appSettings.RecycleOption) checkLength = 1; else checkLength = fileInfo.Length; if (!fileSizeToCollection.TryGetValue(checkLength, out fileTicksToNames)) { fileSizeToCollection.Add(checkLength, new()); if (!fileSizeToCollection.TryGetValue(checkLength, out fileTicksToNames)) throw new Exception(); } if (appSettings.RecycleOption) checkTicks = 1; else checkTicks = new DateTime(ticks).Ticks; if (!fileTicksToNames.TryGetValue(checkTicks, out fileNames)) { fileTicksToNames.Add(checkTicks, new()); if (!fileTicksToNames.TryGetValue(checkTicks, out fileNames)) throw new Exception(); } checkName = fileInfo.Name.ToLower().Replace(".jpeg", ".jpg"); if (fileNames.Contains(checkName)) deletedFiles.Add(file); else fileNames.Add(checkName); } } progressBar.Dispose(); log.Information(". . ."); deleteLog = $"{ticks}-{variable}-Files.lsv"; if (!logOnly) File.WriteAllLines(Path.Combine(directory, deleteLog), deletedFiles); if (deletedFiles.Any() && !logOnly) { log.Information($"Ready to delete {deletedFiles.Count} from {variable} {appSettings.SearchPattern} file(s)? See <{deleteLog}>"); for (int y = 0; y < int.MaxValue; y++) { log.Information("Press \"Y\" key to delete file(s), \"N\" key to log file(s) or close console to not delete files"); consoleKey = Console.ReadKey().Key; if (consoleKey is ConsoleKey.Y or ConsoleKey.N) break; } log.Information(". . ."); if (consoleKey is not null && consoleKey.Value == ConsoleKey.Y) { foreach (string file in deletedFiles) { if (!appSettings.RecycleOption) { try { File.Delete(file); } catch (Exception) { } } else { try { Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile(file, Microsoft.VisualBasic.FileIO.UIOption.OnlyErrorDialogs, Microsoft.VisualBasic.FileIO.RecycleOption.SendToRecycleBin); } catch (Exception) { } } } totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); message = $") Looking for empty directories from <{directory}> - {totalSeconds} total second(s)"; 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); } progressBar.Dispose(); log.Information(". . ."); deleteLog = $"{ticks + 1}-{variable}-Directories.lsv"; File.WriteAllLines(Path.Combine(directory, deleteLog), deletedDirectories.Distinct()); } } } }