From 662ddfc44d2342c223879e5296805431214667d4 Mon Sep 17 00:00:00 2001 From: Mike Phares Date: Mon, 3 Jul 2023 15:53:10 -0700 Subject: [PATCH] Drag-Drop-Set-Property-Item --- .vscode/launch.json | 43 +++- Drag-Drop-Move/DragDropMove.Designer.cs | 4 +- Drag-Drop-Move/DragDropMove.cs | 4 +- Drag-Drop-Move/Models/AppSettings.cs | 19 +- Drag-Drop-Move/Models/Binder/AppSettings.cs | 14 +- Drag-Drop-Move/Program.cs | 2 +- .../.vscode/launch.json | 26 ++ .../.vscode/tasks.json | 41 ++++ .../Drag-Drop-Set-Property-Item.csproj | 51 ++++ .../DragDropSetPropertyItem.Designer.cs | 39 +++ .../DragDropSetPropertyItem.cs | 228 ++++++++++++++++++ .../Models/AppSettings.cs | 18 ++ .../Models/Binder/AppSettings.cs | 52 ++++ Drag-Drop-Set-Property-Item/Program.cs | 15 ++ .../appsettings.Development.json | 11 + Drag-Drop-Set-Property-Item/appsettings.json | 54 +++++ Face/Models/_D_Face.cs | 18 +- .../OffsetDateTimeOriginal.cs | 28 +-- Resize/Models/_C_Resize.cs | 9 - Shared/Models/Stateless/Methods/IProperty.cs | 13 + Shared/Models/Stateless/Methods/Property.cs | 34 +++ View-by-Distance-MKLink-Console.sln | 6 + 22 files changed, 652 insertions(+), 77 deletions(-) create mode 100644 Drag-Drop-Set-Property-Item/.vscode/launch.json create mode 100644 Drag-Drop-Set-Property-Item/.vscode/tasks.json create mode 100644 Drag-Drop-Set-Property-Item/Drag-Drop-Set-Property-Item.csproj create mode 100644 Drag-Drop-Set-Property-Item/DragDropSetPropertyItem.Designer.cs create mode 100644 Drag-Drop-Set-Property-Item/DragDropSetPropertyItem.cs create mode 100644 Drag-Drop-Set-Property-Item/Models/AppSettings.cs create mode 100644 Drag-Drop-Set-Property-Item/Models/Binder/AppSettings.cs create mode 100644 Drag-Drop-Set-Property-Item/Program.cs create mode 100644 Drag-Drop-Set-Property-Item/appsettings.Development.json create mode 100644 Drag-Drop-Set-Property-Item/appsettings.json diff --git a/.vscode/launch.json b/.vscode/launch.json index 4858671..3448e46 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -157,6 +157,23 @@ "stopAtEntry": false, "requireExactSource": false }, + { + "name": "Drag-Drop-Set-Property-Item", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + "program": "${workspaceFolder}/Drag-Drop-Set-Property-Item/bin/Debug/net7.0-windows/win-x64/Drag-Drop-Set-Property-Item.dll", + "args": [ + "s" + ], + "env": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "cwd": "${workspaceFolder}", + "console": "integratedTerminal", + "stopAtEntry": false, + "requireExactSource": false + }, { "name": "Instance", "type": "coreclr", @@ -505,4 +522,28 @@ // _ Import of Partial info // ` Want to find // ~ Approxomite age -// + Approxomite age and have at least one image \ No newline at end of file +// + Approxomite age and have at least one image +// XPAuthor = 40093 | [3-1] ("Picasa") +// Artist = 315 | [182-3] ("Picasa", "unknown", " ") +// Kristy, Mike, Tracy, Mackenzie, Julie, Patrick, ... +// XPKeywords = 40094 | Vulgar !9, Blurry !4, Duplicate !3, Irrelevant !2, Review !1, Slideshow [0] +// XPSubject = 40095 | Family Pictures, Scanned [2-1] (" ") +// XPComment = 40092 | [9-2] ("\uFFFD", " ") +// Rating = 18246 | [52-1] ("0") +// UserComment = 37510 | [3570-^^^] +// XPTitle = 40091 | [24-24] ("Logan and his Doggie", ...) +// ImageDescription = 270 | [2135-5^] 4+37+82+1354+647+11 ("Camera 360", "OLYMPUS DIGITAL CAMERA ", "SAMSUNG ", " ", " ") +// int artist = (int)IExif.Tags.Artist; +// int fileSource = (int)IExif.Tags.FileSource; +// int userComment = (int)IExif.Tags.UserComment; +// 0x9c9b XPTitle int8u IFD0 (tags 0x9c9b-0x9c9f are used by Windows Explorer; special characters in these values are converted to UTF-8 by default, or Windows Latin1 with the -L option. XPTitle is ignored by Windows Explorer if ImageDescription exists) +// 0x9c9c XPComment int8u IFD0 +// 0x9c9d XPAuthor int8u IFD0 (ignored by Windows Explorer if Artist exists) +// 0x9c9e XPKeywords int8u IFD0 +// 0x9c9f XPSubject int8u IFD0 +// 0xa300 FileSource undef ExifIFD 1 = Film Scanner +// 2 = Reflection Print Scanner +// 3 = Digital Camera +// "\x03\x00\x00\x00" = Sigma Digital Camera +// 0x9286 UserComment undef ExifIFD +// 0x013b Artist string IFD0 (becomes a list-type tag when the MWG module is loaded) diff --git a/Drag-Drop-Move/DragDropMove.Designer.cs b/Drag-Drop-Move/DragDropMove.Designer.cs index e272c77..5c7d542 100644 --- a/Drag-Drop-Move/DragDropMove.Designer.cs +++ b/Drag-Drop-Move/DragDropMove.Designer.cs @@ -1,4 +1,4 @@ -namespace View_by_Distance.Drag_Drop_Explorer; +namespace View_by_Distance.Drag.Drop.Move; partial class DragDropMove { @@ -32,7 +32,7 @@ partial class DragDropMove this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(640, 100); this.StartPosition = FormStartPosition.CenterScreen; - this.Text = "Drag Drop Explorer"; + this.Text = "Drag Drop Move"; } #endregion diff --git a/Drag-Drop-Move/DragDropMove.cs b/Drag-Drop-Move/DragDropMove.cs index e456725..02823cb 100644 --- a/Drag-Drop-Move/DragDropMove.cs +++ b/Drag-Drop-Move/DragDropMove.cs @@ -4,11 +4,11 @@ using Serilog; using System.Diagnostics; using System.Reflection; using System.Text.Json; -using View_by_Distance.Drag_Drop_Explorer.Models; +using View_by_Distance.Drag.Drop.Move.Models; using View_by_Distance.Shared.Models.Stateless.Methods; using WindowsShortcutFactory; -namespace View_by_Distance.Drag_Drop_Explorer; +namespace View_by_Distance.Drag.Drop.Move; public partial class DragDropMove : Form { diff --git a/Drag-Drop-Move/Models/AppSettings.cs b/Drag-Drop-Move/Models/AppSettings.cs index e7114a7..07f487e 100644 --- a/Drag-Drop-Move/Models/AppSettings.cs +++ b/Drag-Drop-Move/Models/AppSettings.cs @@ -1,23 +1,12 @@ using System.Text.Json; -using System.Text.Json.Serialization; -namespace View_by_Distance.Drag_Drop_Explorer.Models; +namespace View_by_Distance.Drag.Drop.Move.Models; -public class AppSettings +public record AppSettings(string Company, + int MaxDegreeOfParallelism, + string WorkingDirectoryName) { - 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 }); diff --git a/Drag-Drop-Move/Models/Binder/AppSettings.cs b/Drag-Drop-Move/Models/Binder/AppSettings.cs index 3f35cb0..ff613f6 100644 --- a/Drag-Drop-Move/Models/Binder/AppSettings.cs +++ b/Drag-Drop-Move/Models/Binder/AppSettings.cs @@ -1,18 +1,14 @@ using Microsoft.Extensions.Configuration; using System.Text.Json; -namespace View_by_Distance.Drag_Drop_Explorer.Models.Binder; +namespace View_by_Distance.Drag.Drop.Move.Models.Binder; public class AppSettings { -#nullable disable - - public string Company { get; set; } + public string? Company { get; set; } public int? MaxDegreeOfParallelism { get; set; } - public string WorkingDirectoryName { get; set; } - -#nullable restore + public string? WorkingDirectoryName { get; set; } public override string ToString() { @@ -23,8 +19,12 @@ public class AppSettings private static Models.AppSettings Get(AppSettings? appSettings) { Models.AppSettings result; + if (appSettings?.Company is null) + throw new NullReferenceException(nameof(appSettings.Company)); if (appSettings?.MaxDegreeOfParallelism is null) throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism)); + if (appSettings?.WorkingDirectoryName is null) + throw new NullReferenceException(nameof(appSettings.WorkingDirectoryName)); result = new( appSettings.Company, appSettings.MaxDegreeOfParallelism.Value, diff --git a/Drag-Drop-Move/Program.cs b/Drag-Drop-Move/Program.cs index 057901c..36aadf2 100644 --- a/Drag-Drop-Move/Program.cs +++ b/Drag-Drop-Move/Program.cs @@ -1,4 +1,4 @@ -namespace View_by_Distance.Drag_Drop_Explorer; +namespace View_by_Distance.Drag.Drop.Move; public class Program { diff --git a/Drag-Drop-Set-Property-Item/.vscode/launch.json b/Drag-Drop-Set-Property-Item/.vscode/launch.json new file mode 100644 index 0000000..de44254 --- /dev/null +++ b/Drag-Drop-Set-Property-Item/.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-Set-Property-Item/.vscode/tasks.json b/Drag-Drop-Set-Property-Item/.vscode/tasks.json new file mode 100644 index 0000000..570fdd9 --- /dev/null +++ b/Drag-Drop-Set-Property-Item/.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-Set-Property-Item/Drag-Drop-Set-Property-Item.csproj b/Drag-Drop-Set-Property-Item/Drag-Drop-Set-Property-Item.csproj new file mode 100644 index 0000000..43727a5 --- /dev/null +++ b/Drag-Drop-Set-Property-Item/Drag-Drop-Set-Property-Item.csproj @@ -0,0 +1,51 @@ + + + enable + 10.0 + enable + WinExe + win-x64 + net7.0-windows + true + c64a15ed-0ba3-4378-8f80-0c19d0531747 + + + true + true + true + + + Windows + + + OSX + + + Linux + + + + + + + + + + + + + + + + + + + + + Always + + + Always + + + \ No newline at end of file diff --git a/Drag-Drop-Set-Property-Item/DragDropSetPropertyItem.Designer.cs b/Drag-Drop-Set-Property-Item/DragDropSetPropertyItem.Designer.cs new file mode 100644 index 0000000..d7f5993 --- /dev/null +++ b/Drag-Drop-Set-Property-Item/DragDropSetPropertyItem.Designer.cs @@ -0,0 +1,39 @@ +namespace View_by_Distance.Drag.Drop.Set.Item; + +partial class DragDropSetPropertyItem +{ + /// + /// 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 = "Drag Drop Set Property Item"; + } + + #endregion +} diff --git a/Drag-Drop-Set-Property-Item/DragDropSetPropertyItem.cs b/Drag-Drop-Set-Property-Item/DragDropSetPropertyItem.cs new file mode 100644 index 0000000..219850e --- /dev/null +++ b/Drag-Drop-Set-Property-Item/DragDropSetPropertyItem.cs @@ -0,0 +1,228 @@ +using Microsoft.Extensions.Configuration; +using Phares.Shared; +using Serilog; +using System.Diagnostics; +using System.Drawing.Imaging; +using System.Reflection; +using System.Text; +using System.Text.Json; +using View_by_Distance.Drag.Drop.Set.Item.Models; +using View_by_Distance.Shared.Models.Stateless; +using View_by_Distance.Shared.Models.Stateless.Methods; + +namespace View_by_Distance.Drag.Drop.Set.Item; + +public partial class DragDropSetPropertyItem : Form +{ + + private readonly ILogger _Logger; + 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 DragDropSetPropertyItem() + { + InitializeComponent(); + ILogger logger; + AppSettings appSettings; + string workingDirectory; + IsEnvironment isEnvironment; + IConfigurationRoot configurationRoot; + 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) + .AddUserSecrets(); + configurationRoot = configurationBuilder.Build(); + appSettings = Models.Binder.AppSettings.Get(configurationRoot); + if (string.IsNullOrEmpty(appSettings.WorkingDirectoryName)) + throw new Exception("Working path name must have parentDirectory setTo!"); + 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; + _IsEnvironment = isEnvironment; + _WorkingDirectory = workingDirectory; + _ProgressBar = new() { TabIndex = 4, Location = new(5, 5), Dock = DockStyle.Top, Visible = false }; + string json = JsonSerializer.Serialize(_AppSettings, new JsonSerializerOptions { WriteIndented = true }); + _FirstTextBox = new() { TabIndex = 1, Text = _IsEnvironment.Profile, Location = new(5, 5), Dock = DockStyle.Top }; + _PathTextBox = new() { TabIndex = 2, Text = _AppSettings.WorkingDirectoryName, Location = new(5, 5), Dock = DockStyle.Top }; + _JsonTextBox = new() { TabIndex = 3, Text = json, Multiline = true, MinimumSize = new(1, 80), Location = new(5, 5), Dock = DockStyle.Top }; + Load += new EventHandler(Form1_Load); + Controls.Add(_ProgressBar); + Controls.Add(_JsonTextBox); + Controls.Add(_PathTextBox); + Controls.Add(_FirstTextBox); + } + + private void Form1_Load(object? sender, EventArgs e) + { + try + { + AllowDrop = true; + DragDrop += new DragEventHandler(Form1_DragDrop); + DragEnter += new DragEventHandler(Form1_DragEnter); + if (_WorkingDirectory is null) + { } + } + catch (Exception) + { + throw; + } + } + + private 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; + } + } + + private void SetMessage(string message) + { + _Logger.Information(message); + _JsonTextBox.Text = message; + } + + private static List<(string, int, DateTime?, short?, string?)> GetCollection(ASCIIEncoding asciiEncoding, int tagId, List files) + { + List<(string, int, DateTime?, short?, string?)> results = new(); + string? value; + PropertyItem? propertyItem; + Shared.Models.Property property; + foreach (string file in files) + { + property = Property.Models.A_Property.GetImageProperty(file); + if (property.Id is null) + continue; + using Image image = Image.FromFile(file); + if (!image.PropertyIdList.Contains(tagId)) + (propertyItem, value) = (null, null); + else + { + propertyItem = image.GetPropertyItem(tagId); + if (propertyItem?.Value is null) + value = null; + else + { + if (propertyItem.Type == 2) + value = asciiEncoding.GetString(propertyItem.Value).Trim('\0', ' '); + else if (propertyItem.Type == 1) + value = Encoding.Unicode.GetString(propertyItem.Value).Trim('\0', ' '); + else + value = null; + } + } + results.Add((file, property.Id.Value, property.DateTimeOriginal, propertyItem?.Type, value)); + } + if (files.Count != results.Count) + throw new NotSupportedException(); + return results; + } + + private void SetPropertyItem(string setTo, int tagId, short type, ConstructorInfo constructorInfo, List<(string, int, DateTime?, short?, string?)> collection) + { + Bitmap bitmap; + string checkFile; + PropertyItem? propertyItem; + Shared.Models.Property property; + foreach ((string file, int id, DateTime? dateTimeOriginal, short? propertyItemType, string? value) in collection) + { + if (propertyItemType is not null && propertyItemType.Value != type) + throw new NotSupportedException(); + if ((dateTimeOriginal is null || !string.IsNullOrEmpty(value) || value == setTo) && !_AppSettings.IgnoreRulesKeyWords.Contains(setTo)) + continue; + checkFile = $"{file}.exif"; + propertyItem = IProperty.GetPropertyItem(constructorInfo, tagId, type, setTo); + bitmap = new(file); + bitmap.SetPropertyItem(propertyItem); + bitmap.Save(checkFile); + bitmap.Dispose(); + property = Property.Models.A_Property.GetImageProperty(checkFile); + if (property.Id is null || property.Id.Value != id) + throw new NotSupportedException(); + File.Delete(file); + File.Move(checkFile, file); + } + } + + private void SetPropertyItem(string setTo, List files) + { + short type = 1; + ASCIIEncoding asciiEncoding = new(); + int xpKeywords = (int)IExif.Tags.XPKeywords; + ConstructorInfo? constructorInfo = typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, Array.Empty(), null) ?? throw new Exception(); + List<(string, int, DateTime?, short?, string?)> collection = GetCollection(asciiEncoding, xpKeywords, files); + if (!collection.Any()) + SetMessage("No data"); + else + SetPropertyItem(setTo, xpKeywords, type, constructorInfo, collection); + } + + private void SetPropertyItem(string[] paths, string setTo) + { + FileInfo fileInfo; + List files = new(); + foreach (string path in paths.OrderBy(l => l)) + { + fileInfo = new(path); + if (fileInfo.Exists) + files.Add(path); + else + { + if (paths.Length != 1) + break; + files.AddRange(Directory.GetFiles(path, "*", SearchOption.TopDirectoryOnly)); + } + } + if (!files.Any()) + SetMessage("No data"); + else + SetPropertyItem(setTo, files); + } + + private void SetPropertyItem(string[] paths) + { + if (string.IsNullOrEmpty(_FirstTextBox.Text) || !_AppSettings.ValidKeyWords.Contains(_FirstTextBox.Text)) + SetMessage($"[{_FirstTextBox.Text}] is not valid!"); + else + SetPropertyItem(paths, _FirstTextBox.Text); + } + + private void Form1_DragDrop(object? sender, DragEventArgs e) + { + try + { + if (e.Data is not null && e.Data.GetData(DataFormats.FileDrop) is string[] paths && paths.Any()) + SetPropertyItem(paths); + else + { + _PathTextBox.Text = string.Empty; + SetMessage("No data"); + } + } + catch (Exception) + { + throw; + } + } + +} \ No newline at end of file diff --git a/Drag-Drop-Set-Property-Item/Models/AppSettings.cs b/Drag-Drop-Set-Property-Item/Models/AppSettings.cs new file mode 100644 index 0000000..bcf392f --- /dev/null +++ b/Drag-Drop-Set-Property-Item/Models/AppSettings.cs @@ -0,0 +1,18 @@ +using System.Text.Json; + +namespace View_by_Distance.Drag.Drop.Set.Item.Models; + +public record AppSettings(string Company, + string[] IgnoreRulesKeyWords, + int MaxDegreeOfParallelism, + string[] ValidKeyWords, + string 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-Set-Property-Item/Models/Binder/AppSettings.cs b/Drag-Drop-Set-Property-Item/Models/Binder/AppSettings.cs new file mode 100644 index 0000000..188d65f --- /dev/null +++ b/Drag-Drop-Set-Property-Item/Models/Binder/AppSettings.cs @@ -0,0 +1,52 @@ +using Microsoft.Extensions.Configuration; +using System.Text.Json; + +namespace View_by_Distance.Drag.Drop.Set.Item.Models.Binder; + +public class AppSettings +{ + + public string? Company { get; set; } + public string[]? IgnoreRulesKeyWords { get; set; } + public int? MaxDegreeOfParallelism { get; set; } + public string[]? ValidKeyWords { get; set; } + public string? WorkingDirectoryName { get; set; } + + 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?.Company is null) + throw new NullReferenceException(nameof(appSettings.Company)); + if (appSettings?.IgnoreRulesKeyWords is null) + throw new NullReferenceException(nameof(appSettings.IgnoreRulesKeyWords)); + if (appSettings?.MaxDegreeOfParallelism is null) + throw new NullReferenceException(nameof(appSettings.MaxDegreeOfParallelism)); + if (appSettings?.ValidKeyWords is null) + throw new NullReferenceException(nameof(appSettings.ValidKeyWords)); + if (appSettings?.WorkingDirectoryName is null) + throw new NullReferenceException(nameof(appSettings.WorkingDirectoryName)); + result = new( + appSettings.Company, + appSettings.IgnoreRulesKeyWords, + appSettings.MaxDegreeOfParallelism.Value, + appSettings.ValidKeyWords, + 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-Set-Property-Item/Program.cs b/Drag-Drop-Set-Property-Item/Program.cs new file mode 100644 index 0000000..c3ac35b --- /dev/null +++ b/Drag-Drop-Set-Property-Item/Program.cs @@ -0,0 +1,15 @@ +namespace View_by_Distance.Drag.Drop.Set.Item; + +public class Program +{ + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + ApplicationConfiguration.Initialize(); + Application.Run(new DragDropSetPropertyItem()); + } + +} \ No newline at end of file diff --git a/Drag-Drop-Set-Property-Item/appsettings.Development.json b/Drag-Drop-Set-Property-Item/appsettings.Development.json new file mode 100644 index 0000000..be482be --- /dev/null +++ b/Drag-Drop-Set-Property-Item/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-Set-Property-Item/appsettings.json b/Drag-Drop-Set-Property-Item/appsettings.json new file mode 100644 index 0000000..4ad5bd3 --- /dev/null +++ b/Drag-Drop-Set-Property-Item/appsettings.json @@ -0,0 +1,54 @@ +{ + "Company": "Mike Phares", + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Log4netProvider": "Debug", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "IgnoreRulesKeyWords": [], + "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" + } + }, + "ValidKeyWords": [ + "Review" + ], + "WorkingDirectoryName": "PharesApps" +} \ No newline at end of file diff --git a/Face/Models/_D_Face.cs b/Face/Models/_D_Face.cs index 2f8f0dd..4e2ca01 100644 --- a/Face/Models/_D_Face.cs +++ b/Face/Models/_D_Face.cs @@ -152,22 +152,12 @@ public class D_Face #pragma warning disable CA1416 - private PropertyItem GetPropertyItem(int id, string value) - { - PropertyItem result = (PropertyItem)_ConstructorInfo.Invoke(null); - byte[] bytes = C_Resize.GetBytes(value); - result.Id = id; - result.Len = value.Length + 1; - result.Type = 2; - result.Value = bytes; - return result; - } - private void SaveFaces(FileHolder resizedFileHolder, List<(Shared.Models.Face, FileInfo?, string, bool)> collection) { int width; int height; Bitmap bitmap; + short type = 2; Graphics graphics; Location? location; Rectangle rectangle; @@ -200,11 +190,11 @@ public class D_Face { using (graphics = Graphics.FromImage(bitmap)) graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel); - propertyItem = GetPropertyItem(fileSource, locationJson); + propertyItem = Shared.Models.Stateless.Methods.IProperty.GetPropertyItem(_ConstructorInfo, fileSource, type, locationJson); bitmap.SetPropertyItem(propertyItem); - propertyItem = GetPropertyItem(artist, outputResolutionJson); + propertyItem = Shared.Models.Stateless.Methods.IProperty.GetPropertyItem(_ConstructorInfo, artist, type, outputResolutionJson); bitmap.SetPropertyItem(propertyItem); - propertyItem = GetPropertyItem(userComment, faceEncodingJson); + propertyItem = Shared.Models.Stateless.Methods.IProperty.GetPropertyItem(_ConstructorInfo, userComment, type, faceEncodingJson); bitmap.SetPropertyItem(propertyItem); bitmap.Save(fileInfo.FullName, _ImageCodecInfo, _EncoderParameters); } diff --git a/Offset-Date-Time-Original/OffsetDateTimeOriginal.cs b/Offset-Date-Time-Original/OffsetDateTimeOriginal.cs index 555885c..6b8aa63 100644 --- a/Offset-Date-Time-Original/OffsetDateTimeOriginal.cs +++ b/Offset-Date-Time-Original/OffsetDateTimeOriginal.cs @@ -60,30 +60,6 @@ public class OffsetDateTimeOriginal { } } - private static byte[] GetBytes(string value) - { - byte[] results = new byte[value.Length + 1]; - for (int i = 0; i < value.Length; i++) - results[i] = (byte)value[i]; - results[value.Length] = 0x00; - return results; - } - -#pragma warning disable CA1416 - - private static PropertyItem GetPropertyItem(ConstructorInfo constructorInfo, int id, string value) - { - PropertyItem result = (PropertyItem)constructorInfo.Invoke(null); - byte[] bytes = GetBytes(value); - result.Id = id; - result.Len = value.Length + 1; - result.Type = 2; - result.Value = bytes; - return result; - } - -#pragma warning restore CA1416 - private static List<(string, int, DateTime)> GetCollection(string checkDirectory, DateTime minimumDateTime, DateTime maximumDateTime, long ticks) { List<(string, int, DateTime)> results = new(); @@ -112,6 +88,7 @@ public class OffsetDateTimeOriginal private static void DateFix(string sourceDirectory, string checkDirectory, DateTime minimumDateTime, DateTime maximumDateTime, long ticks) { Bitmap bitmap; + short type = 2; string checkFile; PropertyItem? propertyItem; string? ticksDirectory = null; @@ -126,7 +103,6 @@ public class OffsetDateTimeOriginal break; } ticks++; - } List<(string, int, DateTime)> collection = GetCollection(checkDirectory, minimumDateTime, maximumDateTime, ticks); ConstructorInfo? constructorInfo = typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, Array.Empty(), null) ?? throw new Exception(); @@ -141,7 +117,7 @@ public class OffsetDateTimeOriginal checkFile = Path.Combine(ticksDirectory, Path.GetFileName(file)); if (File.Exists(checkFile)) continue; - propertyItem = GetPropertyItem(constructorInfo, dateTimeOriginal, dateTime.ToString("yyyy:MM:dd HH:mm:ss")); + propertyItem = Shared.Models.Stateless.Methods.IProperty.GetPropertyItem(constructorInfo, dateTimeOriginal, type, dateTime.ToString("yyyy:MM:dd HH:mm:ss")); bitmap = new(file); bitmap.SetPropertyItem(propertyItem); bitmap.Save(checkFile); diff --git a/Resize/Models/_C_Resize.cs b/Resize/Models/_C_Resize.cs index 8c3fbd0..3d20c92 100644 --- a/Resize/Models/_C_Resize.cs +++ b/Resize/Models/_C_Resize.cs @@ -488,13 +488,4 @@ public class C_Resize return results; } - public static byte[] GetBytes(string value) - { - byte[] results = new byte[value.Length + 1]; - for (int i = 0; i < value.Length; i++) - results[i] = (byte)value[i]; - results[value.Length] = 0x00; - return results; - } - } \ No newline at end of file diff --git a/Shared/Models/Stateless/Methods/IProperty.cs b/Shared/Models/Stateless/Methods/IProperty.cs index 3c4488d..f4b7b0f 100644 --- a/Shared/Models/Stateless/Methods/IProperty.cs +++ b/Shared/Models/Stateless/Methods/IProperty.cs @@ -1,3 +1,6 @@ +using System.Drawing.Imaging; +using System.Reflection; + namespace View_by_Distance.Shared.Models.Stateless.Methods; public interface IProperty @@ -101,4 +104,14 @@ public interface IProperty static List GetDateTimes(DateTime creationTime, DateTime lastWriteTime, DateTime? dateTime, DateTime? dateTimeDigitized, DateTime? dateTimeFromName, DateTime? dateTimeOriginal, DateTime? gpsDateStamp) => Property.GetDateTimes(creationTime, lastWriteTime, dateTime, dateTimeDigitized, dateTimeFromName, dateTimeOriginal, gpsDateStamp); + byte[] TestStatic_GetBytes(string value) => + GetBytes(value); + static byte[] GetBytes(string value) => + Property.GetBytes(value); + + PropertyItem TestStatic_GetPropertyItem(ConstructorInfo constructorInfo, int id, short type, string value) => + GetPropertyItem(constructorInfo, id, type, value); + static PropertyItem GetPropertyItem(ConstructorInfo constructorInfo, int id, short type, string value) => + Property.GetPropertyItem(constructorInfo, id, type, value); + } \ No newline at end of file diff --git a/Shared/Models/Stateless/Methods/Property.cs b/Shared/Models/Stateless/Methods/Property.cs index 49b245a..1f7fd7d 100644 --- a/Shared/Models/Stateless/Methods/Property.cs +++ b/Shared/Models/Stateless/Methods/Property.cs @@ -2,6 +2,7 @@ using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.Globalization; +using System.Reflection; using System.Runtime.InteropServices; using System.Text; @@ -491,6 +492,30 @@ internal abstract class Property return new(dateTimeOriginal, dateTimes, id, message); } + internal static PropertyItem GetPropertyItem(ConstructorInfo constructorInfo, int id, short type, string value) + { + PropertyItem result = (PropertyItem)constructorInfo.Invoke(null); + int length; + byte[] bytes; + if (type == 2) + { + bytes = GetBytes(value); + length = value.Length + 1; + } + else if (type == 1) + { + bytes = Encoding.Unicode.GetBytes($"{value}\0"); + length = bytes.Length; + } + else + throw new NotSupportedException(); + result.Id = id; + result.Len = length; + result.Type = type; + result.Value = bytes; + return result; + } + #pragma warning restore CA1416 internal static DateTime? GetDateTime(string dateTimeFormat, string? value) @@ -508,4 +533,13 @@ internal abstract class Property return result; } + internal static byte[] GetBytes(string value) + { + byte[] results = new byte[value.Length + 1]; + for (int i = 0; i < value.Length; i++) + results[i] = (byte)value[i]; + results[value.Length] = 0x00; + return results; + } + } \ No newline at end of file diff --git a/View-by-Distance-MKLink-Console.sln b/View-by-Distance-MKLink-Console.sln index 75ea85e..bd33f10 100644 --- a/View-by-Distance-MKLink-Console.sln +++ b/View-by-Distance-MKLink-Console.sln @@ -21,6 +21,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Drag-Drop-Move", "Drag-Drop EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Drag-Drop-Search", "Drag-Drop-Search\Drag-Drop-Search.csproj", "{87EB76BC-32A9-4FD0-922A-BD7E9B6E7D8B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Drag-Drop-Set-Property-Item", "Drag-Drop-Set-Property-Item\Drag-Drop-Set-Property-Item.csproj", "{BFF75D8C-48E6-4B84-B480-3E5A4F9B2DD8}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicate-Search", "Duplicate-Search\Duplicate-Search.csproj", "{48E87D9B-B802-467A-BDC7-E86F7FD01D5C}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Face", "Face\Face.csproj", "{A12E19E5-59C0-40D4-B807-DF1334D4906D}" @@ -206,5 +208,9 @@ Global {6B68758E-1AF1-401F-844A-C1199A0B6303}.Debug|Any CPU.Build.0 = Debug|Any CPU {6B68758E-1AF1-401F-844A-C1199A0B6303}.Release|Any CPU.ActiveCfg = Release|Any CPU {6B68758E-1AF1-401F-844A-C1199A0B6303}.Release|Any CPU.Build.0 = Release|Any CPU + {BFF75D8C-48E6-4B84-B480-3E5A4F9B2DD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BFF75D8C-48E6-4B84-B480-3E5A4F9B2DD8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BFF75D8C-48E6-4B84-B480-3E5A4F9B2DD8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BFF75D8C-48E6-4B84-B480-3E5A4F9B2DD8}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal