diff --git a/RedundancyFinder/RedundancyFinder.csproj b/RedundancyFinder/RedundancyFinder.csproj
index bb23fb7..92ae209 100644
--- a/RedundancyFinder/RedundancyFinder.csproj
+++ b/RedundancyFinder/RedundancyFinder.csproj
@@ -4,6 +4,7 @@
net8.0
enable
enable
+ Debug;Release;Analyze
diff --git a/RedundancyFinderCLI/AnalyzeCommand.cs b/RedundancyFinderCLI/AnalyzeCommand.cs
new file mode 100644
index 0000000..121d09c
--- /dev/null
+++ b/RedundancyFinderCLI/AnalyzeCommand.cs
@@ -0,0 +1,108 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using RedundancyFinder;
+using Spectre.Console;
+using Spectre.Console.Cli;
+namespace RedundancyFinderCLI
+{
+ internal sealed class AnalyzeCommand : Command
+ {
+ public sealed class Settings : CommandSettings
+ {
+ [Description("Path to analyze.")]
+ [DefaultValue("redundancies.json")]
+ [CommandArgument(0, "[path]")]
+ public string? Path { get; init; }
+
+ [Description("File extensions to search for. Comma separated.")]
+ [CommandOption("-e|--extensions")]
+ [DefaultValue(".jpg,.webp,.raw,.pdf,.xsl,.xslx,.doc,.docx,.txt,.jpeg,.mov,.mp4,.mp3,.wav,.bmp,.gif,.png,.cu,.mid,.msb ,.mov,.avi,.wmv,.flv,.m4v,.bak ,.cpr ,.xml,.psd")]
+ public string? Extensions { get; init; }
+
+ [Description("Show all information.")]
+ [CommandOption("-v|--verbose")]
+ [DefaultValue(false)]
+ public bool Verbose { get; init; }
+
+ }
+ public override int Execute([NotNull] CommandContext context, [NotNull] Settings settings)
+ {
+ WriteLine($"[yellow]Analyzing {settings.Path}[/]");
+
+ var redundancies = JsonConvert.DeserializeObject>(File.ReadAllText(settings.Path));
+
+
+ var groups = redundancies
+ .GroupBy(x => Path.GetExtension(x.Value.Paths[0]), x => x.Value)
+ .ToDictionary(x => x.Key, x => new
+ {
+ FileSize = x.Sum(y => y.FileSize),
+ RedundancySize = x.Sum(y => y.FileSize) * (x.Sum(y => y.Paths.Count) - 1),
+ RedundancyCount = x.Sum(y => y.Paths.Count)-1,
+ });
+ // x => new { FileSize = x, RedundancySize = x.Sum()*(x.Count()-1)}
+ var extensions = settings.Extensions.Split(",", StringSplitOptions.RemoveEmptyEntries);
+ var table = new Table();
+
+ table.AddColumn("Type");
+ table.AddColumn(new TableColumn("Size").RightAligned());
+ table.AddColumn(new TableColumn("Redundancy size").RightAligned());
+ table.AddColumn(new TableColumn("Redundancy count").RightAligned());
+ foreach (var extension in extensions)
+ {
+ if (groups.ContainsKey(extension))
+ {
+
+ var size = groups[extension].FileSize;
+ var sizeFormat = GetSizeFormat((ulong)size);
+
+ var redundancySize = groups[extension].RedundancySize;
+ var redundancySizeFormat = GetSizeFormat((ulong)redundancySize);
+ table.AddRow(
+ new Text(extension),
+ new Markup($"[green]{sizeFormat}[/]"),
+ new Markup($"[yellow]{redundancySizeFormat}[/]"),
+ new Markup($"{groups[extension].RedundancyCount}"));
+ }
+ }
+ AnsiConsole.Write(table);
+ return 0;
+ }
+
+
+ private void WriteLine(string v)
+ {
+ string now = Markup.Escape($"[{DateTime.Now.ToString("HH:mm:ss")}]");
+ AnsiConsole.MarkupLine($"[gray]{now}[/] {v}");
+ }
+
+ private static string GetSizeFormat(ulong totalSize)
+ {
+ string sizeUnit = "B";
+ double size = totalSize;
+ while (size > 1024)
+ {
+ size /= 1024d;
+ sizeUnit = sizeUnit switch
+ {
+ "B" => "KB",
+ "KB" => "MB",
+ "MB" => "GB",
+ "GB" => "TB",
+ _ => sizeUnit
+ };
+
+ }
+ string sizeFormat = $"{size:.00} {sizeUnit}";
+ return sizeFormat;
+ }
+ }
+}
diff --git a/RedundancyFinderCLI/FinderCommand.cs b/RedundancyFinderCLI/FinderCommand.cs
index 64a7bbb..3d02653 100644
--- a/RedundancyFinderCLI/FinderCommand.cs
+++ b/RedundancyFinderCLI/FinderCommand.cs
@@ -50,6 +50,15 @@ namespace RedundancyFinderCLI
SaveRedundancies(finder, settings.OutputPath);
};
+ // Register the CancelKeyPress event to handle Ctrl+C
+ Console.CancelKeyPress += (sender, e) =>
+ {
+ e.Cancel = true; // Prevent the process from terminating immediately
+ WriteLine("[yellow]Ctrl+C detected. Saving redundancies before exiting...[/]");
+ SaveRedundancies(finder, settings.OutputPath ?? "redundancies.json");
+ Environment.Exit(0); // Exit the application gracefully
+ };
+
// Load existing redundancies if the output file exists
if (File.Exists(settings.OutputPath))
{
diff --git a/RedundancyFinderCLI/Program.cs b/RedundancyFinderCLI/Program.cs
index 7caf140..d2d9c0a 100644
--- a/RedundancyFinderCLI/Program.cs
+++ b/RedundancyFinderCLI/Program.cs
@@ -12,7 +12,9 @@ internal class Program
var app = new CommandApp();
app.Configure(config =>
{
+ config.AddCommand("analyze");
#if DEBUG
+
config.PropagateExceptions();
config.ValidateExamples();
#endif
diff --git a/RedundancyFinderCLI/Properties/launchSettings.json b/RedundancyFinderCLI/Properties/launchSettings.json
index e82bfb2..cc974c5 100644
--- a/RedundancyFinderCLI/Properties/launchSettings.json
+++ b/RedundancyFinderCLI/Properties/launchSettings.json
@@ -3,6 +3,10 @@
"RedundancyFinderCLI": {
"commandName": "Project",
"commandLineArgs": "C:\\Users\\daskn\\Pictures\\ -v"
+ },
+ "Analyze": {
+ "commandName": "Project",
+ "commandLineArgs": "analyze"
}
}
}
\ No newline at end of file
diff --git a/RedundancyFinderCLI/RedundancyFinderCLI.csproj b/RedundancyFinderCLI/RedundancyFinderCLI.csproj
index 01dc379..9b8afba 100644
--- a/RedundancyFinderCLI/RedundancyFinderCLI.csproj
+++ b/RedundancyFinderCLI/RedundancyFinderCLI.csproj
@@ -5,6 +5,7 @@
net8.0
enable
enable
+ Debug;Release;Analyze
diff --git a/RedundancyFixer.sln b/RedundancyFixer.sln
index 7209dda..e9034e6 100644
--- a/RedundancyFixer.sln
+++ b/RedundancyFixer.sln
@@ -1,11 +1,11 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
-VisualStudioVersion = 17.13.35818.85 d17.13
+VisualStudioVersion = 17.13.35818.85
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RedundancyFinder", "RedundancyFinder\RedundancyFinder.csproj", "{925C533F-2205-4848-B742-CB013F81DF91}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RedundancyFinder", "RedundancyFinder\RedundancyFinder.csproj", "{925C533F-2205-4848-B742-CB013F81DF91}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RedundancyFinderCLI", "RedundancyFinderCLI\RedundancyFinderCLI.csproj", "{7187EE24-4F0D-48F3-B76C-DAECD4A96F76}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RedundancyFinderCLI", "RedundancyFinderCLI\RedundancyFinderCLI.csproj", "{7187EE24-4F0D-48F3-B76C-DAECD4A96F76}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution