diff --git a/.vscode/launch.json b/.vscode/launch.json index 8d7dd5f..da63235 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -104,7 +104,24 @@ "ASPNETCORE_ENVIRONMENT": "Development" }, "cwd": "${workspaceFolder}", - "console": "externalTerminal", + "console": "integratedTerminal", + "stopAtEntry": false, + "requireExactSource": false + }, + { + "name": "Drag-Drop-Explorer", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + "program": "${workspaceFolder}/Drag-Drop-Explorer/bin/Debug/net7.0-windows/win-x64/Drag-Drop-Explorer.dll", + "args": [ + "s" + ], + "env": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "cwd": "${workspaceFolder}", + "console": "integratedTerminal", "stopAtEntry": false, "requireExactSource": false }, diff --git a/Drag-Drop-Explorer/.vscode/launch.json b/Drag-Drop-Explorer/.vscode/launch.json new file mode 100644 index 0000000..de44254 --- /dev/null +++ b/Drag-Drop-Explorer/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + "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-windows/win-x64/Drag-Drop-Explorer.dll", + "args": [], + "cwd": "${workspaceFolder}", + // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console + "console": "internalConsole", + "stopAtEntry": false + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach" + } + ] +} \ No newline at end of file diff --git a/Drag-Drop-Explorer/.vscode/tasks.json b/Drag-Drop-Explorer/.vscode/tasks.json new file mode 100644 index 0000000..570fdd9 --- /dev/null +++ b/Drag-Drop-Explorer/.vscode/tasks.json @@ -0,0 +1,41 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/Drag-Drop-Explorer.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/Drag-Drop-Explorer.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "--project", + "${workspaceFolder}/Drag-Drop-Explorer.csproj" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/Drag-Drop-Explorer/Drag-Drop-Explorer.csproj b/Drag-Drop-Explorer/Drag-Drop-Explorer.csproj new file mode 100644 index 0000000..21a6b3a --- /dev/null +++ b/Drag-Drop-Explorer/Drag-Drop-Explorer.csproj @@ -0,0 +1,49 @@ + + + enable + 10.0 + enable + WinExe + win-x64 + net7.0-windows + true + + + true + true + true + + + Windows + + + OSX + + + Linux + + + + + + + + + + + + + + + + + + + + Always + + + Always + + + \ No newline at end of file diff --git a/Drag-Drop-Explorer/Form.Designer.cs b/Drag-Drop-Explorer/Form.Designer.cs new file mode 100644 index 0000000..d9d5817 --- /dev/null +++ b/Drag-Drop-Explorer/Form.Designer.cs @@ -0,0 +1,39 @@ +namespace View_by_Distance.Drag_Drop_Explorer; + +partial class Form +{ + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(640, 100); + this.StartPosition = FormStartPosition.CenterScreen; + this.Text = "Form1"; + } + + #endregion +} diff --git a/Drag-Drop-Explorer/Form.cs b/Drag-Drop-Explorer/Form.cs new file mode 100644 index 0000000..f4b6b8c --- /dev/null +++ b/Drag-Drop-Explorer/Form.cs @@ -0,0 +1,167 @@ +using Microsoft.Extensions.Configuration; +using Phares.Shared; +using Serilog; +using System.Diagnostics; +using System.Globalization; +using System.Reflection; +using System.Text.Json; +using View_by_Distance.Drag_Drop_Explorer.Models; +using View_by_Distance.Shared.Models.Stateless.Methods; + +namespace View_by_Distance.Drag_Drop_Explorer; + +public partial class Form : System.Windows.Forms.Form +{ + + private readonly ILogger _Logger; + private readonly Calendar _Calendar; + private readonly TextBox _PathTextBox; + private readonly TextBox _JsonTextBox; + private readonly TextBox _FirstTextBox; + private readonly AppSettings _AppSettings; + private readonly ProgressBar _ProgressBar; + private readonly string _WorkingDirectory; + private readonly IsEnvironment _IsEnvironment; + + public Form() + { + InitializeComponent(); + ILogger logger; + AppSettings appSettings; + string workingDirectory; + IsEnvironment isEnvironment; + IConfigurationRoot configurationRoot; + _Calendar = new CultureInfo("en-US").Calendar; + LoggerConfiguration loggerConfiguration = new(); + Assembly assembly = Assembly.GetExecutingAssembly(); + bool debuggerWasAttachedAtLineZero = Debugger.IsAttached || assembly.Location.Contains(@"\bin\Debug"); + 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); + configurationRoot = configurationBuilder.Build(); + appSettings = Models.Binder.AppSettings.Get(configurationRoot); + if (string.IsNullOrEmpty(appSettings.WorkingDirectoryName)) + throw new Exception("Working path name must have parentDirectory value!"); + workingDirectory = IWorkingDirectory.GetWorkingDirectory(assembly.GetName().Name, appSettings.WorkingDirectoryName); + Environment.SetEnvironmentVariable(nameof(workingDirectory), workingDirectory); + _ = ConfigurationLoggerConfigurationExtensions.Configuration(loggerConfiguration.ReadFrom, configurationRoot); + Log.Logger = loggerConfiguration.CreateLogger(); + logger = Log.ForContext
(); + logger.Information("Complete"); + _Logger = logger; + _AppSettings = appSettings; + Text = "Drag Drop Explorer"; + _IsEnvironment = isEnvironment; + _WorkingDirectory = workingDirectory; + _ProgressBar = new() { Location = new(5, 5), Dock = DockStyle.Top, Visible = false }; + _FirstTextBox = new() { Location = new(5, 5), Dock = DockStyle.Top, Text = _IsEnvironment.Profile }; + _PathTextBox = new() { Location = new(5, 5), Dock = DockStyle.Top, Text = _AppSettings.WorkingDirectoryName }; + _JsonTextBox = new() { Location = new(5, 5), Dock = DockStyle.Top, Text = JsonSerializer.Serialize(_AppSettings, new JsonSerializerOptions { WriteIndented = true }), Multiline = true, MinimumSize = new(1, 80) }; + Load += new EventHandler(Form1_Load); + Controls.Add(_ProgressBar); + Controls.Add(_JsonTextBox); + Controls.Add(_PathTextBox); + Controls.Add(_FirstTextBox); + } + + void Form1_Load(object? sender, EventArgs e) + { + try + { + AllowDrop = true; + DragDrop += new DragEventHandler(Form1_DragDrop); + DragEnter += new DragEventHandler(Form1_DragEnter); + _FirstTextBox.LostFocus += new EventHandler(TextBox_LostFocus); + _PathTextBox.LostFocus += new EventHandler(TextBox_LostFocus); + } + catch (Exception) + { + throw; + } + } + + private static string GetConverted(string value) + { + string result = value.Length < 2 || value[1] != ':' ? value : value.Replace("\\\\", "/").Replace('\\', '/'); + return result; + } + + void TextBox_LostFocus(object? sender, EventArgs e) + { + try + { + if (sender is TextBox textBox) + { + if (textBox.Text == "ps") + throw new NotImplementedException(); + + } + } + catch (Exception) + { + throw; + } + } + + void Form1_DragEnter(object? sender, DragEventArgs e) + { + try + { + if (e.Data is not null && e.Data.GetDataPresent(DataFormats.FileDrop)) + e.Effect = DragDropEffects.Copy; + } + catch (Exception) + { + throw; + } + } + + void Form1_DragDrop(object? sender, DragEventArgs e) + { + try + { + if (e.Data is null || e.Data.GetData(DataFormats.FileDrop) is not string[] paths || !paths.Any()) + { + _FirstTextBox.Text = string.Empty; + _PathTextBox.Text = string.Empty; + _JsonTextBox.Text = string.Empty; + _Logger.Information("No data"); + } + else + { + string converted; + FileInfo fileInfo; + _FirstTextBox.Text = paths[0]; + List files = new(); + DateTime dateTime = DateTime.Now; + List directories = new(); + string weekOfYear = _Calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00"); + string directory = Path.Combine(_WorkingDirectory, $"{dateTime.Year}_{weekOfYear}"); + if (!Directory.Exists(directory)) + _ = Directory.CreateDirectory(directory); + _PathTextBox.Text = GetConverted(Path.Combine(directory, $"{dateTime.Ticks}.json")); + foreach (string path in paths.OrderBy(l => l)) + { + fileInfo = new(path); + converted = GetConverted(path); + if (!fileInfo.Exists) + directories.Add(new(fileInfo.Name, "Directory", fileInfo.LastWriteTime, 0, converted)); + else + files.Add(new(fileInfo.Name, "File", fileInfo.LastWriteTime, fileInfo.Length, converted)); + } + List collection = new(); + collection.AddRange(directories); + collection.AddRange(files); + _JsonTextBox.Text = JsonSerializer.Serialize(collection, new JsonSerializerOptions { WriteIndented = true }); + File.WriteAllText(_PathTextBox.Text, _JsonTextBox.Text); + } + } + catch (Exception) + { + throw; + } + } + +} \ No newline at end of file diff --git a/Drag-Drop-Explorer/Models/AppSettings.cs b/Drag-Drop-Explorer/Models/AppSettings.cs new file mode 100644 index 0000000..e7114a7 --- /dev/null +++ b/Drag-Drop-Explorer/Models/AppSettings.cs @@ -0,0 +1,27 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace View_by_Distance.Drag_Drop_Explorer.Models; + +public class AppSettings +{ + + public string Company { init; get; } + public int MaxDegreeOfParallelism { init; get; } + public string WorkingDirectoryName { init; get; } + + [JsonConstructor] + public AppSettings(string company, int maxDegreeOfParallelism, string workingDirectoryName) + { + Company = company; + MaxDegreeOfParallelism = maxDegreeOfParallelism; + 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/Drag-Drop-Explorer/Models/Binder/AppSettings.cs b/Drag-Drop-Explorer/Models/Binder/AppSettings.cs new file mode 100644 index 0000000..3f35cb0 --- /dev/null +++ b/Drag-Drop-Explorer/Models/Binder/AppSettings.cs @@ -0,0 +1,44 @@ +using Microsoft.Extensions.Configuration; +using System.Text.Json; + +namespace View_by_Distance.Drag_Drop_Explorer.Models.Binder; + +public class AppSettings +{ + +#nullable disable + + public string Company { get; set; } + public int? MaxDegreeOfParallelism { 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.MaxDegreeOfParallelism.Value, + 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/Drag-Drop-Explorer/Models/MatchNginx.cs b/Drag-Drop-Explorer/Models/MatchNginx.cs new file mode 100644 index 0000000..74913e7 --- /dev/null +++ b/Drag-Drop-Explorer/Models/MatchNginx.cs @@ -0,0 +1,4 @@ +namespace View_by_Distance.Drag_Drop_Explorer; + +public record MatchNginx(string Name, string Type, DateTime MTime, long Size, string ConvertedPath) +{ } \ No newline at end of file diff --git a/Drag-Drop-Explorer/Program.cs b/Drag-Drop-Explorer/Program.cs new file mode 100644 index 0000000..b9465ee --- /dev/null +++ b/Drag-Drop-Explorer/Program.cs @@ -0,0 +1,15 @@ +namespace View_by_Distance.Drag_Drop_Explorer; + +static class Program +{ + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + ApplicationConfiguration.Initialize(); + Application.Run(new Form()); + } + +} \ No newline at end of file diff --git a/Drag-Drop-Explorer/appsettings.Development.json b/Drag-Drop-Explorer/appsettings.Development.json new file mode 100644 index 0000000..be482be --- /dev/null +++ b/Drag-Drop-Explorer/appsettings.Development.json @@ -0,0 +1,11 @@ +{ + "Logging": { + "LogLevel": { + "Log4netProvider": "Debug" + } + }, + "MaxDegreeOfParallelism": 6, + "Serilog": { + "MinimumLevel": "Debug" + } +} \ No newline at end of file diff --git a/Drag-Drop-Explorer/appsettings.json b/Drag-Drop-Explorer/appsettings.json new file mode 100644 index 0000000..4be1117 --- /dev/null +++ b/Drag-Drop-Explorer/appsettings.json @@ -0,0 +1,50 @@ +{ + "Company": "Mike Phares", + "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" +} \ No newline at end of file diff --git a/View-by-Distance-MKLink-Console.sln b/View-by-Distance-MKLink-Console.sln index b704951..4199953 100644 --- a/View-by-Distance-MKLink-Console.sln +++ b/View-by-Distance-MKLink-Console.sln @@ -45,6 +45,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Delete-By-Distinct", "Delet EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PhotoPrism", "PhotoPrism\PhotoPrism.csproj", "{DF4B0776-E0E5-4220-8721-8D1E491FF263}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Drag-Drop-Explorer", "Drag-Drop-Explorer\Drag-Drop-Explorer.csproj", "{986B009B-2937-4624-AC9C-13806868DB8C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -138,5 +140,9 @@ Global {DF4B0776-E0E5-4220-8721-8D1E491FF263}.Debug|Any CPU.Build.0 = Debug|Any CPU {DF4B0776-E0E5-4220-8721-8D1E491FF263}.Release|Any CPU.ActiveCfg = Release|Any CPU {DF4B0776-E0E5-4220-8721-8D1E491FF263}.Release|Any CPU.Build.0 = Release|Any CPU + {986B009B-2937-4624-AC9C-13806868DB8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {986B009B-2937-4624-AC9C-13806868DB8C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {986B009B-2937-4624-AC9C-13806868DB8C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {986B009B-2937-4624-AC9C-13806868DB8C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal