Drag-Drop-Move
This commit is contained in:
parent
07ecbeb76c
commit
e6acce3852
17
.vscode/launch.json
vendored
17
.vscode/launch.json
vendored
@ -125,6 +125,23 @@
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Drag-Drop-Move",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
"program": "${workspaceFolder}/Drag-Drop-Move/bin/Debug/net7.0-windows/win-x64/Drag-Drop-Move.dll",
|
||||
"args": [
|
||||
"s"
|
||||
],
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"console": "integratedTerminal",
|
||||
"stopAtEntry": false,
|
||||
"requireExactSource": false
|
||||
},
|
||||
{
|
||||
"name": "Instance",
|
||||
"type": "coreclr",
|
||||
|
26
Drag-Drop-Move/.vscode/launch.json
vendored
Normal file
26
Drag-Drop-Move/.vscode/launch.json
vendored
Normal file
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
41
Drag-Drop-Move/.vscode/tasks.json
vendored
Normal file
41
Drag-Drop-Move/.vscode/tasks.json
vendored
Normal file
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
50
Drag-Drop-Move/Drag-Drop-Move.csproj
Normal file
50
Drag-Drop-Move/Drag-Drop-Move.csproj
Normal file
@ -0,0 +1,50 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
|
||||
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
|
||||
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsWindows)'=='true'">
|
||||
<DefineConstants>Windows</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsOSX)'=='true'">
|
||||
<DefineConstants>OSX</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(IsLinux)'=='true'">
|
||||
<DefineConstants>Linux</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'browser-wasm'">
|
||||
<SupportedPlatform Include="browser" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Humanizer.Core" Version="2.14.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
|
||||
<PackageReference Include="Serilog.Settings.Configuration" Version="3.4.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||
<PackageReference Include="Serilog" Version="2.12.0" />
|
||||
<PackageReference Include="WindowsShortcutFactory" Version="1.1.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Shared\View-by-Distance.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="appsettings.Development.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="appsettings.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
39
Drag-Drop-Move/DragDropMove.Designer.cs
generated
Normal file
39
Drag-Drop-Move/DragDropMove.Designer.cs
generated
Normal file
@ -0,0 +1,39 @@
|
||||
namespace View_by_Distance.Drag_Drop_Explorer;
|
||||
|
||||
partial class DragDropMove
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
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 Explorer";
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
195
Drag-Drop-Move/DragDropMove.cs
Normal file
195
Drag-Drop-Move/DragDropMove.cs
Normal file
@ -0,0 +1,195 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Phares.Shared;
|
||||
using Serilog;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Drag_Drop_Explorer.Models;
|
||||
using View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
using WindowsShortcutFactory;
|
||||
|
||||
namespace View_by_Distance.Drag_Drop_Explorer;
|
||||
|
||||
public partial class DragDropMove : 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 DragDropMove()
|
||||
{
|
||||
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);
|
||||
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<DragDropMove>();
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
textBox.Text = GetConverted(textBox.Text);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
private void MovePaths(string[] paths)
|
||||
{
|
||||
string file;
|
||||
string checkFile;
|
||||
string? directory;
|
||||
string? relativePath;
|
||||
string[] directories;
|
||||
string? checkDirectory;
|
||||
string? shellDirectory;
|
||||
int rootDirectoryLength;
|
||||
WindowsShortcut windowsShortcut;
|
||||
_PathTextBox.Text = string.Empty;
|
||||
_FirstTextBox.Text = GetConverted(paths[0]);
|
||||
foreach (string path in paths.OrderBy(l => l))
|
||||
{
|
||||
relativePath = null;
|
||||
shellDirectory = null;
|
||||
if (!path.EndsWith(".lnk"))
|
||||
file = path;
|
||||
else
|
||||
{
|
||||
windowsShortcut = WindowsShortcut.Load(path);
|
||||
if (windowsShortcut.Path is null)
|
||||
continue;
|
||||
file = windowsShortcut.Path;
|
||||
windowsShortcut.Dispose();
|
||||
}
|
||||
directory = Path.GetDirectoryName(file);
|
||||
if (string.IsNullOrEmpty(directory))
|
||||
continue;
|
||||
directories = IPath.GetDirectories(directory);
|
||||
foreach (string directoryName in directories)
|
||||
{
|
||||
checkDirectory = $"{directoryName}-Shell";
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
continue;
|
||||
shellDirectory = checkDirectory;
|
||||
rootDirectoryLength = directoryName.Length;
|
||||
relativePath = file[rootDirectoryLength..];
|
||||
break;
|
||||
}
|
||||
if (string.IsNullOrEmpty(shellDirectory) || string.IsNullOrEmpty(relativePath))
|
||||
continue;
|
||||
checkFile = string.Concat(shellDirectory, relativePath);
|
||||
checkDirectory = Path.GetDirectoryName(checkFile);
|
||||
if (string.IsNullOrEmpty(checkDirectory))
|
||||
continue;
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
if (File.Exists(checkFile))
|
||||
continue;
|
||||
File.Move(file, checkFile);
|
||||
}
|
||||
}
|
||||
|
||||
void Form1_DragDrop(object? sender, DragEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (e.Data is not null && e.Data.GetData(DataFormats.FileDrop) is string[] paths && paths.Any())
|
||||
MovePaths(paths);
|
||||
else
|
||||
{
|
||||
_FirstTextBox.Text = string.Empty;
|
||||
_PathTextBox.Text = string.Empty;
|
||||
_JsonTextBox.Text = string.Empty;
|
||||
_Logger.Information("No data");
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
27
Drag-Drop-Move/Models/AppSettings.cs
Normal file
27
Drag-Drop-Move/Models/AppSettings.cs
Normal file
@ -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;
|
||||
}
|
||||
|
||||
}
|
44
Drag-Drop-Move/Models/Binder/AppSettings.cs
Normal file
44
Drag-Drop-Move/Models/Binder/AppSettings.cs
Normal file
@ -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<AppSettings>();
|
||||
result = Get(appSettings);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
15
Drag-Drop-Move/Program.cs
Normal file
15
Drag-Drop-Move/Program.cs
Normal file
@ -0,0 +1,15 @@
|
||||
namespace View_by_Distance.Drag_Drop_Explorer;
|
||||
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
ApplicationConfiguration.Initialize();
|
||||
Application.Run(new DragDropMove());
|
||||
}
|
||||
|
||||
}
|
11
Drag-Drop-Move/appsettings.Development.json
Normal file
11
Drag-Drop-Move/appsettings.Development.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Log4netProvider": "Debug"
|
||||
}
|
||||
},
|
||||
"MaxDegreeOfParallelism": 6,
|
||||
"Serilog": {
|
||||
"MinimumLevel": "Debug"
|
||||
}
|
||||
}
|
50
Drag-Drop-Move/appsettings.json
Normal file
50
Drag-Drop-Move/appsettings.json
Normal file
@ -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"
|
||||
}
|
@ -271,26 +271,18 @@ public partial class DlibDotNet
|
||||
return result;
|
||||
}
|
||||
|
||||
private void SetMapping(ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, MapLogic mapLogic, Item item, bool? isFocusRelativePath, bool? isIgnoreRelativePath, MappingFromItem mappingFromItem, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, List<Shared.Models.Face> faces)
|
||||
private bool? GetIsFocusModel(ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, MappingFromItem mappingFromItem)
|
||||
{
|
||||
bool? result;
|
||||
string? model;
|
||||
Mapping mapping;
|
||||
bool? isFocusModel;
|
||||
int faceAreaPermyriad;
|
||||
int confidencePercent;
|
||||
bool? inSkipCollection;
|
||||
int normalizedRectangle;
|
||||
string deterministicHashCodeKey;
|
||||
MappingFromFilter mappingFromFilter;
|
||||
MappingFromLocation? mappingFromLocation;
|
||||
IReadOnlyList<MetadataExtractor.Directory> directories;
|
||||
List<LocationContainer<MetadataExtractor.Directory>>? locationContainers;
|
||||
IReadOnlyList<MetadataExtractor.Directory> directories;
|
||||
if (string.IsNullOrEmpty(_Configuration.FocusModel))
|
||||
isFocusModel = null;
|
||||
result = null;
|
||||
else
|
||||
{
|
||||
if (!idToLocationContainers.TryGetValue(mappingFromItem.Id, out locationContainers) || !locationContainers.Any())
|
||||
isFocusModel = false;
|
||||
result = false;
|
||||
else
|
||||
{
|
||||
directories = locationContainers.First().Directories;
|
||||
@ -298,11 +290,25 @@ public partial class DlibDotNet
|
||||
if (model is null)
|
||||
directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(mappingFromItem.ResizedFileHolder.FullName);
|
||||
model = Metadata.Models.Stateless.Methods.IMetadata.GetModel(directories);
|
||||
isFocusModel = model is not null && model.Contains(_Configuration.FocusModel);
|
||||
if (isFocusModel.Value)
|
||||
isFocusModel = true;
|
||||
result = model is not null && model.Contains(_Configuration.FocusModel);
|
||||
if (result.Value)
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void SetMapping(ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, MapLogic mapLogic, Item item, bool? isFocusRelativePath, bool? isIgnoreRelativePath, MappingFromItem mappingFromItem, List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection, List<Shared.Models.Face> faces)
|
||||
{
|
||||
Mapping mapping;
|
||||
int faceAreaPermyriad;
|
||||
int confidencePercent;
|
||||
bool? inSkipCollection;
|
||||
int normalizedRectangle;
|
||||
string deterministicHashCodeKey;
|
||||
MappingFromFilter mappingFromFilter;
|
||||
MappingFromLocation? mappingFromLocation;
|
||||
bool? isFocusModel = GetIsFocusModel(idToLocationContainers, mappingFromItem);
|
||||
foreach (Shared.Models.Face face in faces)
|
||||
{
|
||||
if (item.Property?.Id is null || face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
|
||||
@ -327,6 +333,35 @@ public partial class DlibDotNet
|
||||
}
|
||||
}
|
||||
|
||||
private Mapping GetMapping(ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, MapLogic mapLogic, Item item, bool? isFocusRelativePath, bool? isIgnoreRelativePath, MappingFromItem mappingFromItem)
|
||||
{
|
||||
Mapping result;
|
||||
bool? inSkipCollection;
|
||||
int normalizedRectangle;
|
||||
int faceAreaPermyriad = 0;
|
||||
int confidencePercent = 0;
|
||||
string deterministicHashCodeKey;
|
||||
MappingFromFilter mappingFromFilter;
|
||||
MappingFromLocation? mappingFromLocation;
|
||||
bool? isFocusModel = GetIsFocusModel(idToLocationContainers, mappingFromItem);
|
||||
if (item.Property?.Id is null)
|
||||
{
|
||||
inSkipCollection = null;
|
||||
mappingFromLocation = null;
|
||||
mappingFromFilter = new(isFocusModel, isFocusRelativePath, isIgnoreRelativePath, inSkipCollection);
|
||||
}
|
||||
else
|
||||
{
|
||||
normalizedRectangle = Shared.Models.Stateless.Methods.ILocation.GetNormalizedRectangle(Shared.Models.Stateless.ILocation.Digits);
|
||||
deterministicHashCodeKey = Shared.Models.Stateless.Methods.IMapping.GetDeterministicHashCodeKey(item.Property.Id.Value, Shared.Models.Stateless.ILocation.Digits);
|
||||
mappingFromLocation = new(faceAreaPermyriad, confidencePercent, deterministicHashCodeKey, normalizedRectangle);
|
||||
inSkipCollection = mapLogic.InSkipCollection(item.Property.Id.Value, mappingFromLocation);
|
||||
mappingFromFilter = new(isFocusModel, isFocusRelativePath, isIgnoreRelativePath, inSkipCollection);
|
||||
}
|
||||
result = new(mappingFromItem, mappingFromFilter, mappingFromLocation, mappingFromPhotoPrismCollection: null);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void FullParallelForWork(A_Property propertyLogic,
|
||||
B_Metadata metadata,
|
||||
ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers,
|
||||
@ -677,61 +712,6 @@ public partial class DlibDotNet
|
||||
}
|
||||
}
|
||||
|
||||
private List<Shared.Models.Face> GetFilteredDistinct(string argZero, Container[] containers)
|
||||
{
|
||||
List<Shared.Models.Face> results = new();
|
||||
Item[] filteredItems;
|
||||
List<int> distinct = new();
|
||||
foreach (Container container in containers)
|
||||
{
|
||||
if (!container.Items.Any())
|
||||
continue;
|
||||
if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
|
||||
continue;
|
||||
filteredItems = Shared.Models.Stateless.Methods.IContainer.GetFilterItems(_Configuration.PropertyConfiguration, container);
|
||||
if (!filteredItems.Any())
|
||||
continue;
|
||||
foreach (Item item in filteredItems)
|
||||
{
|
||||
if (item.Property?.Id is null || item.ResizedFileHolder is null)
|
||||
continue;
|
||||
if (distinct.Contains(item.Property.Id.Value))
|
||||
continue;
|
||||
distinct.Add(item.Property.Id.Value);
|
||||
foreach (Shared.Models.Face face in item.Faces)
|
||||
{
|
||||
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
|
||||
continue;
|
||||
results.Add(face);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private List<Item> GetItems(string argZero, Container[] containers)
|
||||
{
|
||||
List<Item> items = new();
|
||||
Item[] filteredItems;
|
||||
foreach (Container container in containers)
|
||||
{
|
||||
if (!container.Items.Any())
|
||||
continue;
|
||||
if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
|
||||
continue;
|
||||
filteredItems = Shared.Models.Stateless.Methods.IContainer.GetFilterItems(_Configuration.PropertyConfiguration, container);
|
||||
if (!filteredItems.Any())
|
||||
continue;
|
||||
foreach (Item item in filteredItems)
|
||||
{
|
||||
if (item.Property?.Id is null || item.ResizedFileHolder is null)
|
||||
continue;
|
||||
items.Add(item);
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
private void SaveFaceDistances(long ticks, MapLogic mapLogic, Mapping[] mappingCollection, string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping, List<FaceDistance> faceDistanceEncodings, FaceDistanceContainer[] faceDistanceContainers)
|
||||
{
|
||||
if (_Log is null)
|
||||
@ -785,36 +765,33 @@ public partial class DlibDotNet
|
||||
SaveFaceDistances(ticks, mapLogic, mappingCollection, dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, idToNormalizedRectangleToMapping, faceDistanceEncodings, faceDistanceContainers);
|
||||
}
|
||||
|
||||
private void MapLogic(string argZero, long ticks, Container[] containers, string a2PeopleSingletonDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, string fPhotoPrismContentDirectory, MapLogic mapLogic, string outputResolution, Dictionary<long, List<int>> personKeyToIds, List<Shared.Models.Face> distinctFilteredFaces, Mapping[] mappingCollection, int totalNotMapped)
|
||||
private void MapLogic(long ticks, Container[] containers, string a2PeopleSingletonDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, string fPhotoPrismContentDirectory, MapLogic mapLogic, string outputResolution, Dictionary<long, List<int>> personKeyToIds, List<Shared.Models.Face> distinctFilteredFaces, Mapping[] distinctFilteredMappingCollection, int totalNotMapped)
|
||||
{
|
||||
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, "()");
|
||||
string d2FacePartsContentDirectory = Path.Combine(d2ResultsFullGroupDirectory, "()");
|
||||
string d2FacePartsContentCollectionDirectory = Path.Combine(d2ResultsFullGroupDirectory, "[()]");
|
||||
string dFacesCollectionDirectory = Path.Combine(dResultsFullGroupDirectory, "[]", _Configuration.PropertyConfiguration.ResultAllInOne);
|
||||
if (mappingCollection.Any())
|
||||
if (distinctFilteredMappingCollection.Any())
|
||||
{
|
||||
Shared.Models.Stateless.Methods.IPath.ChangeDateForEmptyDirectories(d2FacePartsContentDirectory, ticks);
|
||||
Shared.Models.Stateless.Methods.IPath.MakeHiddenIfAllItemsAreHidden(d2FacePartsContentCollectionDirectory);
|
||||
}
|
||||
Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping = Map.Models.Stateless.Methods.IMapLogic.GetIdToNormalizedRectangleToFace(mappingCollection);
|
||||
Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping = Map.Models.Stateless.Methods.IMapLogic.GetIdToNormalizedRectangleToFace(distinctFilteredMappingCollection);
|
||||
if (Directory.Exists(fPhotoPrismContentDirectory))
|
||||
F_PhotoPrism.WriteMatches(fPhotoPrismContentDirectory, _Configuration.PersonBirthdayFormat, ticks, distinctFilteredFaces, mapLogic);
|
||||
if (_Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
|
||||
{
|
||||
List<Item> filteredItems = GetItems(argZero, containers);
|
||||
mapLogic.SaveShortcutsForOutputResolutionsDuringMapLogic(personKeyToIds, dFacesContentDirectory, filteredItems, mappingCollection);
|
||||
}
|
||||
mapLogic.SaveShortcutsForOutputResolutionsDuringMapLogic(containers, personKeyToIds, dFacesContentDirectory, distinctFilteredMappingCollection);
|
||||
if (!string.IsNullOrEmpty(_Configuration.PersonCharacters))
|
||||
{
|
||||
if (_Configuration.PersonCharactersCopyCount > 0)
|
||||
mapLogic.CopyAtLeastOneMappedFiles(_Configuration.PersonCharactersCopyCount, dFacesContentDirectory, a2PeopleSingletonDirectory, mappingCollection);
|
||||
mapLogic.SavePersonKeyToCount(dFacesContentDirectory, a2PeopleSingletonDirectory, mappingCollection);
|
||||
mapLogic.CopyAtLeastOneMappedFiles(_Configuration.PersonCharactersCopyCount, dFacesContentDirectory, a2PeopleSingletonDirectory, distinctFilteredMappingCollection);
|
||||
mapLogic.SavePersonKeyToCount(dFacesContentDirectory, a2PeopleSingletonDirectory, distinctFilteredMappingCollection);
|
||||
}
|
||||
mapLogic.CopyManualFiles(dFacesContentDirectory, idToNormalizedRectangleToMapping);
|
||||
if (_Configuration.SaveMappedForOutputResolutions.Contains(outputResolution))
|
||||
mapLogic.SaveMapped(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, personKeyToIds, mappingCollection, idToNormalizedRectangleToMapping, totalNotMapped);
|
||||
mapLogic.SaveMapped(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, personKeyToIds, distinctFilteredMappingCollection, idToNormalizedRectangleToMapping, totalNotMapped);
|
||||
if (_Configuration.SaveFaceDistancesForOutputResolutions.Contains(outputResolution))
|
||||
SaveFaceDistances(ticks, mapLogic, distinctFilteredFaces, mappingCollection, dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, dFacesCollectionDirectory, idToNormalizedRectangleToMapping);
|
||||
SaveFaceDistances(ticks, mapLogic, distinctFilteredFaces, distinctFilteredMappingCollection, dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, dFacesCollectionDirectory, idToNormalizedRectangleToMapping);
|
||||
}
|
||||
|
||||
private string SaveUrlAndGetNewRootDirectory(Container container)
|
||||
@ -860,24 +837,6 @@ public partial class DlibDotNet
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void LookForAbandoned(ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, List<int> distinctFilteredIds)
|
||||
{
|
||||
List<string> renameCollection = new();
|
||||
foreach (KeyValuePair<int, List<LocationContainer<MetadataExtractor.Directory>>> idToCollection in idToLocationContainers)
|
||||
{
|
||||
if (distinctFilteredIds.Contains(idToCollection.Key))
|
||||
continue;
|
||||
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in idToCollection.Value)
|
||||
{
|
||||
if (locationContainer.File.Contains('!'))
|
||||
continue;
|
||||
renameCollection.Add(locationContainer.File);
|
||||
}
|
||||
}
|
||||
if (renameCollection.Any())
|
||||
Shared.Models.Stateless.Methods.IDirectory.MoveFiles(renameCollection, "()", "(abd)");
|
||||
}
|
||||
|
||||
private static void LookForAbandoned(List<int> distinctFilteredIds, string directory, string directoryName)
|
||||
{
|
||||
string fileNameWithoutExtension;
|
||||
@ -898,21 +857,52 @@ public partial class DlibDotNet
|
||||
if (directoryName.Length == 2)
|
||||
Shared.Models.Stateless.Methods.IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[0]}abd{directoryName[^1]}");
|
||||
else if (directoryName.Length == 4)
|
||||
Shared.Models.Stateless.Methods.IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[..2]}abd{directoryName[^2]}");
|
||||
Shared.Models.Stateless.Methods.IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[..2]}abd{directoryName[^2..]}");
|
||||
else
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
private void LookForAbandoned(Container[] containers, ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers)
|
||||
private static void LookForAbandoned(string bResultsFullGroupDirectory, List<int> distinctFilteredIds)
|
||||
{
|
||||
string[] directories = Directory.GetDirectories(bResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
string? directoryName = Path.GetFileName(directory);
|
||||
if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4))
|
||||
continue;
|
||||
LookForAbandoned(distinctFilteredIds, directory, directoryName);
|
||||
}
|
||||
}
|
||||
|
||||
private static void LookForAbandoned(ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, List<int> distinctFilteredIds)
|
||||
{
|
||||
List<string> renameCollection = new();
|
||||
foreach (KeyValuePair<int, List<LocationContainer<MetadataExtractor.Directory>>> idToCollection in idToLocationContainers)
|
||||
{
|
||||
if (distinctFilteredIds.Contains(idToCollection.Key))
|
||||
continue;
|
||||
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in idToCollection.Value)
|
||||
{
|
||||
if (locationContainer.File.Contains('!'))
|
||||
continue;
|
||||
renameCollection.Add(locationContainer.File);
|
||||
}
|
||||
}
|
||||
if (renameCollection.Any())
|
||||
Shared.Models.Stateless.Methods.IDirectory.MoveFiles(renameCollection, "()", "(abd)");
|
||||
}
|
||||
|
||||
private void LookForAbandoned(string bResultsFullGroupDirectory, Container[] containers, ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers)
|
||||
{
|
||||
string[] directories;
|
||||
string? directoryName;
|
||||
string cResultsFullGroupDirectory;
|
||||
string dResultsFullGroupDirectory;
|
||||
string d2ResultsFullGroupDirectory;
|
||||
List<int> distinctFilteredIds = Shared.Models.Stateless.Methods.IContainer.GetFilteredDistinct(_Configuration.PropertyConfiguration, containers);
|
||||
List<int> distinctFilteredIds = Shared.Models.Stateless.Methods.IContainer.GetFilteredDistinctIds(_Configuration.PropertyConfiguration, containers);
|
||||
LookForAbandoned(idToLocationContainers, distinctFilteredIds);
|
||||
LookForAbandoned(bResultsFullGroupDirectory, distinctFilteredIds);
|
||||
foreach (string outputResolution in _Configuration.OutputResolutions)
|
||||
{
|
||||
(cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
|
||||
@ -943,6 +933,62 @@ public partial class DlibDotNet
|
||||
}
|
||||
}
|
||||
|
||||
private Mapping[] GetMappings(Property.Models.Configuration propertyConfiguration, Container[] containers, MapLogic mapLogic, ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, bool distinctItems)
|
||||
{
|
||||
Mapping[] results;
|
||||
int count = 0;
|
||||
Mapping mapping;
|
||||
bool anyValidFaces;
|
||||
string focusRelativePath;
|
||||
bool? isFocusRelativePath;
|
||||
bool? isIgnoreRelativePath;
|
||||
List<int> distinct = new();
|
||||
DateTime[] containerDateTimes;
|
||||
IEnumerable<Item> filteredItems;
|
||||
MappingFromItem mappingFromItem;
|
||||
List<Mapping> mappingCollection = new();
|
||||
foreach (Container container in containers)
|
||||
{
|
||||
if (!container.Items.Any())
|
||||
continue;
|
||||
filteredItems = Shared.Models.Stateless.Methods.IContainer.GetFilterItems(propertyConfiguration, container);
|
||||
if (!filteredItems.Any())
|
||||
continue;
|
||||
containerDateTimes = Shared.Models.Stateless.Methods.IContainer.GetContainerDateTimes(filteredItems);
|
||||
focusRelativePath = Path.GetFullPath(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, _Configuration.FocusDirectory));
|
||||
isFocusRelativePath = string.IsNullOrEmpty(_Configuration.FocusDirectory) ? null : container.SourceDirectory.StartsWith(focusRelativePath);
|
||||
isIgnoreRelativePath = !_Configuration.IgnoreRelativePaths.Any() ? null : _Configuration.IgnoreRelativePaths.Any(l => container.SourceDirectory.Contains(l)) && Shared.Models.Stateless.Methods.IContainer.IsIgnoreRelativePath(_Configuration.PropertyConfiguration, _Configuration.IgnoreRelativePaths, container.SourceDirectory);
|
||||
foreach (Item item in filteredItems)
|
||||
{
|
||||
if (item.Property?.Id is null || item.ResizedFileHolder is null)
|
||||
continue;
|
||||
mappingFromItem = Shared.Models.Stateless.Methods.IMappingFromItem.GetMappingFromItem(containerDateTimes, item, item.ResizedFileHolder);
|
||||
if (distinctItems)
|
||||
{
|
||||
if (distinct.Contains(item.Property.Id.Value))
|
||||
continue;
|
||||
distinct.Add(item.Property.Id.Value);
|
||||
}
|
||||
count++;
|
||||
anyValidFaces = false;
|
||||
foreach (Shared.Models.Face face in item.Faces)
|
||||
{
|
||||
if (face.Mapping is null)
|
||||
continue;
|
||||
anyValidFaces = true;
|
||||
mappingCollection.Add(face.Mapping);
|
||||
}
|
||||
if (!anyValidFaces)
|
||||
{
|
||||
mapping = GetMapping(idToLocationContainers, mapLogic, item, isFocusRelativePath, isIgnoreRelativePath, mappingFromItem);
|
||||
mappingCollection.Add(mapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
results = (from l in mappingCollection orderby l.MappingFromItem.Id select l).ToArray();
|
||||
return results;
|
||||
}
|
||||
|
||||
private void Search(long ticks, string argZero, string propertyRoot)
|
||||
{
|
||||
int t;
|
||||
@ -1006,14 +1052,15 @@ public partial class DlibDotNet
|
||||
ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers = mapLogic.GetIdToLocationContainers();
|
||||
fileNameToCollection = !Directory.Exists(fPhotoPrismSingletonDirectory) ? fileNameToCollection = new() : F_PhotoPrism.GetFileNameToCollection(fPhotoPrismSingletonDirectory);
|
||||
FullDoWork(argZero, propertyRoot, ticks, aResultsFullGroupDirectory, bResultsFullGroupDirectory, t, containers, propertyLogic, metadata, eDistanceContentDirectory, fileNameToCollection, idToLocationContainers, mapLogic);
|
||||
LookForAbandoned(containers, idToLocationContainers);
|
||||
LookForAbandoned(bResultsFullGroupDirectory, containers, idToLocationContainers);
|
||||
_Distance.Clear();
|
||||
if (!personKeyToIds.Any())
|
||||
personKeyToIds = mapLogic.GetPersonKeyToIds();
|
||||
List<Shared.Models.Face> distinctFilteredFaces = GetFilteredDistinct(argZero, containers);
|
||||
Mapping[] mappingCollection = Map.Models.Stateless.Methods.IMapLogic.GetSelectedMappingCollection(distinctFilteredFaces);
|
||||
int totalNotMapped = mapLogic.UpdateMappingFromPerson(mappingCollection);
|
||||
string json = System.Text.Json.JsonSerializer.Serialize(mappingCollection);
|
||||
Mapping[] distinctFilteredMappingCollection = GetMappings(_Configuration.PropertyConfiguration, containers, mapLogic, idToLocationContainers, distinctItems: true);
|
||||
List<Item> distinctFilteredItems = Shared.Models.Stateless.Methods.IContainer.GetItems(_Configuration.PropertyConfiguration, containers, distinctItems: true, filterItems: true);
|
||||
List<Shared.Models.Face> distinctFilteredFaces = Map.Models.Stateless.Methods.IMapLogic.GetFaces(distinctFilteredItems);
|
||||
int totalNotMapped = mapLogic.UpdateMappingFromPerson(distinctFilteredMappingCollection);
|
||||
string json = System.Text.Json.JsonSerializer.Serialize(distinctFilteredMappingCollection);
|
||||
File.WriteAllText(Path.Combine(eDistanceContentDirectory, $"{ticks}.json"), json);
|
||||
for (int i = 1; i < 5; i++)
|
||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(eDistanceContentDirectory);
|
||||
@ -1022,18 +1069,18 @@ public partial class DlibDotNet
|
||||
if (_PropertyRootExistedBefore)
|
||||
break;
|
||||
if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && _Configuration.SaveShortcutsForOutputResolutions.Contains(outputResolution))
|
||||
mapLogic.SaveShortcutsForOutputResolutionsPreMapLogic(eDistanceContentDirectory, personKeyToIds, idToLocationContainers, mappingCollection);
|
||||
mapLogic.SaveShortcutsForOutputResolutionsPreMapLogic(eDistanceContentDirectory, personKeyToIds, distinctFilteredMappingCollection);
|
||||
if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && _Configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions.Contains(outputResolution))
|
||||
mapLogic.SaveFilteredOriginalImagesFromJLinks(_Configuration.JLinks, _PersonContainers, a2PeopleContentDirectory, personKeyToIds, mappingCollection, totalNotMapped);
|
||||
mapLogic.SaveFilteredOriginalImagesFromJLinks(_Configuration.JLinks, _PersonContainers, a2PeopleContentDirectory, personKeyToIds, distinctFilteredMappingCollection, totalNotMapped);
|
||||
(cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
|
||||
if (_ArgZeroIsConfigurationRootDirectory
|
||||
&& _Configuration.SaveResizedSubfiles
|
||||
&& outputResolution == _Configuration.OutputResolutions[0]
|
||||
&& _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)
|
||||
&& _Exceptions.Count == 0)
|
||||
MapLogic(argZero, ticks, containers, a2PeopleSingletonDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, fPhotoPrismContentDirectory, mapLogic, outputResolution, personKeyToIds, distinctFilteredFaces, mappingCollection, totalNotMapped);
|
||||
if (_Configuration.SaveRandomForOutputResolutions.Contains(outputResolution) && personKeyToIds.Any() && mappingCollection.Any())
|
||||
_Random.Random(_Configuration.PropertyConfiguration, outputResolution, personKeyToIds, mappingCollection);
|
||||
MapLogic(ticks, containers, a2PeopleSingletonDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, fPhotoPrismContentDirectory, mapLogic, outputResolution, personKeyToIds, distinctFilteredFaces, distinctFilteredMappingCollection, totalNotMapped);
|
||||
if (_Configuration.SaveRandomForOutputResolutions.Contains(outputResolution) && personKeyToIds.Any() && distinctFilteredMappingCollection.Any())
|
||||
_Random.Random(_Configuration.PropertyConfiguration, outputResolution, personKeyToIds, distinctFilteredMappingCollection);
|
||||
if (_IsEnvironment.Development)
|
||||
continue;
|
||||
if (!_IsEnvironment.Development)
|
||||
|
@ -1,6 +1,7 @@
|
||||
using Humanizer;
|
||||
using ShellProgressBar;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using View_by_Distance.Shared.Models;
|
||||
@ -1122,35 +1123,43 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
SaveContainers(saveIndividually, totalNotMapped, null, saveContainers);
|
||||
}
|
||||
|
||||
private List<SaveShortcutsForOutputResolutions> GetCollectionForSaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, Dictionary<long, List<int>> personKeyToIds, ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, Mapping[] mappingCollection)
|
||||
private List<SaveShortcutsForOutputResolutions> GetCollectionForSaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, Dictionary<long, List<int>> personKeyToIds, Mapping[] mappingCollection)
|
||||
{
|
||||
List<SaveShortcutsForOutputResolutions> results = new();
|
||||
if (_Configuration is null)
|
||||
throw new NullReferenceException(nameof(_Configuration));
|
||||
int season;
|
||||
string? model;
|
||||
long personKey;
|
||||
string fileName;
|
||||
string directory;
|
||||
int dateCount = 0;
|
||||
string weekOfYear;
|
||||
string description;
|
||||
DateTime? dateTime;
|
||||
string directoryName;
|
||||
List<long>? personKeys;
|
||||
string personKeyFormatted;
|
||||
Calendar calendar = new CultureInfo("en-US").Calendar;
|
||||
IReadOnlyList<MetadataExtractor.Directory> directories;
|
||||
List<LocationContainer<MetadataExtractor.Directory>>? locationContainers;
|
||||
Dictionary<int, List<long>> idToPersonKeys = Stateless.Methods.IMapLogic.GetIdToPersonKeys(personKeyToIds);
|
||||
foreach (Mapping mapping in mappingCollection)
|
||||
{
|
||||
if (mapping.MappingFromLocation is null || mapping.MappingFromItem.ImageFileHolder.DirectoryName is null || mapping.MappingFromPerson is null)
|
||||
continue;
|
||||
if (!idToLocationContainers.TryGetValue(mapping.MappingFromItem.Id, out locationContainers) || !locationContainers.Any())
|
||||
directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(mapping.MappingFromItem.ResizedFileHolder.FullName);
|
||||
else
|
||||
directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(mapping.MappingFromItem.ResizedFileHolder.FullName);
|
||||
dateTime = Metadata.Models.Stateless.Methods.IMetadata.GetMinimumDateTime(directories);
|
||||
description = mapping.MappingFromLocation is null ? mapping.MappingFromItem.Id.ToString() : mapping.MappingFromLocation.DeterministicHashCodeKey;
|
||||
if (dateTime is not null)
|
||||
{
|
||||
directories = locationContainers.First().Directories;
|
||||
model = Metadata.Models.Stateless.Methods.IMetadata.GetModel(directories);
|
||||
if (model is null)
|
||||
directories = MetadataExtractor.ImageMetadataReader.ReadMetadata(mapping.MappingFromItem.ResizedFileHolder.FullName);
|
||||
dateCount++;
|
||||
(season, _) = IProperty.GetSeason(dateTime.Value.DayOfYear);
|
||||
weekOfYear = calendar.GetWeekOfYear(dateTime.Value, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00");
|
||||
directory = Path.Combine($"{eDistanceContentDirectory}---", "Date Shortcuts", $"{dateTime.Value.Year}.{season}-MM{dateTime.Value.Month:00}-WW{weekOfYear}");
|
||||
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}.lnk");
|
||||
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.MinimumDateTime, fileName, description, MakeAllHidden: false));
|
||||
}
|
||||
model = Metadata.Models.Stateless.Methods.IMetadata.GetModel(directories);
|
||||
if (mapping.MappingFromItem.ImageFileHolder.DirectoryName is null)
|
||||
continue;
|
||||
directoryName = Path.GetFileName(mapping.MappingFromItem.ImageFileHolder.DirectoryName);
|
||||
if (!string.IsNullOrEmpty(model) && !string.IsNullOrEmpty(model.Trim()))
|
||||
{
|
||||
@ -1158,8 +1167,10 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
model = Regex.Replace(model.Trim(), @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]", "_");
|
||||
directory = Path.Combine($"{eDistanceContentDirectory}---", "Model Shortcuts", model, directoryName);
|
||||
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}.lnk");
|
||||
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.MinimumDateTime, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey, MakeAllHidden: false));
|
||||
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.MinimumDateTime, fileName, description, MakeAllHidden: false));
|
||||
}
|
||||
if (mapping.MappingFromPerson is null)
|
||||
continue;
|
||||
if (!idToPersonKeys.TryGetValue(mapping.MappingFromItem.Id, out personKeys))
|
||||
continue;
|
||||
personKey = mapping.MappingFromPerson.PersonBirthday.Value.Ticks;
|
||||
@ -1168,22 +1179,22 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonBirthday);
|
||||
directory = Path.Combine($"{eDistanceContentDirectory}---", "Person Key Shortcuts", personKeyFormatted, directoryName);
|
||||
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}.lnk");
|
||||
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.MinimumDateTime, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey, MakeAllHidden: false));
|
||||
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.MinimumDateTime, fileName, description, MakeAllHidden: false));
|
||||
if (IPerson.IsDefaultName(_Configuration.MappingDefaultName, mapping.MappingFromPerson.DisplayDirectoryName))
|
||||
continue;
|
||||
directory = Path.Combine($"{eDistanceContentDirectory}---", "Name Shortcuts", mapping.MappingFromPerson.DisplayDirectoryName, directoryName);
|
||||
fileName = Path.Combine(directory, $"{mapping.MappingFromItem.ImageFileHolder.Name}.lnk");
|
||||
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.MinimumDateTime, fileName, mapping.MappingFromLocation.DeterministicHashCodeKey, MakeAllHidden: false));
|
||||
results.Add(new(mapping.MappingFromItem.ImageFileHolder.FullName, directory, mapping.MappingFromItem.MinimumDateTime, fileName, description, MakeAllHidden: false));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public void SaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, Dictionary<long, List<int>> personKeyToIds, ReadOnlyDictionary<int, List<LocationContainer<MetadataExtractor.Directory>>> idToLocationContainers, Mapping[] mappingCollection)
|
||||
public void SaveShortcutsForOutputResolutionsPreMapLogic(string eDistanceContentDirectory, Dictionary<long, List<int>> personKeyToIds, Mapping[] mappingCollection)
|
||||
{
|
||||
string hiddenFile;
|
||||
WindowsShortcut windowsShortcut;
|
||||
List<SaveShortcutsForOutputResolutions> collection = new();
|
||||
collection = GetCollectionForSaveShortcutsForOutputResolutionsPreMapLogic(eDistanceContentDirectory, personKeyToIds, idToLocationContainers, mappingCollection);
|
||||
collection = GetCollectionForSaveShortcutsForOutputResolutionsPreMapLogic(eDistanceContentDirectory, personKeyToIds, mappingCollection);
|
||||
string[] distinctDirectories = (from l in collection select l.Directory).Distinct().ToArray();
|
||||
foreach (string directory in distinctDirectories)
|
||||
{
|
||||
@ -1308,13 +1319,14 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
|
||||
return new(directoriesAndDateTimes, collection);
|
||||
}
|
||||
|
||||
public void SaveShortcutsForOutputResolutionsDuringMapLogic(Dictionary<long, List<int>> personKeyToIds, string dFacesContentDirectory, List<Item> filteredItems, Mapping[] mappingCollection)
|
||||
public void SaveShortcutsForOutputResolutionsDuringMapLogic(Container[] containers, Dictionary<long, List<int>> personKeyToIds, string dFacesContentDirectory, Mapping[] mappingCollection)
|
||||
{
|
||||
if (_Configuration is null)
|
||||
throw new NullReferenceException(nameof(_Configuration));
|
||||
WindowsShortcut windowsShortcut;
|
||||
List<(string, DateTime[])> directoriesAndDateTimes;
|
||||
List<SaveShortcutsForOutputResolutions> collection;
|
||||
List<Item> filteredItems = IContainer.GetItems(_PropertyConfiguration, containers, distinctItems: true, filterItems: true);
|
||||
(directoriesAndDateTimes, collection) = GetCollectionForSaveShortcutsForOutputResolutionsDuringMapLogic(personKeyToIds, dFacesContentDirectory, filteredItems, mappingCollection);
|
||||
string[] directories = (from l in collection select l.Directory).Distinct().ToArray();
|
||||
foreach (string directory in directories)
|
||||
|
@ -993,14 +993,39 @@ internal abstract class MapLogic
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static Mapping[] GetSelectedMappingCollection(List<Face> distinctFilteredFaces)
|
||||
internal static Mapping[] GetSelectedMappingCollection(List<Face> faces)
|
||||
{
|
||||
Mapping[] results;
|
||||
IEnumerable<Mapping> collection = from l in distinctFilteredFaces orderby l.Mapping?.MappingFromItem.Id select l.Mapping;
|
||||
IEnumerable<Mapping> collection = from l in faces orderby l.Mapping?.MappingFromItem.Id select l.Mapping;
|
||||
results = (from l in collection where l is not null select l).ToArray();
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static List<Face> GetFaces(List<Item> items)
|
||||
{
|
||||
List<Face> results = new();
|
||||
foreach (Item item in items)
|
||||
{
|
||||
if (item.Property?.Id is null || item.ResizedFileHolder is null)
|
||||
continue;
|
||||
foreach (Face face in item.Faces)
|
||||
{
|
||||
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null)
|
||||
continue;
|
||||
results.Add(face);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static Mapping[] GetSelectedMappingCollection(List<Item> items)
|
||||
{
|
||||
Mapping[] results;
|
||||
List<Face> faces = GetFaces(items);
|
||||
results = GetSelectedMappingCollection(faces);
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static Dictionary<int, Dictionary<int, Mapping>> GetIdToNormalizedRectangleToFace(Mapping[] mappingCollection)
|
||||
{
|
||||
Dictionary<int, Dictionary<int, Mapping>> results = new();
|
||||
|
@ -8,10 +8,20 @@ public interface IMapLogic
|
||||
static Dictionary<int, List<long>> GetIdToPersonKeys(Dictionary<long, List<int>> personKeyToIds) =>
|
||||
MapLogic.GetIdToPersonKeys(personKeyToIds);
|
||||
|
||||
Shared.Models.Mapping[] TestStatic_GetSelectedMappingCollection(List<Shared.Models.Face> distinctFilteredFaces) =>
|
||||
GetSelectedMappingCollection(distinctFilteredFaces);
|
||||
static Shared.Models.Mapping[] GetSelectedMappingCollection(List<Shared.Models.Face> distinctFilteredFaces) =>
|
||||
MapLogic.GetSelectedMappingCollection(distinctFilteredFaces);
|
||||
List<Shared.Models.Face> TestStatic_GetFaces(List<Shared.Models.Item> items) =>
|
||||
GetFaces(items);
|
||||
static List<Shared.Models.Face> GetFaces(List<Shared.Models.Item> items) =>
|
||||
MapLogic.GetFaces(items);
|
||||
|
||||
Shared.Models.Mapping[] TestStatic_GetSelectedMappingCollection(List<Shared.Models.Item> items) =>
|
||||
GetSelectedMappingCollection(items);
|
||||
static Shared.Models.Mapping[] GetSelectedMappingCollection(List<Shared.Models.Item> items) =>
|
||||
MapLogic.GetSelectedMappingCollection(items);
|
||||
|
||||
Shared.Models.Mapping[] TestStatic_GetSelectedMappingCollection(List<Shared.Models.Face> faces) =>
|
||||
GetSelectedMappingCollection(faces);
|
||||
static Shared.Models.Mapping[] GetSelectedMappingCollection(List<Shared.Models.Face> faces) =>
|
||||
MapLogic.GetSelectedMappingCollection(faces);
|
||||
|
||||
Dictionary<int, Dictionary<int, Shared.Models.Mapping>> TestStatic_GetIdToNormalizedRectangleToFace(Shared.Models.Mapping[] mappingCollection) =>
|
||||
GetIdToNormalizedRectangleToFace(mappingCollection);
|
||||
|
@ -3,10 +3,15 @@ namespace View_by_Distance.Metadata.Models.Stateless.Methods;
|
||||
public interface IMetadata
|
||||
{
|
||||
|
||||
DateTime TestStatic_GetMinimumDateTime(DateTime?[] dateTimes, int year, IReadOnlyList<MetadataExtractor.Directory> directories) =>
|
||||
DateTime? TestStatic_GetMinimumDateTime(DateTime?[] dateTimes, int year, IReadOnlyList<MetadataExtractor.Directory> directories) =>
|
||||
GetMinimumDateTime(dateTimes, year, directories);
|
||||
static DateTime GetMinimumDateTime(DateTime?[] dateTimes, int year, IReadOnlyList<MetadataExtractor.Directory> directories) =>
|
||||
Metadata.GetMinimumDateTime(dateTimes, year, directories);
|
||||
static DateTime? GetMinimumDateTime(DateTime?[] dateTimes, int year, IReadOnlyList<MetadataExtractor.Directory> directories) =>
|
||||
Metadata.GetMinimumDateTime(directories, dateTimes, year);
|
||||
|
||||
DateTime? TestStatic_GetMinimumDateTime(IReadOnlyList<MetadataExtractor.Directory> directories) =>
|
||||
GetMinimumDateTime(directories);
|
||||
static DateTime? GetMinimumDateTime(IReadOnlyList<MetadataExtractor.Directory> directories) =>
|
||||
Metadata.GetMinimumDateTime(directories, dateTimes: null, year: null);
|
||||
|
||||
string? TestStatic_GetModel(IReadOnlyList<MetadataExtractor.Directory> directories) =>
|
||||
GetModel(directories);
|
||||
|
@ -53,11 +53,11 @@ internal class Metadata
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static DateTime GetMinimumDateTime(DateTime?[] dateTimes, int year, IReadOnlyList<MetadataExtractor.Directory> directories)
|
||||
internal static DateTime? GetMinimumDateTime(IReadOnlyList<MetadataExtractor.Directory> directories, DateTime?[]? dateTimes, int? year)
|
||||
{
|
||||
DateTime result;
|
||||
DateTime? result;
|
||||
DateTime dateTime;
|
||||
List<DateTime> results = (from l in dateTimes where l is not null select l.Value).ToList();
|
||||
List<DateTime> results = dateTimes is null ? new() : (from l in dateTimes where l is not null select l.Value).ToList();
|
||||
ExifDirectoryBase? exifDirectoryBase = directories.OfType<ExifDirectoryBase>().FirstOrDefault();
|
||||
if (exifDirectoryBase is not null)
|
||||
{
|
||||
@ -86,11 +86,13 @@ internal class Metadata
|
||||
if (quickTimeTrackHeaderDirectory.TryGetDateTime(QuickTimeTrackHeaderDirectory.TagCreated, out dateTime))
|
||||
results.Add(dateTime);
|
||||
}
|
||||
DateTime[] filtered = (from l in results where l.Year >= year select l).ToArray();
|
||||
if (!filtered.Any())
|
||||
DateTime[] filtered = year is null ? results.ToArray() : (from l in results where l.Year >= year select l).ToArray();
|
||||
if (filtered.Any())
|
||||
result = filtered.Min();
|
||||
else if (results.Any())
|
||||
result = results.Min();
|
||||
else
|
||||
result = filtered.Min();
|
||||
result = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -7,16 +7,16 @@ internal abstract class Container
|
||||
|
||||
private record FilePair(string Path, string? Directory, bool IsUnique, List<string> Collection, Models.Item Item) { }
|
||||
|
||||
internal static DateTime[] GetContainerDateTimes(Models.Item[] filteredItems)
|
||||
internal static DateTime[] GetContainerDateTimes(IEnumerable<Models.Item> items)
|
||||
{
|
||||
DateTime[] results;
|
||||
DateTime? containerMinimumDateTime;
|
||||
DateTime? containerMaximumDateTime;
|
||||
containerMinimumDateTime = (from l in filteredItems select l.ImageFileHolder.LastWriteTime).Min();
|
||||
containerMinimumDateTime = (from l in items select l.ImageFileHolder.LastWriteTime).Min();
|
||||
if (containerMinimumDateTime is null)
|
||||
containerMaximumDateTime = null;
|
||||
else
|
||||
containerMaximumDateTime = (from l in filteredItems select l.ImageFileHolder.LastWriteTime).Max();
|
||||
containerMaximumDateTime = (from l in items select l.ImageFileHolder.LastWriteTime).Max();
|
||||
if (containerMinimumDateTime is null || containerMaximumDateTime is null)
|
||||
results = Array.Empty<DateTime>();
|
||||
else
|
||||
@ -94,10 +94,7 @@ internal abstract class Container
|
||||
filePairs = IDirectory.GetFiles(filesCollection, fileNamesToFiles, extension, compareFileNamesToFiles);
|
||||
renamed += IDirectory.MaybeMove(propertyConfiguration.RootDirectory, propertyConfiguration.ResultAllInOne, filePairs, aPropertySingletonDirectory, extension);
|
||||
if (renamed == 0)
|
||||
{
|
||||
_ = IPath.DeleteEmptyDirectories(aPropertySingletonDirectory);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (filePairs is null || jsonFilesCollection is null || compareFileNamesToFiles is null)
|
||||
throw new NullReferenceException(nameof(filePairs));
|
||||
@ -228,7 +225,7 @@ internal abstract class Container
|
||||
return (collection.Count, results.ToArray());
|
||||
}
|
||||
|
||||
internal static List<int> GetFilteredDistinct(Properties.IPropertyConfiguration propertyConfiguration, Models.Container[] containers)
|
||||
internal static List<int> GetFilteredDistinctIds(Properties.IPropertyConfiguration propertyConfiguration, Models.Container[] containers)
|
||||
{
|
||||
List<int> results = new();
|
||||
Models.Item[] filteredItems;
|
||||
@ -251,4 +248,37 @@ internal abstract class Container
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static List<Models.Item> GetItems(Properties.IPropertyConfiguration propertyConfiguration, Models.Container[] containers, bool distinctItems, bool filterItems)
|
||||
{
|
||||
List<Models.Item> results = new();
|
||||
List<int> distinct = new();
|
||||
IEnumerable<Models.Item> filteredItems;
|
||||
foreach (Models.Container container in containers)
|
||||
{
|
||||
if (!container.Items.Any())
|
||||
continue;
|
||||
if (!filterItems)
|
||||
filteredItems = container.Items;
|
||||
else
|
||||
{
|
||||
filteredItems = GetFilterItems(propertyConfiguration, container);
|
||||
if (!filteredItems.Any())
|
||||
continue;
|
||||
}
|
||||
foreach (Models.Item item in filteredItems)
|
||||
{
|
||||
if (item.Property?.Id is null || item.ResizedFileHolder is null)
|
||||
continue;
|
||||
if (distinctItems)
|
||||
{
|
||||
if (distinct.Contains(item.Property.Id.Value))
|
||||
continue;
|
||||
distinct.Add(item.Property.Id.Value);
|
||||
}
|
||||
results.Add(item);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
@ -3,10 +3,10 @@ namespace View_by_Distance.Shared.Models.Stateless.Methods;
|
||||
public interface IContainer
|
||||
{
|
||||
|
||||
DateTime[] TestStatic_GetContainerDateTimes(Models.Item[] filteredItems) =>
|
||||
GetContainerDateTimes(filteredItems);
|
||||
static DateTime[] GetContainerDateTimes(Models.Item[] filteredItems) =>
|
||||
Container.GetContainerDateTimes(filteredItems);
|
||||
DateTime[] TestStatic_GetContainerDateTimes(IEnumerable<Models.Item> items) =>
|
||||
GetContainerDateTimes(items);
|
||||
static DateTime[] GetContainerDateTimes(IEnumerable<Models.Item> items) =>
|
||||
Container.GetContainerDateTimes(items);
|
||||
|
||||
Models.Item[] TestStatic_GetFilterItems(Properties.IPropertyConfiguration propertyConfiguration, Models.Container container) =>
|
||||
GetFilterItems(propertyConfiguration, container);
|
||||
@ -33,9 +33,14 @@ public interface IContainer
|
||||
static (int, Models.Container[]) GetContainers(Properties.IPropertyConfiguration propertyConfiguration, string aPropertySingletonDirectory) =>
|
||||
Container.GetContainers(propertyConfiguration, aPropertySingletonDirectory);
|
||||
|
||||
List<int> TestStatic_GetFilteredDistinct(Properties.IPropertyConfiguration propertyConfiguration, Models.Container[] containers) =>
|
||||
GetFilteredDistinct(propertyConfiguration, containers);
|
||||
static List<int> GetFilteredDistinct(Properties.IPropertyConfiguration propertyConfiguration, Models.Container[] containers) =>
|
||||
Container.GetFilteredDistinct(propertyConfiguration, containers);
|
||||
List<int> TestStatic_GetFilteredDistinctIds(Properties.IPropertyConfiguration propertyConfiguration, Models.Container[] containers) =>
|
||||
GetFilteredDistinctIds(propertyConfiguration, containers);
|
||||
static List<int> GetFilteredDistinctIds(Properties.IPropertyConfiguration propertyConfiguration, Models.Container[] containers) =>
|
||||
Container.GetFilteredDistinctIds(propertyConfiguration, containers);
|
||||
|
||||
List<Models.Item> TestStatic_GetItems(Properties.IPropertyConfiguration propertyConfiguration, Models.Container[] containers, bool distinctItems, bool filterItems) =>
|
||||
GetItems(propertyConfiguration, containers, distinctItems, filterItems);
|
||||
static List<Models.Item> GetItems(Properties.IPropertyConfiguration propertyConfiguration, Models.Container[] containers, bool distinctItems, bool filterItems) =>
|
||||
Container.GetItems(propertyConfiguration, containers, distinctItems, filterItems);
|
||||
|
||||
}
|
@ -95,6 +95,11 @@ public interface ILocation
|
||||
static int GetNormalizedRectangle(Models.Location location, int locationDigits, Models.OutputResolution outputResolution) =>
|
||||
Location.GetNormalizedRectangle(location.Bottom, OutputResolution.Get(outputResolution).Height, location.Left, locationDigits, location.Right, location.Top, OutputResolution.Get(outputResolution).Width, zCount: 1);
|
||||
|
||||
int TestStatic_GetNormalizedRectangle(int locationDigits) =>
|
||||
GetNormalizedRectangle(locationDigits);
|
||||
static int GetNormalizedRectangle(int locationDigits) =>
|
||||
Location.GetNormalizedRectangle(1, 1, 0, locationDigits, 1, 0, 1, zCount: 1);
|
||||
|
||||
int TestStatic_GetNormalizedRectangle(int bottom, int height, int left, int locationDigits, int right, int top, int width) =>
|
||||
GetNormalizedRectangle(bottom, height, left, locationDigits, right, top, width);
|
||||
static int GetNormalizedRectangle(int bottom, int height, int left, int locationDigits, int right, int top, int width) =>
|
||||
|
@ -28,6 +28,11 @@ public interface IMapping
|
||||
static string GetDeterministicHashCodeKey(int id, Models.Location location, int locationDigits, Models.OutputResolution outputResolution)
|
||||
=> $"{id}.{ILocation.GetLeftPadded(locationDigits, ILocation.GetNormalizedRectangle(location, locationDigits, outputResolution))}";
|
||||
|
||||
string TestStatic_GetDeterministicHashCodeKey(int id, int locationDigits)
|
||||
=> GetDeterministicHashCodeKey(id, locationDigits);
|
||||
static string GetDeterministicHashCodeKey(int id, int locationDigits)
|
||||
=> $"{id}.{ILocation.GetLeftPadded(locationDigits, ILocation.GetNormalizedRectangle(locationDigits))}";
|
||||
|
||||
(int?, int?) TestStatic_GetConverted(string facesFileNameExtension, string file) =>
|
||||
GetConverted(facesFileNameExtension, file);
|
||||
static (int?, int?) GetConverted(string facesFileNameExtension, string file) =>
|
||||
|
@ -34,6 +34,11 @@ public interface IPath
|
||||
static string[] GetDirectoryNames(string directory) =>
|
||||
XPath.GetDirectoryNames(directory).ToArray();
|
||||
|
||||
string[] TestStatic_GetDirectories(string directory) =>
|
||||
GetDirectories(directory);
|
||||
static string[] GetDirectories(string directory) =>
|
||||
XPath.GetDirectories(directory).ToArray();
|
||||
|
||||
string TestStatic_GetRelativePath(string path, int length, bool forceExtensionToLower) =>
|
||||
GetRelativePath(path, length, forceExtensionToLower);
|
||||
static string GetRelativePath(string path, int length, bool forceExtensionToLower) =>
|
||||
|
@ -138,6 +138,27 @@ internal abstract class XPath
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static List<string> GetDirectories(string directory)
|
||||
{
|
||||
List<string> results = new();
|
||||
string? checkDirectory = directory;
|
||||
string? pathRoot = Path.GetPathRoot(directory);
|
||||
if (string.IsNullOrEmpty(pathRoot))
|
||||
throw new NullReferenceException(nameof(pathRoot));
|
||||
if (Directory.Exists(directory))
|
||||
results.Add(directory);
|
||||
for (int i = 0; i < int.MaxValue; i++)
|
||||
{
|
||||
checkDirectory = Path.GetDirectoryName(checkDirectory);
|
||||
if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == pathRoot)
|
||||
break;
|
||||
results.Add(checkDirectory);
|
||||
}
|
||||
results.Add(pathRoot);
|
||||
results.Reverse();
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static (int level, List<string> directories) Get(string rootDirectory, string sourceDirectory)
|
||||
{
|
||||
int result = 0;
|
||||
|
@ -51,6 +51,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Move-By-Id", "Move-By-Id\Mo
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Person", "Person\Person.csproj", "{C5003A39-334B-444B-9873-39B26E58D667}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Drag-Drop-Move", "Drag-Drop-Move\Drag-Drop-Move.csproj", "{CF05EFAC-C212-4EE0-A644-3F728991AA54}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -160,5 +162,9 @@ Global
|
||||
{C5003A39-334B-444B-9873-39B26E58D667}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C5003A39-334B-444B-9873-39B26E58D667}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C5003A39-334B-444B-9873-39B26E58D667}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CF05EFAC-C212-4EE0-A644-3F728991AA54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CF05EFAC-C212-4EE0-A644-3F728991AA54}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CF05EFAC-C212-4EE0-A644-3F728991AA54}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CF05EFAC-C212-4EE0-A644-3F728991AA54}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
Loading…
x
Reference in New Issue
Block a user