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; } } }