Init
This commit is contained in:
35
Instance/Models/AppSettings.cs
Normal file
35
Instance/Models/AppSettings.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Instance.Models;
|
||||
|
||||
public class AppSettings
|
||||
{
|
||||
|
||||
protected string _Company;
|
||||
protected string _WorkingDirectoryName;
|
||||
protected int? _MaxDegreeOfParallelism;
|
||||
public string Company => _Company;
|
||||
public string WorkingDirectoryName => _WorkingDirectoryName;
|
||||
public int? MaxDegreeOfParallelism => _MaxDegreeOfParallelism;
|
||||
|
||||
// public AppSettings()
|
||||
// {
|
||||
|
||||
// }
|
||||
|
||||
[JsonConstructor]
|
||||
public AppSettings(string company, string workingDirectoryName, int? maxDegreeOfParallelism)
|
||||
{
|
||||
_Company = company;
|
||||
_WorkingDirectoryName = workingDirectoryName;
|
||||
_MaxDegreeOfParallelism = maxDegreeOfParallelism;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
26
Instance/Models/Binder/AppSettings.cs
Normal file
26
Instance/Models/Binder/AppSettings.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace View_by_Distance.Instance.Models.Binder;
|
||||
|
||||
public class AppSettings
|
||||
{
|
||||
|
||||
[Display(Name = "Company"), Required] public string Company { get; set; }
|
||||
[Display(Name = "Working Directory Name"), Required] public string WorkingDirectoryName { get; set; }
|
||||
[Display(Name = "Max Degree Of Parallelism"), Required] public int? MaxDegreeOfParallelism { get; set; }
|
||||
|
||||
public AppSettings()
|
||||
{
|
||||
Company = string.Empty;
|
||||
WorkingDirectoryName = string.Empty;
|
||||
MaxDegreeOfParallelism = -1;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
99
Instance/Models/Binder/Configuration.cs
Normal file
99
Instance/Models/Binder/Configuration.cs
Normal file
@ -0,0 +1,99 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace View_by_Distance.Instance.Models.Binder;
|
||||
|
||||
public class Configuration
|
||||
{
|
||||
|
||||
[Display(Name = "Check Json For Distance Results"), Required] public bool? CheckJsonForDistanceResults { get; set; }
|
||||
[Display(Name = "CrossDirectory Max Items In Distance Collection"), Required] public int? CrossDirectoryMaxItemsInDistanceCollection { get; set; }
|
||||
[Display(Name = "Distance Factor"), Required] public int? DistanceFactor { get; set; }
|
||||
[Display(Name = "Force Metadata Last Write Time to Creation Time"), Required] public bool? ForceMetadataLastWriteTimeToCreationTime { get; set; }
|
||||
[Display(Name = "Force Resize Last Write Time to Creation Time"), Required] public bool? ForceResizeLastWriteTimeToCreationTime { get; set; }
|
||||
[Display(Name = "Ignore Extensions"), Required] public string[] IgnoreExtensions { get; set; }
|
||||
[Display(Name = "Ignore Relative Paths"), Required] public string[] IgnoreRelativePaths { get; set; }
|
||||
[Display(Name = "Load Or Create Then Save Directroy Distance Results"), Required] public bool? LoadOrCreateThenSaveDirectoryDistanceResults { get; set; }
|
||||
[Display(Name = "Load Or Create Then Save Distance Results"), Required] public bool? LoadOrCreateThenSaveDistanceResults { get; set; }
|
||||
[Display(Name = "Load Or Create Then Save Image Faces Results"), Required] public bool? LoadOrCreateThenSaveImageFacesResults { get; set; }
|
||||
[Display(Name = "Load Or Create Then Save Index"), Required] public bool? LoadOrCreateThenSaveIndex { get; set; }
|
||||
[Display(Name = "Location Confidence Factor"), Required] public int? LocationConfidenceFactor { get; set; }
|
||||
[Display(Name = "Mapped Max Index"), Required] public int? MappedMaxIndex { get; set; }
|
||||
[Display(Name = "Max Items In Distance Collection"), Required] public int? MaxItemsInDistanceCollection { get; set; }
|
||||
[Display(Name = "Mixed Year Relative Paths"), Required] public string[] MixedYearRelativePaths { get; set; }
|
||||
[Display(Name = "Model Directory"), Required] public string ModelDirectory { get; set; }
|
||||
[Display(Name = "Model Name"), Required] public string ModelName { get; set; }
|
||||
[Display(Name = "Num Jitters"), Required] public int? NumJitters { get; set; }
|
||||
[Display(Name = "Output Extension"), Required] public string OutputExtension { get; set; }
|
||||
[Display(Name = "Output Quality"), Required] public int? OutputQuality { get; set; }
|
||||
[Display(Name = "Output Resolutions"), Required] public string[] OutputResolutions { get; set; }
|
||||
[Display(Name = "Override For Face Images"), Required] public bool? OverrideForFaceImages { get; set; }
|
||||
[Display(Name = "Override For Face Landmark Images"), Required] public bool? OverrideForFaceLandmarkImages { get; set; }
|
||||
[Display(Name = "Override For Resize Images"), Required] public bool? OverrideForResizeImages { get; set; }
|
||||
[Display(Name = "Padding Loops"), Required] public int? PaddingLoops { get; set; }
|
||||
[Display(Name = "Predictor Model Name"), Required] public string PredictorModelName { get; set; }
|
||||
[Display(Name = "Properties Changed For Distance"), Required] public bool? PropertiesChangedForDistance { get; set; }
|
||||
[Display(Name = "Properties Changed For Faces"), Required] public bool? PropertiesChangedForFaces { get; set; }
|
||||
[Display(Name = "Properties Changed For Index"), Required] public bool? PropertiesChangedForIndex { get; set; }
|
||||
[Display(Name = "Properties Changed For Metadata"), Required] public bool? PropertiesChangedForMetadata { get; set; }
|
||||
[Display(Name = "Properties Changed For Resize"), Required] public bool? PropertiesChangedForResize { get; set; }
|
||||
[Display(Name = "Property Configuration"), Required] public Property.Models.Configuration? PropertyConfiguration { get; set; }
|
||||
[Display(Name = "Reverse"), Required] public bool? Reverse { get; set; }
|
||||
[Display(Name = "Save Face Landmark For Output Resolutions"), Required] public string[] SaveFaceLandmarkForOutputResolutions { get; set; }
|
||||
[Display(Name = "Save Full Year Of Random Files"), Required] public bool? SaveFullYearOfRandomFiles { get; set; }
|
||||
[Display(Name = "Save Resized Subfiles"), Required] public bool? SaveResizedSubfiles { get; set; }
|
||||
[Display(Name = "Search for Abandoned Files"), Required] public bool? SearchForAbandonedFilesFull { get; set; }
|
||||
[Display(Name = "Skip Search"), Required] public bool? SkipSearch { get; set; }
|
||||
[Display(Name = "Test Distance Results"), Required] public bool? TestDistanceResults { get; set; }
|
||||
[Display(Name = "Valid Resolutions"), Required] public string[] ValidResolutions { get; set; }
|
||||
|
||||
public Configuration()
|
||||
{
|
||||
CheckJsonForDistanceResults = null;
|
||||
CrossDirectoryMaxItemsInDistanceCollection = null;
|
||||
DistanceFactor = null;
|
||||
ForceMetadataLastWriteTimeToCreationTime = null;
|
||||
ForceResizeLastWriteTimeToCreationTime = null;
|
||||
IgnoreExtensions = Array.Empty<string>();
|
||||
IgnoreRelativePaths = Array.Empty<string>();
|
||||
LoadOrCreateThenSaveDirectoryDistanceResults = null;
|
||||
LoadOrCreateThenSaveDistanceResults = null;
|
||||
LoadOrCreateThenSaveImageFacesResults = null;
|
||||
LoadOrCreateThenSaveIndex = null;
|
||||
LocationConfidenceFactor = null;
|
||||
MappedMaxIndex = null;
|
||||
MaxItemsInDistanceCollection = null;
|
||||
MixedYearRelativePaths = Array.Empty<string>();
|
||||
ModelDirectory = string.Empty;
|
||||
ModelName = string.Empty;
|
||||
NumJitters = null;
|
||||
OutputExtension = string.Empty;
|
||||
OutputQuality = null;
|
||||
OutputResolutions = Array.Empty<string>();
|
||||
OverrideForFaceImages = null;
|
||||
OverrideForFaceLandmarkImages = null;
|
||||
OverrideForResizeImages = null;
|
||||
PaddingLoops = null;
|
||||
PredictorModelName = string.Empty;
|
||||
PropertiesChangedForDistance = null;
|
||||
PropertiesChangedForFaces = null;
|
||||
PropertiesChangedForIndex = null;
|
||||
PropertiesChangedForMetadata = null;
|
||||
PropertiesChangedForResize = null;
|
||||
Reverse = null;
|
||||
SaveFaceLandmarkForOutputResolutions = Array.Empty<string>();
|
||||
SaveFullYearOfRandomFiles = null;
|
||||
SaveResizedSubfiles = null;
|
||||
SearchForAbandonedFilesFull = null;
|
||||
SkipSearch = null;
|
||||
TestDistanceResults = null;
|
||||
ValidResolutions = Array.Empty<string>();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
145
Instance/Models/Configuration.cs
Normal file
145
Instance/Models/Configuration.cs
Normal file
@ -0,0 +1,145 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace View_by_Distance.Instance.Models;
|
||||
|
||||
public class Configuration
|
||||
{
|
||||
|
||||
protected readonly bool? _CheckJsonForDistanceResults;
|
||||
protected readonly int? _CrossDirectoryMaxItemsInDistanceCollection;
|
||||
protected readonly int? _DistanceFactor;
|
||||
protected readonly bool? _ForceMetadataLastWriteTimeToCreationTime;
|
||||
protected readonly bool? _ForceResizeLastWriteTimeToCreationTime;
|
||||
protected readonly string[] _IgnoreExtensions;
|
||||
protected readonly string[] _IgnoreRelativePaths;
|
||||
protected readonly bool? _LoadOrCreateThenSaveDirectoryDistanceResults;
|
||||
protected readonly bool? _LoadOrCreateThenSaveDistanceResults;
|
||||
protected readonly bool? _LoadOrCreateThenSaveImageFacesResults;
|
||||
protected readonly bool? _LoadOrCreateThenSaveIndex;
|
||||
protected readonly int? _LocationConfidenceFactor;
|
||||
protected readonly int? _MappedMaxIndex;
|
||||
protected readonly int? _MaxItemsInDistanceCollection;
|
||||
protected readonly string[] _MixedYearRelativePaths;
|
||||
protected readonly string _ModelDirectory;
|
||||
protected readonly string _ModelName;
|
||||
protected readonly int? _NumJitters;
|
||||
protected readonly string _OutputExtension;
|
||||
protected readonly int? _OutputQuality;
|
||||
protected readonly string[] _OutputResolutions;
|
||||
protected readonly bool? _OverrideForFaceImages;
|
||||
protected readonly bool? _OverrideForFaceLandmarkImages;
|
||||
protected readonly bool? _OverrideForResizeImages;
|
||||
protected readonly int? _PaddingLoops;
|
||||
protected readonly string _PredictorModelName;
|
||||
protected readonly bool? _PropertiesChangedForDistance;
|
||||
protected readonly bool? _PropertiesChangedForFaces;
|
||||
protected readonly bool? _PropertiesChangedForIndex;
|
||||
protected readonly bool? _PropertiesChangedForMetadata;
|
||||
protected readonly bool? _PropertiesChangedForResize;
|
||||
protected Property.Models.Configuration? _PropertyConfiguration;
|
||||
protected readonly bool? _Reverse;
|
||||
protected readonly string[] _SaveFaceLandmarkForOutputResolutions;
|
||||
protected readonly bool? _SaveFullYearOfRandomFiles;
|
||||
protected readonly bool? _SaveResizedSubfiles;
|
||||
protected readonly bool? _SearchForAbandonedFiles;
|
||||
protected readonly bool? _SkipSearch;
|
||||
protected readonly bool? _TestDistanceResults;
|
||||
protected readonly string[] _ValidResolutions;
|
||||
public bool? CheckJsonForDistanceResults => _CheckJsonForDistanceResults;
|
||||
public int? CrossDirectoryMaxItemsInDistanceCollection => _CrossDirectoryMaxItemsInDistanceCollection;
|
||||
public int? DistanceFactor => _DistanceFactor;
|
||||
public bool? ForceMetadataLastWriteTimeToCreationTime => _ForceMetadataLastWriteTimeToCreationTime;
|
||||
public bool? ForceResizeLastWriteTimeToCreationTime => _ForceResizeLastWriteTimeToCreationTime;
|
||||
public string[] IgnoreExtensions => _IgnoreExtensions;
|
||||
public string[] IgnoreRelativePaths => _IgnoreRelativePaths;
|
||||
public bool? LoadOrCreateThenSaveDirectoryDistanceResults => _LoadOrCreateThenSaveDirectoryDistanceResults;
|
||||
public bool? LoadOrCreateThenSaveDistanceResults => _LoadOrCreateThenSaveDistanceResults;
|
||||
public bool? LoadOrCreateThenSaveImageFacesResults => _LoadOrCreateThenSaveImageFacesResults;
|
||||
public bool? LoadOrCreateThenSaveIndex => _LoadOrCreateThenSaveIndex;
|
||||
public int? LocationConfidenceFactor => _LocationConfidenceFactor;
|
||||
public int? MappedMaxIndex => _MappedMaxIndex;
|
||||
public int? MaxItemsInDistanceCollection => _MaxItemsInDistanceCollection;
|
||||
public string[] MixedYearRelativePaths => _MixedYearRelativePaths;
|
||||
public string ModelDirectory => _ModelDirectory;
|
||||
public string ModelName => _ModelName;
|
||||
public int? NumJitters => _NumJitters;
|
||||
public string OutputExtension => _OutputExtension;
|
||||
public int? OutputQuality => _OutputQuality;
|
||||
public string[] OutputResolutions => _OutputResolutions;
|
||||
public bool? OverrideForFaceImages => _OverrideForFaceImages;
|
||||
public bool? OverrideForFaceLandmarkImages => _OverrideForFaceLandmarkImages;
|
||||
public bool? OverrideForResizeImages => _OverrideForResizeImages;
|
||||
public int? PaddingLoops => _PaddingLoops;
|
||||
public string PredictorModelName => _PredictorModelName;
|
||||
public bool? PropertiesChangedForDistance => _PropertiesChangedForDistance;
|
||||
public bool? PropertiesChangedForFaces => _PropertiesChangedForFaces;
|
||||
public bool? PropertiesChangedForIndex => _PropertiesChangedForIndex;
|
||||
public bool? PropertiesChangedForMetadata => _PropertiesChangedForMetadata;
|
||||
public bool? PropertiesChangedForResize => _PropertiesChangedForResize;
|
||||
public Property.Models.Configuration? PropertyConfiguration => _PropertyConfiguration;
|
||||
public bool? Reverse => _Reverse;
|
||||
public string[] SaveFaceLandmarkForOutputResolutions => _SaveFaceLandmarkForOutputResolutions;
|
||||
public bool? SaveFullYearOfRandomFiles => _SaveFullYearOfRandomFiles;
|
||||
public bool? SaveResizedSubfiles => _SaveResizedSubfiles;
|
||||
public bool? SearchForAbandonedFilesFull => _SearchForAbandonedFiles;
|
||||
public bool? SkipSearch => _SkipSearch;
|
||||
public bool? TestDistanceResults => _TestDistanceResults;
|
||||
public string[] ValidResolutions => _ValidResolutions;
|
||||
|
||||
[JsonConstructor]
|
||||
public Configuration(bool? checkJsonForDistanceResults, int? crossDirectoryMaxItemsInDistanceCollection, int? distanceFactor, bool? forceMetadataLastWriteTimeToCreationTime, bool? forceResizeLastWriteTimeToCreationTime, string[] ignoreExtensions, string[] ignoreRelativePaths, bool? loadOrCreateThenSaveDirectoryDistanceResults, bool? loadOrCreateThenSaveDistanceResults, bool? loadOrCreateThenSaveImageFacesResults, bool? loadOrCreateThenSaveIndex, int? locationConfidenceFactor, int? mappedMaxIndex, int? maxItemsInDistanceCollection, string[] mixedYearRelativePaths, string modelDirectory, string modelName, int? numJitters, string outputExtension, int? outputQuality, string[] outputResolutions, bool? overrideForFaceImages, bool? overrideForFaceLandmarkImages, bool? overrideForResizeImages, int? paddingLoops, string predictorModelName, bool? propertiesChangedForDistance, bool? propertiesChangedForFaces, bool? propertiesChangedForIndex, bool? propertiesChangedForMetadata, bool? propertiesChangedForResize, Property.Models.Configuration? propertyConfiguration, bool? reverse, string[] saveFaceLandmarkForOutputResolutions, bool? saveFullYearOfRandomFiles, bool? saveResizedSubfiles, bool? searchForAbandonedFilesFull, bool? skipSearch, bool? testDistanceResults, string[] validResolutions)
|
||||
{
|
||||
_CheckJsonForDistanceResults = checkJsonForDistanceResults;
|
||||
_CrossDirectoryMaxItemsInDistanceCollection = crossDirectoryMaxItemsInDistanceCollection;
|
||||
_DistanceFactor = distanceFactor;
|
||||
_ForceMetadataLastWriteTimeToCreationTime = forceMetadataLastWriteTimeToCreationTime;
|
||||
_ForceResizeLastWriteTimeToCreationTime = forceResizeLastWriteTimeToCreationTime;
|
||||
_IgnoreExtensions = ignoreExtensions;
|
||||
_IgnoreRelativePaths = ignoreRelativePaths;
|
||||
_LoadOrCreateThenSaveDirectoryDistanceResults = loadOrCreateThenSaveDirectoryDistanceResults;
|
||||
_LoadOrCreateThenSaveDistanceResults = loadOrCreateThenSaveDistanceResults;
|
||||
_LoadOrCreateThenSaveImageFacesResults = loadOrCreateThenSaveImageFacesResults;
|
||||
_LoadOrCreateThenSaveIndex = loadOrCreateThenSaveIndex;
|
||||
_LocationConfidenceFactor = locationConfidenceFactor;
|
||||
_MappedMaxIndex = mappedMaxIndex;
|
||||
_MaxItemsInDistanceCollection = maxItemsInDistanceCollection;
|
||||
_MixedYearRelativePaths = mixedYearRelativePaths;
|
||||
_ModelDirectory = modelDirectory;
|
||||
_ModelName = modelName;
|
||||
_NumJitters = numJitters;
|
||||
_OutputExtension = outputExtension;
|
||||
_OutputQuality = outputQuality;
|
||||
_OutputResolutions = outputResolutions;
|
||||
_OverrideForFaceImages = overrideForFaceImages;
|
||||
_OverrideForFaceLandmarkImages = overrideForFaceLandmarkImages;
|
||||
_OverrideForResizeImages = overrideForResizeImages;
|
||||
_PaddingLoops = paddingLoops;
|
||||
_PredictorModelName = predictorModelName;
|
||||
_PropertiesChangedForDistance = propertiesChangedForDistance;
|
||||
_PropertiesChangedForFaces = propertiesChangedForFaces;
|
||||
_PropertiesChangedForIndex = propertiesChangedForIndex;
|
||||
_PropertiesChangedForMetadata = propertiesChangedForMetadata;
|
||||
_PropertiesChangedForResize = propertiesChangedForResize;
|
||||
_PropertyConfiguration = propertyConfiguration;
|
||||
_Reverse = reverse;
|
||||
_SaveFaceLandmarkForOutputResolutions = saveFaceLandmarkForOutputResolutions;
|
||||
_SaveFullYearOfRandomFiles = saveFullYearOfRandomFiles;
|
||||
_SaveResizedSubfiles = saveResizedSubfiles;
|
||||
_SearchForAbandonedFiles = searchForAbandonedFilesFull;
|
||||
_SkipSearch = skipSearch;
|
||||
_TestDistanceResults = testDistanceResults;
|
||||
_ValidResolutions = validResolutions;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
return result;
|
||||
}
|
||||
|
||||
public void Set(Property.Models.Configuration propertyConfiguration) => _PropertyConfiguration = propertyConfiguration;
|
||||
|
||||
public void Update() => _PropertyConfiguration?.Update();
|
||||
|
||||
}
|
40
Instance/Models/Stateless/AppSettings.cs
Normal file
40
Instance/Models/Stateless/AppSettings.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace View_by_Distance.Instance.Models.Stateless;
|
||||
|
||||
public abstract class AppSettings
|
||||
{
|
||||
|
||||
public static Models.AppSettings Get(IConfigurationRoot configurationRoot)
|
||||
{
|
||||
Models.AppSettings? result;
|
||||
Binder.AppSettings appSettings = configurationRoot.Get<Binder.AppSettings>();
|
||||
string json = JsonSerializer.Serialize(appSettings, new JsonSerializerOptions() { WriteIndented = true });
|
||||
result = JsonSerializer.Deserialize<Models.AppSettings>(json);
|
||||
if (result is null)
|
||||
throw new Exception(json);
|
||||
if (string.IsNullOrEmpty(result.Company))
|
||||
throw new Exception(json);
|
||||
string jsonThis = result.ToString();
|
||||
if (jsonThis != json)
|
||||
{
|
||||
int? check = null;
|
||||
int min = new int[] { json.Length, jsonThis.Length }.Min();
|
||||
for (int i = 0; i < min; i++)
|
||||
{
|
||||
if (json[i] == jsonThis[i])
|
||||
continue;
|
||||
check = i;
|
||||
break;
|
||||
}
|
||||
if (check is null)
|
||||
throw new Exception();
|
||||
string a = json[..check.Value].Split(',')[^1];
|
||||
string b = json[check.Value..].Split(',')[0];
|
||||
throw new Exception($"{a}{b}");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
44
Instance/Models/Stateless/Configuration.cs
Normal file
44
Instance/Models/Stateless/Configuration.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Phares.Shared;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace View_by_Distance.Instance.Models.Stateless;
|
||||
|
||||
public abstract class Configuration
|
||||
{
|
||||
|
||||
public static Models.Configuration Get(IsEnvironment isEnvironment, IConfigurationRoot configurationRoot, string workingDirectory, Property.Models.Configuration propertyConfiguration)
|
||||
{
|
||||
Models.Configuration? result;
|
||||
string environmentName = IsEnvironment.GetEnvironmentName(isEnvironment);
|
||||
string section = string.Concat(environmentName, ":", nameof(Binder.Configuration));
|
||||
IConfigurationSection configurationSection = configurationRoot.GetSection(section);
|
||||
Binder.Configuration configuration = configurationSection.Get<Binder.Configuration>();
|
||||
string json = JsonSerializer.Serialize(configuration, new JsonSerializerOptions() { WriteIndented = true });
|
||||
result = JsonSerializer.Deserialize<Models.Configuration>(json);
|
||||
if (result is null)
|
||||
throw new Exception(json);
|
||||
string jsonThis = result.ToString();
|
||||
result.Set(propertyConfiguration);
|
||||
result.Update();
|
||||
if (jsonThis != json)
|
||||
{
|
||||
int? check = null;
|
||||
int min = new int[] { json.Length, jsonThis.Length }.Min();
|
||||
for (int i = 0; i < min; i++)
|
||||
{
|
||||
if (json[i] == jsonThis[i])
|
||||
continue;
|
||||
check = i;
|
||||
break;
|
||||
}
|
||||
if (check is null)
|
||||
throw new Exception();
|
||||
string a = json[..check.Value].Split(',')[^1];
|
||||
string b = json[check.Value..].Split(',')[0];
|
||||
throw new Exception($"{a}{b}");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
10
Instance/Models/Stateless/SerilogExtensionMethods.cs
Normal file
10
Instance/Models/Stateless/SerilogExtensionMethods.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace View_by_Distance.Instance.Models.Stateless;
|
||||
|
||||
public static class SerilogExtensionMethods
|
||||
{
|
||||
|
||||
internal static void Warn(this Serilog.ILogger log, string messageTemplate) => log.Warning(messageTemplate);
|
||||
|
||||
internal static void Info(this Serilog.ILogger log, string messageTemplate) => log.Information(messageTemplate);
|
||||
|
||||
}
|
79
Instance/Models/_A2_People.cs
Normal file
79
Instance/Models/_A2_People.cs
Normal file
@ -0,0 +1,79 @@
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Property.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
|
||||
namespace View_by_Distance.Instance.Models;
|
||||
|
||||
/// <summary>
|
||||
// ?
|
||||
/// </summary>
|
||||
internal class A2_People
|
||||
{
|
||||
|
||||
private readonly Serilog.ILogger? _Log;
|
||||
private readonly Configuration _Configuration;
|
||||
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
|
||||
|
||||
internal A2_People(Configuration configuration)
|
||||
{
|
||||
_Configuration = configuration;
|
||||
_Log = Serilog.Log.ForContext<A2_People>();
|
||||
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void WriteAllText(Property.Models.Configuration configuration, string outputResolution, List<G2_Identify> identifiedCollection)
|
||||
{
|
||||
string key;
|
||||
string json;
|
||||
string jsonFile;
|
||||
FileInfo fileInfo;
|
||||
string[] segments;
|
||||
string directoryFullName;
|
||||
Dictionary<string, List<G2_Identify>> keyValuePairs = new();
|
||||
string hPeopleCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A2_People), "[]");
|
||||
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
|
||||
foreach (G2_Identify identified in identifiedCollection)
|
||||
{
|
||||
fileInfo = new FileInfo(string.Concat(aPropertySingletonDirectory, identified.RelativePath));
|
||||
if (fileInfo?.Directory is null || !fileInfo.Directory.Exists || fileInfo.Exists)
|
||||
continue;
|
||||
key = string.Concat(identified.ParentDirectoryName, '|', identified.Person);
|
||||
if (!keyValuePairs.ContainsKey(key))
|
||||
keyValuePairs.Add(key, new List<G2_Identify>());
|
||||
keyValuePairs[key].Add(identified);
|
||||
}
|
||||
foreach (KeyValuePair<string, List<G2_Identify>> keyValuePair in keyValuePairs)
|
||||
{
|
||||
segments = keyValuePair.Key.Split('|');
|
||||
directoryFullName = Path.Combine(hPeopleCollectionDirectory, segments[0]);
|
||||
if (!Directory.Exists(directoryFullName))
|
||||
_ = Directory.CreateDirectory(directoryFullName);
|
||||
jsonFile = Path.Combine(directoryFullName, $"{segments[1]}.json");
|
||||
json = JsonSerializer.Serialize(keyValuePair.Value, _WriteIndentedJsonSerializerOptions);
|
||||
if (!Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: true))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
internal Person[] GetPeople(Property.Models.Configuration configuration)
|
||||
{
|
||||
Person[] results;
|
||||
if (_Configuration?.PropertyConfiguration is null)
|
||||
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!");
|
||||
string rootDirectory = _Configuration.PropertyConfiguration.RootDirectory;
|
||||
string peopleRootDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A2_People));
|
||||
string? rootResultsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(peopleRootDirectory));
|
||||
if (rootResultsDirectory is null)
|
||||
throw new Exception();
|
||||
Storage storage = new(rootDirectory, rootResultsDirectory, peopleRootDirectory);
|
||||
results = Shared.Models.Stateless.Methods.IPerson.GetPeople(storage);
|
||||
return results.ToArray();
|
||||
}
|
||||
|
||||
}
|
161
Instance/Models/_D2_FaceLandmark.cs
Normal file
161
Instance/Models/_D2_FaceLandmark.cs
Normal file
@ -0,0 +1,161 @@
|
||||
using FaceRecognitionDotNet;
|
||||
using System.Drawing;
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Metadata.Models;
|
||||
using View_by_Distance.Property.Models;
|
||||
using View_by_Distance.Resize.Models;
|
||||
|
||||
namespace View_by_Distance.Instance.Models;
|
||||
|
||||
/// <summary>
|
||||
// *.png
|
||||
/// </summary>
|
||||
internal class D2_FaceLandmarks
|
||||
{
|
||||
|
||||
internal List<string> AngleBracketCollection { get; }
|
||||
|
||||
private readonly Serilog.ILogger? _Log;
|
||||
private readonly Configuration _Configuration;
|
||||
|
||||
internal D2_FaceLandmarks(Configuration configuration)
|
||||
{
|
||||
_Configuration = configuration;
|
||||
AngleBracketCollection = new List<string>();
|
||||
_Log = Serilog.Log.ForContext<D2_FaceLandmarks>();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
return result;
|
||||
}
|
||||
|
||||
#pragma warning disable CA1416
|
||||
|
||||
private static Bitmap RotateBitmap(System.Drawing.Image image, float angle)
|
||||
{
|
||||
Bitmap result;
|
||||
Bitmap bitmap = new(image);
|
||||
result = D_Face.RotateBitmap(bitmap, angle);
|
||||
if (bitmap is not null)
|
||||
bitmap.Dispose();
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void SaveFaceLandmarkImages(List<D_Face> faceCollections, List<string[]> imageFiles, int pointSize, FileInfo resizedFileInfo)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
D_Face face;
|
||||
int width;
|
||||
int height;
|
||||
string imageFileFullName;
|
||||
Bitmap rotated;
|
||||
string rotatedImageFileFullName;
|
||||
Shared.Models.FacePoint[] facePoints;
|
||||
for (int i = 0; i < faceCollections.Count; i++)
|
||||
{
|
||||
if (!faceCollections[i].Populated)
|
||||
continue;
|
||||
face = faceCollections[i];
|
||||
imageFileFullName = imageFiles[i][0];
|
||||
rotatedImageFileFullName = imageFiles[i][1];
|
||||
try
|
||||
{
|
||||
using (System.Drawing.Image image = System.Drawing.Image.FromFile(resizedFileInfo.FullName))
|
||||
{
|
||||
using Graphics graphic = Graphics.FromImage(image);
|
||||
if (face.FaceLandmarks is null || !face.FaceLandmarks.Any())
|
||||
{
|
||||
width = face.Location.Right - face.Location.Left;
|
||||
height = face.Location.Bottom - face.Location.Top;
|
||||
graphic.DrawEllipse(Pens.Red, face.Location.Left, face.Location.Top, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (KeyValuePair<string, Shared.Models.FacePoint[]> keyValuePair in face.FaceLandmarks)
|
||||
{
|
||||
facePoints = keyValuePair.Value.ToArray();
|
||||
foreach (Shared.Models.FacePoint facePoint in facePoints)
|
||||
graphic.DrawEllipse(Pens.GreenYellow, face.Location.Left + facePoint.X - pointSize, face.Location.Top + facePoint.Y - pointSize, pointSize * 2, pointSize * 2);
|
||||
if (keyValuePair.Key == FacePart.Chin.ToString())
|
||||
continue;
|
||||
if (facePoints.Length < 3)
|
||||
continue;
|
||||
x = (int)(from l in facePoints select l.X).Average();
|
||||
y = (int)(from l in facePoints select l.Y).Average();
|
||||
graphic.DrawEllipse(Pens.Purple, face.Location.Left + x - pointSize, face.Location.Top + y - pointSize, pointSize * 2, pointSize * 2);
|
||||
}
|
||||
}
|
||||
image.Save(imageFileFullName, System.Drawing.Imaging.ImageFormat.Png);
|
||||
}
|
||||
if (face.α.HasValue)
|
||||
{
|
||||
using System.Drawing.Image image = System.Drawing.Image.FromFile(resizedFileInfo.FullName);
|
||||
rotated = RotateBitmap(image, (float)face.α.Value);
|
||||
if (rotated is not null)
|
||||
{
|
||||
rotated.Save(rotatedImageFileFullName, System.Drawing.Imaging.ImageFormat.Png);
|
||||
rotated.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore CA1416
|
||||
|
||||
internal void SaveFaceLandmarkImages(List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, string relativePath, string fileNameWithoutExtension, FileInfo resizedFileInfo, List<D_Face> faceCollections)
|
||||
{
|
||||
FileInfo fileInfo;
|
||||
bool check = false;
|
||||
string parentCheck;
|
||||
const int pointSize = 2;
|
||||
FileInfo rotatedFileInfo;
|
||||
long ticks = DateTime.Now.Ticks;
|
||||
List<string[]> imageFiles = new();
|
||||
string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), fileNameWithoutExtension);
|
||||
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) };
|
||||
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||
if (!Directory.Exists(facesDirectory))
|
||||
_ = Directory.CreateDirectory(facesDirectory);
|
||||
for (int i = 0; i < faceCollections.Count; i++)
|
||||
{
|
||||
if (!faceCollections[i].Populated)
|
||||
{
|
||||
imageFiles.Add(Array.Empty<string>());
|
||||
continue;
|
||||
}
|
||||
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{i} - {fileNameWithoutExtension}.png"));
|
||||
if (!fileInfo.Exists)
|
||||
{
|
||||
if (fileInfo.Directory?.Parent is null)
|
||||
throw new Exception();
|
||||
parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
|
||||
if (File.Exists(parentCheck))
|
||||
File.Delete(parentCheck);
|
||||
}
|
||||
if (string.IsNullOrEmpty(fileInfo.DirectoryName))
|
||||
continue;
|
||||
rotatedFileInfo = new FileInfo(Path.Combine(fileInfo.DirectoryName, string.Concat(Path.GetFileNameWithoutExtension(fileInfo.FullName), " - ", i, " - R", Path.GetExtension(fileInfo.FullName))));
|
||||
imageFiles.Add(new string[] { fileInfo.FullName, rotatedFileInfo.FullName });
|
||||
if (check)
|
||||
continue;
|
||||
if (_Configuration.OverrideForFaceLandmarkImages is null)
|
||||
check = false;
|
||||
else if (_Configuration.OverrideForFaceLandmarkImages.Value)
|
||||
check = true;
|
||||
else if (!fileInfo.Exists)
|
||||
check = true;
|
||||
else if (!rotatedFileInfo.Exists)
|
||||
check = true;
|
||||
else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
||||
check = true;
|
||||
}
|
||||
if (check)
|
||||
SaveFaceLandmarkImages(faceCollections, imageFiles, pointSize, resizedFileInfo);
|
||||
}
|
||||
|
||||
}
|
498
Instance/Models/_D_Face.cs
Normal file
498
Instance/Models/_D_Face.cs
Normal file
@ -0,0 +1,498 @@
|
||||
using FaceRecognitionDotNet;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using View_by_Distance.Metadata.Models;
|
||||
using View_by_Distance.Property.Models;
|
||||
using View_by_Distance.Resize.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Methods;
|
||||
|
||||
namespace View_by_Distance.Instance.Models;
|
||||
|
||||
/// <summary>
|
||||
// List<D_Faces>
|
||||
/// </summary>
|
||||
public class D_Face : Shared.Models.Properties.IFace, IFace
|
||||
{
|
||||
|
||||
internal List<string> AngleBracketCollection { get; }
|
||||
|
||||
private readonly Model _Model;
|
||||
private readonly string _ArgZero;
|
||||
private readonly Serilog.ILogger? _Log;
|
||||
private readonly ModelParameter _ModelParameter;
|
||||
private readonly PredictorModel _PredictorModel;
|
||||
private readonly Configuration _Configuration;
|
||||
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
|
||||
|
||||
protected double? _Α;
|
||||
protected DateTime _DateTime;
|
||||
protected Shared.Models.FaceEncoding _FaceEncoding;
|
||||
protected Dictionary<string, Shared.Models.FacePoint[]> _FaceLandmarks;
|
||||
protected Shared.Models.Location _Location;
|
||||
protected int? _LocationIndex;
|
||||
protected OutputResolution _OutputResolution;
|
||||
protected bool _Populated;
|
||||
protected string _RelativePath;
|
||||
public double? α => _Α;
|
||||
public DateTime DateTime => _DateTime;
|
||||
public Shared.Models.FaceEncoding FaceEncoding => _FaceEncoding;
|
||||
public Dictionary<string, Shared.Models.FacePoint[]> FaceLandmarks => _FaceLandmarks;
|
||||
public OutputResolution OutputResolution => _OutputResolution;
|
||||
public Shared.Models.Location Location => _Location;
|
||||
public int? LocationIndex => _LocationIndex;
|
||||
public bool Populated => _Populated;
|
||||
public string RelativePath => _RelativePath;
|
||||
|
||||
#nullable disable
|
||||
[JsonConstructor]
|
||||
public D_Face(double? α, DateTime dateTime, Shared.Models.FaceEncoding faceEncoding, Dictionary<string, Shared.Models.FacePoint[]> faceLandmarks, Shared.Models.Location location, int? locationIndex, OutputResolution outputResolution, bool populated, string relativePath)
|
||||
{
|
||||
_Α = α;
|
||||
_DateTime = dateTime;
|
||||
_FaceEncoding = faceEncoding;
|
||||
_FaceLandmarks = faceLandmarks;
|
||||
_Location = location;
|
||||
_LocationIndex = locationIndex;
|
||||
_OutputResolution = outputResolution;
|
||||
_Populated = populated;
|
||||
_RelativePath = relativePath;
|
||||
}
|
||||
|
||||
internal D_Face(Configuration configuration, string argZero, Model model, ModelParameter modelParameter, PredictorModel predictorModel)
|
||||
{
|
||||
_Model = model;
|
||||
_ArgZero = argZero;
|
||||
_Configuration = configuration;
|
||||
_ModelParameter = modelParameter;
|
||||
_PredictorModel = predictorModel;
|
||||
AngleBracketCollection = new List<string>();
|
||||
_Log = Serilog.Log.ForContext<D_Face>();
|
||||
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
|
||||
}
|
||||
|
||||
private D_Face(Shared.Models.Location location)
|
||||
{
|
||||
_Α = α;
|
||||
_DateTime = DateTime.MinValue;
|
||||
_FaceEncoding = null;
|
||||
_FaceLandmarks = null;
|
||||
_OutputResolution = null;
|
||||
_Location = location;
|
||||
_LocationIndex = null;
|
||||
_Populated = false;
|
||||
_RelativePath = string.Empty;
|
||||
}
|
||||
|
||||
private D_Face()
|
||||
{
|
||||
_Α = α;
|
||||
_DateTime = DateTime.MinValue;
|
||||
_FaceEncoding = null;
|
||||
_FaceLandmarks = null;
|
||||
_OutputResolution = null;
|
||||
_Location = null;
|
||||
_LocationIndex = null;
|
||||
_Populated = false;
|
||||
_RelativePath = string.Empty;
|
||||
}
|
||||
|
||||
private D_Face(A_Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, string relativePath, int? i, Shared.Models.Location location)
|
||||
{
|
||||
DateTime?[] dateTimes;
|
||||
dateTimes = new DateTime?[] { property.CreationTime, property.LastWriteTime, property.DateTime, property.DateTimeDigitized, property.DateTimeOriginal, property.GPSDateStamp };
|
||||
_DateTime = (from l in dateTimes where l.HasValue select l.Value).Min();
|
||||
_FaceLandmarks = new Dictionary<string, Shared.Models.FacePoint[]>();
|
||||
_OutputResolution = new(outputResolutionHeight, outputResolutionOrientation, outputResolutionWidth);
|
||||
_Location = location;
|
||||
_LocationIndex = i;
|
||||
_Populated = false;
|
||||
_RelativePath = relativePath;
|
||||
}
|
||||
|
||||
private D_Face(int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, Shared.Models.Properties.IFace face)
|
||||
{
|
||||
_Α = face.α;
|
||||
_DateTime = face.DateTime;
|
||||
_FaceEncoding = face.FaceEncoding;
|
||||
_FaceLandmarks = face.FaceLandmarks;
|
||||
_OutputResolution = new(outputResolutionHeight, outputResolutionOrientation, outputResolutionWidth);
|
||||
_Location = face.Location;
|
||||
_LocationIndex = face.LocationIndex;
|
||||
_Populated = face.Populated;
|
||||
_RelativePath = face.RelativePath;
|
||||
}
|
||||
|
||||
private static void GetPointBounds(PointF[] points, out float xmin, out float xmax, out float ymin, out float ymax)
|
||||
{
|
||||
xmin = points[0].X;
|
||||
xmax = xmin;
|
||||
ymin = points[0].Y;
|
||||
ymax = ymin;
|
||||
foreach (PointF point in points)
|
||||
{
|
||||
if (xmin > point.X)
|
||||
xmin = point.X;
|
||||
if (xmax < point.X)
|
||||
xmax = point.X;
|
||||
if (ymin > point.Y)
|
||||
ymin = point.Y;
|
||||
if (ymax < point.Y)
|
||||
ymax = point.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
return result;
|
||||
}
|
||||
|
||||
#pragma warning disable CA1416
|
||||
|
||||
internal static Bitmap RotateBitmap(Bitmap bitmap, float angle)
|
||||
{
|
||||
Bitmap result;
|
||||
#if Linux
|
||||
throw new Exception("Built on Linux!");
|
||||
#elif OSX
|
||||
throw new Exception("Built on macOS!");
|
||||
#elif Windows
|
||||
// Make a Matrix to represent rotation
|
||||
// by this angle.
|
||||
Matrix rotate_at_origin = new();
|
||||
rotate_at_origin.Rotate(angle);
|
||||
|
||||
// Rotate the image's corners to see how big
|
||||
// it will be after rotation.
|
||||
PointF[] points =
|
||||
{
|
||||
new PointF(0, 0),
|
||||
new PointF(bitmap.Width, 0),
|
||||
new PointF(bitmap.Width, bitmap.Height),
|
||||
new PointF(0, bitmap.Height),
|
||||
};
|
||||
rotate_at_origin.TransformPoints(points);
|
||||
float xmin, xmax, ymin, ymax;
|
||||
GetPointBounds(points, out xmin, out xmax, out ymin, out ymax);
|
||||
|
||||
// Make a bitmap to hold the rotated result.
|
||||
int wid = (int)Math.Round(xmax - xmin);
|
||||
int hgt = (int)Math.Round(ymax - ymin);
|
||||
result = new Bitmap(wid, hgt);
|
||||
|
||||
// Create the real rotation transformation.
|
||||
Matrix rotate_at_center = new();
|
||||
rotate_at_center.RotateAt(angle,
|
||||
new PointF(wid / 2f, hgt / 2f));
|
||||
|
||||
// Draw the image onto the new bitmap rotated.
|
||||
using (Graphics gr = Graphics.FromImage(result))
|
||||
{
|
||||
// Use smooth image interpolation.
|
||||
gr.InterpolationMode = InterpolationMode.High;
|
||||
|
||||
// Clear with the color in the image's upper left corner.
|
||||
gr.Clear(bitmap.GetPixel(0, 0));
|
||||
|
||||
// For debugging. (It's easier to see the background.)
|
||||
// gr.Clear(Color.LightBlue);
|
||||
|
||||
// Set up the transformation to rotate.
|
||||
gr.Transform = rotate_at_center;
|
||||
|
||||
// Draw the image centered on the bitmap.
|
||||
int x = (wid - bitmap.Width) / 2;
|
||||
int y = (hgt - bitmap.Height) / 2;
|
||||
gr.DrawImage(bitmap, x, y);
|
||||
}
|
||||
#endif
|
||||
// Return the result bitmap.
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void SaveFaces(List<D_Face> faceCollection, FileInfo resizedFileInfo, List<string> imageFiles)
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
Graphics graphics;
|
||||
Rectangle rectangle;
|
||||
Bitmap preRotated;
|
||||
Shared.Models.Location location;
|
||||
using Bitmap source = new(resizedFileInfo.FullName);
|
||||
for (int i = 0; i < faceCollection.Count; i++)
|
||||
{
|
||||
if (!faceCollection[i].Populated || faceCollection[i]?.Location is null)
|
||||
continue;
|
||||
location = new Shared.Models.Location(faceCollection[i].Location.Confidence,
|
||||
faceCollection[i].Location.Bottom,
|
||||
faceCollection[i].Location.Left,
|
||||
faceCollection[i].Location.Right,
|
||||
faceCollection[i].Location.Top);
|
||||
width = location.Right - location.Left;
|
||||
height = location.Bottom - location.Top;
|
||||
rectangle = new Rectangle(location.Left, location.Top, width, height);
|
||||
using (preRotated = new(width, height))
|
||||
{
|
||||
using (graphics = Graphics.FromImage(preRotated))
|
||||
graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
|
||||
preRotated.Save(imageFiles[i], System.Drawing.Imaging.ImageFormat.Png);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<D_Face> GetFaces(FileInfo resizedFileInfo, string relativePath, string fileNameWithoutExtension, A_Property property, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation, string facesDirectory)
|
||||
{
|
||||
List<D_Face> results = new();
|
||||
if (_Configuration.PaddingLoops is null)
|
||||
throw new Exception();
|
||||
if (_Configuration.NumJitters is null)
|
||||
throw new Exception();
|
||||
FaceRecognitionDotNet.Location[] locations;
|
||||
FaceRecognitionDotNet.Image unknownImage = null;
|
||||
if (resizedFileInfo.Exists)
|
||||
{
|
||||
try
|
||||
{ unknownImage = FaceRecognition.LoadImageFile(resizedFileInfo.FullName); }
|
||||
catch (Exception) { }
|
||||
}
|
||||
if (unknownImage is null)
|
||||
results.Add(new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, relativePath, i: null, location: null));
|
||||
else
|
||||
{
|
||||
FaceRecognition faceRecognition = FaceRecognition.Create(_ModelParameter);
|
||||
locations = faceRecognition.FaceLocations(unknownImage, numberOfTimesToUpsample: 1, _Model).ToArray();
|
||||
if (!locations.Any())
|
||||
results.Add(new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, relativePath, i: null, location: null));
|
||||
else
|
||||
{
|
||||
double? α;
|
||||
int width;
|
||||
int height;
|
||||
int padding;
|
||||
int leftEyeX;
|
||||
int leftEyeY;
|
||||
int rightEyeX;
|
||||
int rightEyeY;
|
||||
string faceFile;
|
||||
Graphics graphics;
|
||||
D_Face face = null;
|
||||
Rectangle rectangle;
|
||||
double[] rawEncoding;
|
||||
Bitmap rotated;
|
||||
Bitmap preRotated;
|
||||
FaceRecognitionDotNet.Image knownImage;
|
||||
FaceRecognitionDotNet.Image rotatedImage;
|
||||
Shared.Models.Location location;
|
||||
FaceRecognitionDotNet.FaceEncoding[] faceEncodings;
|
||||
IEnumerable<FaceRecognitionDotNet.FacePoint> facePoints;
|
||||
Shared.Models.FaceEncoding faceEncoding;
|
||||
IDictionary<FacePart, IEnumerable<FaceRecognitionDotNet.FacePoint>>[] faceLandmarks;
|
||||
using Bitmap source = unknownImage.ToBitmap();
|
||||
padding = (int)((source.Width + source.Height) / 2 * .01);
|
||||
for (int i = 0; i < locations.Length; i++)
|
||||
{
|
||||
for (int p = 0; p <= _Configuration.PaddingLoops.Value; p++)
|
||||
{
|
||||
//Location(double confidence, int bottom, int left, int right, int top)
|
||||
location = new(locations[i].Confidence,
|
||||
locations[i].Bottom + (padding * p),
|
||||
locations[i].Left - (padding * p),
|
||||
locations[i].Right + (padding * p),
|
||||
locations[i].Top - (padding * p));
|
||||
face = new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, relativePath, i, location);
|
||||
width = location.Right - location.Left;
|
||||
height = location.Bottom - location.Top;
|
||||
rectangle = new Rectangle(location.Left, location.Top, width, height);
|
||||
using (preRotated = new Bitmap(width, height))
|
||||
{
|
||||
using (graphics = Graphics.FromImage(preRotated))
|
||||
graphics.DrawImage(source, new Rectangle(0, 0, width, height), rectangle, GraphicsUnit.Pixel);
|
||||
// source.Save(Path.Combine(_Configuration.RootDirectory, "source.jpg"));
|
||||
// preRotated.Save(Path.Combine(_Configuration.RootDirectory, $"{p} - preRotated.jpg"));
|
||||
using (knownImage = FaceRecognition.LoadImage(preRotated))
|
||||
faceLandmarks = faceRecognition.FaceLandmark(knownImage, faceLocations: null, _PredictorModel, _Model).ToArray();
|
||||
if (faceLandmarks.Length == 0 && p < _Configuration.PaddingLoops.Value)
|
||||
continue;
|
||||
else if (faceLandmarks.Length != 1)
|
||||
continue;
|
||||
foreach (KeyValuePair<FacePart, IEnumerable<FaceRecognitionDotNet.FacePoint>> keyValuePair in faceLandmarks[0])
|
||||
face.FaceLandmarks.Add(keyValuePair.Key.ToString(), (from l in keyValuePair.Value select new Shared.Models.FacePoint(l.Index, l.Point.X, l.Point.Y)).ToArray());
|
||||
if (!faceLandmarks[0].ContainsKey(FacePart.LeftEye) || !faceLandmarks[0].ContainsKey(FacePart.RightEye))
|
||||
continue;
|
||||
facePoints = faceLandmarks[0][FacePart.LeftEye];
|
||||
leftEyeX = (int)(from l in facePoints select l.Point.X).Average();
|
||||
leftEyeY = (int)(from l in facePoints select l.Point.Y).Average();
|
||||
facePoints = faceLandmarks[0][FacePart.RightEye];
|
||||
rightEyeX = (int)(from l in facePoints select l.Point.X).Average();
|
||||
rightEyeY = (int)(from l in facePoints select l.Point.Y).Average();
|
||||
α = Shared.Models.Stateless.Methods.IFace.Getα(rightEyeX, leftEyeX, rightEyeY, leftEyeY);
|
||||
using (rotated = RotateBitmap(preRotated, (float)α.Value))
|
||||
{
|
||||
// rotated.Save(Path.Combine(_Configuration.RootDirectory, $"{p} - rotated.jpg"));
|
||||
using (rotatedImage = FaceRecognition.LoadImage(rotated))
|
||||
faceEncodings = faceRecognition.FaceEncodings(rotatedImage, knownFaceLocation: null, _Configuration.NumJitters.Value, _PredictorModel, _Model).ToArray();
|
||||
if (faceEncodings.Length == 0 && p < _Configuration.PaddingLoops.Value)
|
||||
continue;
|
||||
else if (faceEncodings.Length != 1)
|
||||
continue;
|
||||
rawEncoding = faceEncodings[0].GetRawEncoding();
|
||||
faceEncoding = new(rawEncoding, faceEncodings[0].Size);
|
||||
face.Update(α, faceEncoding, populated: true);
|
||||
}
|
||||
faceFile = Path.Combine(facesDirectory, $"{i} - {fileNameWithoutExtension}.png");
|
||||
preRotated.Save(faceFile, System.Drawing.Imaging.ImageFormat.Png);
|
||||
results.Add(face);
|
||||
}
|
||||
if (face.Populated)
|
||||
break;
|
||||
}
|
||||
if (face is null || !face.Populated)
|
||||
{
|
||||
location = new(locations[i].Confidence,
|
||||
locations[i].Bottom,
|
||||
locations[i].Left,
|
||||
locations[i].Right,
|
||||
locations[i].Top);
|
||||
face = new D_Face(property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, relativePath, i, location);
|
||||
results.Add(face);
|
||||
}
|
||||
}
|
||||
}
|
||||
unknownImage.Dispose();
|
||||
faceRecognition.Dispose();
|
||||
}
|
||||
if (!results.Any())
|
||||
throw new Exception();
|
||||
return results;
|
||||
}
|
||||
|
||||
#pragma warning restore CA1416
|
||||
|
||||
private void Update(double? α, Shared.Models.FaceEncoding faceEncoding, bool populated)
|
||||
{
|
||||
_Α = α;
|
||||
_FaceEncoding = faceEncoding;
|
||||
_Populated = populated;
|
||||
}
|
||||
|
||||
internal List<D_Face> GetFaces(Property.Models.Configuration configuration, string outputResolution, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, string relativePath, string fileNameWithoutExtension, A_Property property, FileInfo resizedFileInfo, int outputResolutionWidth, int outputResolutionHeight, int outputResolutionOrientation)
|
||||
{
|
||||
List<D_Face> results;
|
||||
if (_Configuration.PropertiesChangedForFaces is null)
|
||||
throw new Exception();
|
||||
string json;
|
||||
D_Face face;
|
||||
bool checkForOutputResolutionChange = false;
|
||||
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) };
|
||||
string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), fileNameWithoutExtension);
|
||||
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||
FileInfo fileInfo = new(Path.Combine(AngleBracketCollection[0].Replace("<>", "[]"), $"{fileNameWithoutExtension}.json"));
|
||||
if (!fileInfo.Exists)
|
||||
{
|
||||
if (fileInfo.Directory?.Parent is null)
|
||||
throw new Exception();
|
||||
string parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
|
||||
if (File.Exists(parentCheck))
|
||||
File.Delete(parentCheck);
|
||||
}
|
||||
if (!Directory.Exists(facesDirectory))
|
||||
_ = Directory.CreateDirectory(facesDirectory);
|
||||
if (_Configuration.PropertiesChangedForFaces.Value)
|
||||
results = null;
|
||||
else if (!fileInfo.Exists)
|
||||
results = null;
|
||||
else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
||||
results = null;
|
||||
else
|
||||
{
|
||||
json = Shared.Models.Stateless.Methods.IFace.GetJson(fileInfo.FullName);
|
||||
try
|
||||
{
|
||||
results = JsonSerializer.Deserialize<List<D_Face>>(json);
|
||||
for (int i = 0; i < results.Count; i++)
|
||||
{
|
||||
face = results[i];
|
||||
if (face.OutputResolution is not null)
|
||||
continue;
|
||||
if (!checkForOutputResolutionChange)
|
||||
checkForOutputResolutionChange = true;
|
||||
results[i] = new(outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, face);
|
||||
}
|
||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), fileInfo.LastWriteTime));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
results = null;
|
||||
parseExceptions.Add(nameof(D_Face));
|
||||
}
|
||||
}
|
||||
if (results is not null && checkForOutputResolutionChange)
|
||||
{
|
||||
json = JsonSerializer.Serialize(results, _WriteIndentedJsonSerializerOptions);
|
||||
if (Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, compareBeforeWrite: true))
|
||||
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
|
||||
}
|
||||
else if (results is null)
|
||||
{
|
||||
results = GetFaces(resizedFileInfo, relativePath, fileNameWithoutExtension, property, outputResolutionWidth, outputResolutionHeight, outputResolutionOrientation, facesDirectory);
|
||||
json = JsonSerializer.Serialize(results, _WriteIndentedJsonSerializerOptions);
|
||||
if (Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, compareBeforeWrite: true))
|
||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(D_Face), DateTime.Now));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
internal void SaveFaces(Property.Models.Configuration configuration, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, string relativePath, string fileNameWithoutExtension, FileInfo resizedFileInfo, List<D_Face> faceCollection)
|
||||
{
|
||||
if (_Configuration.OverrideForFaceImages is null)
|
||||
throw new Exception();
|
||||
FileInfo fileInfo;
|
||||
bool check = false;
|
||||
string parentCheck;
|
||||
List<string> imageFiles = new();
|
||||
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize) };
|
||||
string facesDirectory = Path.Combine(AngleBracketCollection[0].Replace("<>", "()"), fileNameWithoutExtension);
|
||||
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||
bool facesDirectoryExisted = Directory.Exists(facesDirectory);
|
||||
if (!facesDirectoryExisted)
|
||||
_ = Directory.CreateDirectory(facesDirectory);
|
||||
for (int i = 0; i < faceCollection.Count; i++)
|
||||
{
|
||||
if (!faceCollection[i].Populated || faceCollection[i]?.Location is null)
|
||||
{
|
||||
imageFiles.Add(string.Empty);
|
||||
continue;
|
||||
}
|
||||
fileInfo = new FileInfo(Path.Combine(facesDirectory, $"{i} - {fileNameWithoutExtension}.png"));
|
||||
if (!fileInfo.Exists)
|
||||
{
|
||||
if (fileInfo.Directory?.Parent is null)
|
||||
throw new Exception();
|
||||
parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
|
||||
if (File.Exists(parentCheck))
|
||||
File.Delete(parentCheck);
|
||||
}
|
||||
imageFiles.Add(fileInfo.FullName);
|
||||
if (_Configuration.OverrideForFaceImages.Value)
|
||||
check = true;
|
||||
else if (!fileInfo.Exists)
|
||||
check = true;
|
||||
else if (dateTimes.Any() && dateTimes.Max() > fileInfo.LastWriteTime)
|
||||
check = true;
|
||||
}
|
||||
if (check)
|
||||
SaveFaces(faceCollection, resizedFileInfo, imageFiles);
|
||||
}
|
||||
|
||||
double Shared.Models.Stateless.Methods.IFace.TestStatic_Getα(int x1, int x2, int y1, int y2) => throw new NotImplementedException();
|
||||
|
||||
string Shared.Models.Stateless.Methods.IFace.TestStatic_GetJson(string jsonFileFullName) => throw new NotImplementedException();
|
||||
|
||||
Face Shared.Models.Stateless.Methods.IFace.TestStatic_GetFace(string jsonFileFullName) => throw new NotImplementedException();
|
||||
|
||||
Face[] Shared.Models.Stateless.Methods.IFace.TestStatic_GetFaces(string jsonFileFullName) => throw new NotImplementedException();
|
||||
|
||||
}
|
230
Instance/Models/_E2_Navigate.cs
Normal file
230
Instance/Models/_E2_Navigate.cs
Normal file
@ -0,0 +1,230 @@
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Instance.Models.Stateless;
|
||||
using View_by_Distance.Metadata.Models;
|
||||
using View_by_Distance.Resize.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Methods;
|
||||
|
||||
namespace View_by_Distance.Instance.Models;
|
||||
|
||||
/// <summary>
|
||||
// N/A
|
||||
/// </summary>
|
||||
internal class E2_Navigate
|
||||
{
|
||||
|
||||
private readonly string _ArgZero;
|
||||
private readonly E3_Rename _Rename;
|
||||
private readonly IConsole _Console;
|
||||
private readonly Serilog.ILogger? _Log;
|
||||
private readonly Configuration _Configuration;
|
||||
|
||||
internal E2_Navigate(IConsole console, Configuration configuration, string argZero)
|
||||
{
|
||||
_Console = console;
|
||||
_ArgZero = argZero;
|
||||
_Configuration = configuration;
|
||||
_Rename = new E3_Rename(configuration);
|
||||
_Log = Serilog.Log.ForContext<E2_Navigate>();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
return result;
|
||||
}
|
||||
|
||||
private void DisplayTags(Property.Models.Configuration configuration, string outputResolution, string[] directories, Dictionary<ConsoleKey, int> directoryKeyValuePairs, string[] files, Dictionary<ConsoleKey, int> fileKeyValuePairs)
|
||||
{
|
||||
if (_Log is null)
|
||||
throw new Exception($"{nameof(_Log)} is null!");
|
||||
bool all = false;
|
||||
FileSystem fileSystem;
|
||||
string requestPath = "/RootResultsDirectory";
|
||||
string? rootResultsDirectory = Path.GetDirectoryName(Property.Models.Stateless.IResult.GetResultsGroupDirectory(configuration, nameof(B_Metadata)));
|
||||
if (string.IsNullOrEmpty(rootResultsDirectory))
|
||||
throw new Exception();
|
||||
string rootResultsDirectoryAbsoluteUri = new Uri(rootResultsDirectory).AbsoluteUri;
|
||||
string dFacesContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
|
||||
string cResizeContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(C_Resize), outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false), "()");
|
||||
string eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
|
||||
(string RootResultsDirectoryAbsoluteUri, string C_ResizeContentDirectory, string D_FacesContentDirectory, string E_DistanceCollectionDirectory) tuple = new(rootResultsDirectoryAbsoluteUri, cResizeContentDirectory, dFacesContentDirectory, eDistanceCollectionDirectory);
|
||||
List<FileSystem> fileSystemCollection = Shared.Models.Stateless.Methods.IFileSystem.GetFileSystemCollection(requestPath, tuple, directories, files, all);
|
||||
Queue<FileSystem> queue = new(fileSystemCollection);
|
||||
foreach (KeyValuePair<ConsoleKey, int> element in directoryKeyValuePairs)
|
||||
{
|
||||
fileSystem = queue.Dequeue();
|
||||
_Log.Warn(string.Concat(element.Key, " - D) ", " <", fileSystem.Display, ">"));
|
||||
// _Log.Info(string.Join(Environment.NewLine, from l in fileSystem where !string.IsNullOrEmpty(l) select l));
|
||||
_Log.Info(string.Empty);
|
||||
}
|
||||
foreach (KeyValuePair<ConsoleKey, int> element in fileKeyValuePairs)
|
||||
{
|
||||
fileSystem = queue.Dequeue();
|
||||
_Log.Warn(string.Concat(element.Key, " - F) [", fileSystem.Display, '}'));
|
||||
// _Log.Info(string.Join(Environment.NewLine, from l in fileSystem where !string.IsNullOrEmpty(l) select l));
|
||||
_Log.Info(string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
private void DisplayFaces(Property.Models.Configuration configuration, string outputResolution, string selectedFileFullName)
|
||||
{
|
||||
if (_Log is null)
|
||||
throw new Exception($"{nameof(_Log)} is null!");
|
||||
string requestPath = "/RootResultsDirectory";
|
||||
string? rootResultsDirectory = Path.GetDirectoryName(Property.Models.Stateless.IResult.GetResultsGroupDirectory(configuration, nameof(B_Metadata)));
|
||||
if (string.IsNullOrEmpty(rootResultsDirectory))
|
||||
throw new Exception();
|
||||
string rootResultsDirectoryAbsoluteUri = new Uri(rootResultsDirectory).AbsoluteUri;
|
||||
string dFacesContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
|
||||
string cResizeContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(C_Resize), outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false), "()");
|
||||
string eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
|
||||
(string RootResultsDirectoryAbsoluteUri, string C_ResizeContentDirectory, string D_FacesContentDirectory, string E_DistanceCollectionDirectory) tuple = new(rootResultsDirectoryAbsoluteUri, cResizeContentDirectory, dFacesContentDirectory, eDistanceCollectionDirectory);
|
||||
FaceFileSystem[] faceFileSystemCollection = Shared.Models.Stateless.Methods.IFaceFileSystem.GetFaceFileSystemCollection(requestPath, tuple, selectedFileFullName);
|
||||
for (int i = 0; i < faceFileSystemCollection.Length; i++)
|
||||
{
|
||||
_Log.Warn(string.Concat(i, " - F) [", faceFileSystemCollection[i].Display, '}'));
|
||||
// _Log.Info(string.Join(Environment.NewLine, from l in fileSystemCollection[i] where !string.IsNullOrEmpty(l) select l));
|
||||
_Log.Info(string.Empty);
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
private string Rename(Property.Models.Configuration configuration, string subSourceDirectory)
|
||||
{
|
||||
string result;
|
||||
if (_Log is null)
|
||||
throw new Exception($"{nameof(_Log)} is null!");
|
||||
if (_Configuration?.PropertyConfiguration is null)
|
||||
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!");
|
||||
_Log.Warn(string.Concat("What is the new name for [", Path.GetFileName(subSourceDirectory), "]<", subSourceDirectory, ">?"));
|
||||
string? newDirectoryName = _Console.ReadLine();
|
||||
_Log.Warn("Are you sure y[es] || n[o]?");
|
||||
if (string.IsNullOrEmpty(newDirectoryName) || _Console.ReadKey() != ConsoleKey.Y)
|
||||
{
|
||||
_Log.Warn(string.Empty);
|
||||
_Log.Warn("No changes made.");
|
||||
result = subSourceDirectory;
|
||||
}
|
||||
else
|
||||
{
|
||||
_Log.Warn(string.Empty);
|
||||
string eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(E_Distance), _Configuration.ValidResolutions[0], includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
|
||||
string relativePath = Property.Models.Stateless.IPath.GetRelativePath(subSourceDirectory, eDistanceCollectionDirectory.Length);
|
||||
if (relativePath.Length == 1)
|
||||
throw new Exception();
|
||||
if (Directory.Exists(Path.Combine(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName)))
|
||||
{
|
||||
_Log.Warn("\"To\" directory already exits!");
|
||||
result = subSourceDirectory;
|
||||
}
|
||||
else
|
||||
{
|
||||
_Rename.DirectoryRename(configuration, relativePath, newDirectoryName);
|
||||
_Log.Warn("Renamed...");
|
||||
string? directoryName = Path.GetDirectoryName(subSourceDirectory);
|
||||
if (string.IsNullOrEmpty(directoryName))
|
||||
throw new Exception();
|
||||
result = Path.Combine(directoryName, newDirectoryName);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void Navigate(Property.Models.Configuration configuration, string outputResolution)
|
||||
{
|
||||
if (_Log is null)
|
||||
throw new Exception($"{nameof(_Log)} is null!");
|
||||
string[] subFiles;
|
||||
ConsoleKey consoleKey;
|
||||
string[] subDirectories;
|
||||
string selectedFileFullName;
|
||||
string rootDirectory = string.Empty;
|
||||
string? subSourceDirectory = string.Empty;
|
||||
Dictionary<ConsoleKey, int> fileKeyValuePairs = new();
|
||||
Dictionary<ConsoleKey, int> directoryKeyValuePairs = new();
|
||||
string eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(E_Distance), _Configuration.OutputResolutions[0], includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
|
||||
if (!Directory.Exists(eDistanceCollectionDirectory))
|
||||
_ = Directory.CreateDirectory(eDistanceCollectionDirectory);
|
||||
for (int z = 0; z < int.MaxValue; z++)
|
||||
{
|
||||
if (string.IsNullOrEmpty(subSourceDirectory))
|
||||
{
|
||||
rootDirectory = eDistanceCollectionDirectory;
|
||||
subSourceDirectory = rootDirectory;
|
||||
}
|
||||
subFiles = Directory.GetFiles(subSourceDirectory, "*.json", SearchOption.TopDirectoryOnly);
|
||||
subDirectories = Directory.GetDirectories(subSourceDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
directoryKeyValuePairs.Clear();
|
||||
for (int i = (int)ConsoleKey.A; i < (subDirectories.Length + (int)ConsoleKey.A) && i <= (int)ConsoleKey.RightWindows; i++)
|
||||
directoryKeyValuePairs.Add((ConsoleKey)i, i - (int)ConsoleKey.A);
|
||||
fileKeyValuePairs.Clear();
|
||||
for (int i = (int)ConsoleKey.A + subDirectories.Length; i < (subFiles.Length + (int)ConsoleKey.A + subDirectories.Length) && i <= (int)ConsoleKey.RightWindows; i++)
|
||||
fileKeyValuePairs.Add((ConsoleKey)i, i - (int)ConsoleKey.A);
|
||||
_Log.Warn("");
|
||||
DisplayTags(configuration, outputResolution, subDirectories, directoryKeyValuePairs, subFiles, fileKeyValuePairs);
|
||||
_Log.Warn(string.Empty);
|
||||
_Log.Warn(string.Empty);
|
||||
_Log.Warn(string.Empty);
|
||||
_Log.Warn("Select a file system object. Enter \"Backspace\" to go up a directory, \"F2\" to rename and \"Esc\" to end navigation.");
|
||||
consoleKey = _Console.ReadKey();
|
||||
_Log.Warn(string.Empty);
|
||||
if (consoleKey == ConsoleKey.Escape)
|
||||
break;
|
||||
if (consoleKey == ConsoleKey.F2)
|
||||
{
|
||||
if (subSourceDirectory == rootDirectory)
|
||||
{
|
||||
_Log.Warn("Root directory can not be renamed! Try again.");
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
subSourceDirectory = Rename(configuration, subSourceDirectory);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (consoleKey is ConsoleKey.Backspace or ConsoleKey.LeftArrow)
|
||||
{
|
||||
if (subSourceDirectory != rootDirectory)
|
||||
subSourceDirectory = Path.GetDirectoryName(subSourceDirectory);
|
||||
else
|
||||
{
|
||||
_Log.Warn("At root directory. Try again.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (directoryKeyValuePairs.ContainsKey(consoleKey))
|
||||
{
|
||||
subSourceDirectory = subDirectories[directoryKeyValuePairs[consoleKey]];
|
||||
_Log.Warn(string.Concat(">>> [", Path.GetFileName(subSourceDirectory), "]<", subSourceDirectory, ">?"));
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!fileKeyValuePairs.ContainsKey(consoleKey))
|
||||
{
|
||||
subSourceDirectory = _ArgZero;
|
||||
_Log.Warn("Invalid selection. Try again.");
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedFileFullName = subFiles[fileKeyValuePairs[consoleKey]];
|
||||
_Log.Warn(string.Concat(">>> [", Path.GetFileName(selectedFileFullName), "]<", selectedFileFullName, ">?"));
|
||||
DisplayFaces(configuration, outputResolution, selectedFileFullName);
|
||||
_Log.Warn(string.Empty);
|
||||
_Log.Warn(string.Empty);
|
||||
_Log.Warn(string.Empty);
|
||||
_Log.Warn("Go up a directory? Enter escape end.");
|
||||
consoleKey = _Console.ReadKey();
|
||||
if (consoleKey == ConsoleKey.Escape)
|
||||
break;
|
||||
subSourceDirectory = Path.GetDirectoryName(subSourceDirectory);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
338
Instance/Models/_E3_Rename.cs
Normal file
338
Instance/Models/_E3_Rename.cs
Normal file
@ -0,0 +1,338 @@
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Metadata.Models;
|
||||
using View_by_Distance.Property.Models;
|
||||
using View_by_Distance.Resize.Models;
|
||||
|
||||
namespace View_by_Distance.Instance.Models;
|
||||
|
||||
/// <summary>
|
||||
// N/A
|
||||
/// </summary>
|
||||
internal class E3_Rename
|
||||
{
|
||||
|
||||
private readonly Serilog.ILogger? _Log;
|
||||
private readonly Configuration _Configuration;
|
||||
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
|
||||
|
||||
internal E3_Rename(Configuration configuration)
|
||||
{
|
||||
_Configuration = configuration;
|
||||
_Log = Serilog.Log.ForContext<G2_Identify>();
|
||||
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
return result;
|
||||
}
|
||||
|
||||
internal string[] GetDirectoryRenameCollection(Property.Models.Configuration configuration, string relativePath, string newDirectoryName, bool jsonFiles4InfoAny)
|
||||
{
|
||||
List<string> results = new();
|
||||
bool add;
|
||||
string to;
|
||||
string dFacesContentDirectory;
|
||||
string cResizeContentDirectory;
|
||||
string dFacesCollectionDirectory;
|
||||
string cResizeSingletonDirectory;
|
||||
string eDistanceContentDirectory;
|
||||
string aPropertySingletonDirectory;
|
||||
string bMetadataSingletonDirectory;
|
||||
string eDistanceCollectionDirectory;
|
||||
string g2IdentifyCollectionDirectory;
|
||||
string d2FaceLandmarksContentDirectory;
|
||||
add = Directory.Exists(string.Concat(Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(C_Resize), _Configuration.ValidResolutions[0], includeResizeGroup: true, includeModel: false, includePredictorModel: false), "()"), relativePath));
|
||||
bMetadataSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(B_Metadata), "{}");
|
||||
if (Directory.Exists(bMetadataSingletonDirectory))
|
||||
{
|
||||
to = Path.Combine(string.Concat(bMetadataSingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(to);
|
||||
}
|
||||
aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
|
||||
if (Directory.Exists(aPropertySingletonDirectory))
|
||||
{
|
||||
to = Path.Combine(string.Concat(aPropertySingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(to);
|
||||
}
|
||||
cResizeContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(C_Resize), _Configuration.ValidResolutions[0], includeResizeGroup: true, includeModel: false, includePredictorModel: false), "()");
|
||||
if (Directory.Exists(cResizeContentDirectory))
|
||||
{
|
||||
to = Path.Combine(string.Concat(cResizeContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(to);
|
||||
}
|
||||
foreach (string outputResolution in _Configuration.ValidResolutions)
|
||||
{
|
||||
cResizeSingletonDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(C_Resize), outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false), "{}");
|
||||
if (Directory.Exists(cResizeSingletonDirectory))
|
||||
{
|
||||
to = Path.Combine(string.Concat(cResizeSingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(to);
|
||||
}
|
||||
dFacesContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
|
||||
if (Directory.Exists(dFacesContentDirectory))
|
||||
{
|
||||
to = Path.Combine(string.Concat(dFacesContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(to);
|
||||
}
|
||||
dFacesCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
|
||||
if (Directory.Exists(dFacesCollectionDirectory))
|
||||
{
|
||||
to = Path.Combine(string.Concat(dFacesCollectionDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(to);
|
||||
}
|
||||
d2FaceLandmarksContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(D2_FaceLandmarks), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
|
||||
if (add && _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution) && Directory.Exists(d2FaceLandmarksContentDirectory))
|
||||
{
|
||||
to = Path.Combine(string.Concat(d2FaceLandmarksContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(to);
|
||||
}
|
||||
eDistanceContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
|
||||
if (Directory.Exists(eDistanceContentDirectory))
|
||||
{
|
||||
to = Path.Combine(string.Concat(eDistanceContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(to);
|
||||
}
|
||||
eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
|
||||
if (Directory.Exists(eDistanceCollectionDirectory))
|
||||
{
|
||||
to = Path.Combine(string.Concat(eDistanceCollectionDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(to);
|
||||
}
|
||||
g2IdentifyCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(G2_Identify), "[]");
|
||||
if (add && jsonFiles4InfoAny && Directory.Exists(g2IdentifyCollectionDirectory))
|
||||
{
|
||||
to = Path.Combine(string.Concat(g2IdentifyCollectionDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(to);
|
||||
}
|
||||
}
|
||||
return results.ToArray();
|
||||
}
|
||||
|
||||
internal List<string[]> GetDirectoryRenameCollections(Property.Models.Configuration configuration, string relativePath, string newDirectoryName, bool jsonFiles4InfoAny)
|
||||
{
|
||||
List<string[]> results = new();
|
||||
if (_Configuration?.PropertyConfiguration is null)
|
||||
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!");
|
||||
bool add;
|
||||
string to;
|
||||
bool exists;
|
||||
string from;
|
||||
string dFacesContentDirectory;
|
||||
string cResizeContentDirectory;
|
||||
string dFacesCollectionDirectory;
|
||||
string cResizeSingletonDirectory;
|
||||
string eDistanceContentDirectory;
|
||||
string bMetadataSingletonDirectory;
|
||||
string aPropertySingletonDirectory;
|
||||
string eDistanceCollectionDirectory;
|
||||
string g2IdentifyCollectionDirectory;
|
||||
string d2FaceLandmarksContentDirectory;
|
||||
if (!string.IsNullOrEmpty(relativePath))
|
||||
{
|
||||
from = string.Concat(_Configuration.PropertyConfiguration.RootDirectory, relativePath);
|
||||
to = Path.Combine(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(new string[] { from, to });
|
||||
}
|
||||
foreach (string outputResolution in _Configuration.ValidResolutions)
|
||||
{
|
||||
add = Directory.Exists(string.Concat(Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(C_Resize), outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false), "()"), relativePath));
|
||||
bMetadataSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(B_Metadata), "{}");
|
||||
from = string.Concat(bMetadataSingletonDirectory, relativePath);
|
||||
exists = Directory.Exists(bMetadataSingletonDirectory);
|
||||
if (exists)
|
||||
{
|
||||
to = Path.Combine(string.Concat(bMetadataSingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(new string[] { from, to });
|
||||
}
|
||||
aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
|
||||
from = string.Concat(aPropertySingletonDirectory, relativePath);
|
||||
exists = Directory.Exists(aPropertySingletonDirectory);
|
||||
if (exists)
|
||||
{
|
||||
to = Path.Combine(string.Concat(aPropertySingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(new string[] { from, to });
|
||||
}
|
||||
cResizeContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(C_Resize), outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false), "()");
|
||||
from = string.Concat(cResizeContentDirectory, relativePath);
|
||||
exists = Directory.Exists(cResizeContentDirectory);
|
||||
if (exists)
|
||||
{
|
||||
to = Path.Combine(string.Concat(cResizeContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(new string[] { from, to });
|
||||
}
|
||||
cResizeSingletonDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(C_Resize), outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false), "{}");
|
||||
from = string.Concat(cResizeSingletonDirectory, relativePath);
|
||||
exists = Directory.Exists(cResizeSingletonDirectory);
|
||||
if (exists)
|
||||
{
|
||||
to = Path.Combine(string.Concat(cResizeSingletonDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(new string[] { from, to });
|
||||
}
|
||||
dFacesContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
|
||||
from = string.Concat(dFacesContentDirectory, relativePath);
|
||||
exists = Directory.Exists(dFacesContentDirectory);
|
||||
if (exists)
|
||||
{
|
||||
to = Path.Combine(string.Concat(dFacesContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(new string[] { from, to });
|
||||
}
|
||||
dFacesCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
|
||||
from = string.Concat(dFacesCollectionDirectory, relativePath);
|
||||
exists = Directory.Exists(dFacesCollectionDirectory);
|
||||
if (exists)
|
||||
{
|
||||
to = Path.Combine(string.Concat(dFacesCollectionDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(new string[] { from, to });
|
||||
}
|
||||
d2FaceLandmarksContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(D2_FaceLandmarks), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
|
||||
from = string.Concat(d2FaceLandmarksContentDirectory, relativePath);
|
||||
exists = Directory.Exists(d2FaceLandmarksContentDirectory);
|
||||
if (!exists && add && _Configuration.SaveFaceLandmarkForOutputResolutions.Contains(outputResolution))
|
||||
results.Add(new string[] { from });
|
||||
else if (exists)
|
||||
{
|
||||
to = Path.Combine(string.Concat(d2FaceLandmarksContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(new string[] { from, to });
|
||||
}
|
||||
eDistanceContentDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "()");
|
||||
from = string.Concat(eDistanceContentDirectory, relativePath);
|
||||
exists = Directory.Exists(eDistanceContentDirectory);
|
||||
if (exists)
|
||||
{
|
||||
to = Path.Combine(string.Concat(eDistanceContentDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(new string[] { from, to });
|
||||
}
|
||||
eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
|
||||
from = string.Concat(eDistanceCollectionDirectory, relativePath);
|
||||
exists = Directory.Exists(eDistanceCollectionDirectory);
|
||||
if (exists)
|
||||
{
|
||||
to = Path.Combine(string.Concat(eDistanceCollectionDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(new string[] { from, to });
|
||||
}
|
||||
g2IdentifyCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(G2_Identify), "[]");
|
||||
from = string.Concat(g2IdentifyCollectionDirectory, relativePath);
|
||||
exists = Directory.Exists(g2IdentifyCollectionDirectory);
|
||||
if (!exists && add && jsonFiles4InfoAny)
|
||||
results.Add(new string[] { from });
|
||||
else if (exists)
|
||||
{
|
||||
to = Path.Combine(string.Concat(g2IdentifyCollectionDirectory, Path.GetDirectoryName(relativePath)), newDirectoryName);
|
||||
results.Add(new string[] { from, to });
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
internal void DirectoryRename(Property.Models.Configuration configuration, string relativePath, string newDirectoryName)
|
||||
{
|
||||
if (_Configuration?.PropertyConfiguration is null)
|
||||
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!");
|
||||
string json;
|
||||
FileInfo current;
|
||||
FileInfo fileInfo;
|
||||
string error = "Error";
|
||||
string target = "Target";
|
||||
string pending = "Pending";
|
||||
DirectoryInfo directoryInfo;
|
||||
IEnumerator<FileInfo> fileInfoCollection;
|
||||
string oldValue = string.Concat("\"", relativePath);
|
||||
string oldDirectoryName = Path.GetFileName(relativePath);
|
||||
string traceFileName = string.Concat(DateTime.Now.Ticks, ".tsv");
|
||||
string directoryName = Path.GetFileName(_Configuration.PropertyConfiguration.RootDirectory);
|
||||
string? relativePathParent = Path.GetDirectoryName(relativePath);
|
||||
if (string.IsNullOrEmpty(relativePathParent))
|
||||
throw new Exception();
|
||||
string newValue = string.Concat("\"", Path.Combine(relativePathParent, newDirectoryName));
|
||||
string e3RenameContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(E3_Rename), "()");
|
||||
string jsonRootDirectory = Path.Combine(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, " - Copied"), string.Concat(directoryName, " - 4) Info"), _Configuration.PropertyConfiguration.DateGroup, "[]");
|
||||
directoryInfo = new DirectoryInfo(jsonRootDirectory);
|
||||
if (!directoryInfo.Exists)
|
||||
directoryInfo.Create();
|
||||
IEnumerator<FileInfo> fileInfoCollection4 = directoryInfo.EnumerateFiles("*.json", SearchOption.AllDirectories).GetEnumerator();
|
||||
bool fileInfoCollection4MoveNext = fileInfoCollection4.MoveNext();
|
||||
if (!fileInfoCollection4MoveNext)
|
||||
current = new(string.Empty);
|
||||
else
|
||||
current = fileInfoCollection4.Current;
|
||||
List<string[]> directoryCollections = GetDirectoryRenameCollections(configuration, relativePath, newDirectoryName, fileInfoCollection4MoveNext);
|
||||
if ((from l in directoryCollections where l.Length != 2 select true).Any())
|
||||
throw new Exception();
|
||||
if (!Directory.Exists(e3RenameContentDirectory))
|
||||
{
|
||||
_ = Directory.CreateDirectory(e3RenameContentDirectory);
|
||||
_ = Directory.CreateDirectory(Path.Combine(e3RenameContentDirectory, error));
|
||||
_ = Directory.CreateDirectory(Path.Combine(e3RenameContentDirectory, target));
|
||||
_ = Directory.CreateDirectory(Path.Combine(e3RenameContentDirectory, "Test"));
|
||||
_ = Directory.CreateDirectory(Path.Combine(e3RenameContentDirectory, pending));
|
||||
}
|
||||
string fRandomSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(F_Random), "{}");
|
||||
string[] files = Directory.GetFiles(fRandomSingletonDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
foreach (string file in files)
|
||||
File.Delete(file);
|
||||
File.WriteAllText(Path.Combine(e3RenameContentDirectory, pending, traceFileName), string.Concat(relativePath, newDirectoryName, Environment.NewLine));
|
||||
try
|
||||
{
|
||||
foreach (string[] directoryCollection in directoryCollections)
|
||||
{
|
||||
directoryInfo = new DirectoryInfo(directoryCollection[0]);
|
||||
if (!directoryInfo.Exists)
|
||||
continue;
|
||||
fileInfoCollection = directoryInfo.EnumerateFiles("*.json", SearchOption.AllDirectories).GetEnumerator();
|
||||
for (int i = 0; i < int.MaxValue; i++)
|
||||
{
|
||||
if (fileInfoCollection.MoveNext())
|
||||
fileInfo = fileInfoCollection.Current;
|
||||
else if (fileInfoCollection4MoveNext && fileInfoCollection4.MoveNext())
|
||||
fileInfo = fileInfoCollection4.Current;
|
||||
else if (fileInfoCollection4MoveNext && current is not null)
|
||||
{
|
||||
fileInfo = current;
|
||||
current = new(string.Empty);
|
||||
}
|
||||
else
|
||||
break;
|
||||
json = Shared.Models.Stateless.Methods.IIndex.GetJson(fileInfo.FullName, fileInfo);
|
||||
if (json.Contains(oldValue))
|
||||
{
|
||||
json = json.Replace(oldValue, newValue);
|
||||
if (!Property.Models.Stateless.IPath.WriteAllText(fileInfo.FullName, json, compareBeforeWrite: true))
|
||||
continue;
|
||||
File.SetLastWriteTime(fileInfo.FullName, fileInfo.LastWriteTime);
|
||||
}
|
||||
}
|
||||
Directory.Move(directoryCollection[0], directoryCollection[1]);
|
||||
}
|
||||
File.Move(Path.Combine(e3RenameContentDirectory, pending, traceFileName), Path.Combine(e3RenameContentDirectory, target, traceFileName));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
File.Move(Path.Combine(e3RenameContentDirectory, pending, traceFileName), Path.Combine(e3RenameContentDirectory, error, traceFileName));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
internal void RenameQueue(Property.Models.Configuration configuration)
|
||||
{
|
||||
string[] lines;
|
||||
string[] segments;
|
||||
string e3RenameContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(E3_Rename), "()");
|
||||
string[] files = Directory.GetFiles(e3RenameContentDirectory, "*.tsv", SearchOption.TopDirectoryOnly);
|
||||
foreach (string file in files)
|
||||
{
|
||||
lines = File.ReadAllLines(file);
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (string.IsNullOrEmpty(line) || !line.Contains('\t'))
|
||||
continue;
|
||||
segments = line.Split('\t');
|
||||
if (segments.Length != 2)
|
||||
throw new Exception();
|
||||
DirectoryRename(configuration, segments[0], segments[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
390
Instance/Models/_E_Distance.cs
Normal file
390
Instance/Models/_E_Distance.cs
Normal file
@ -0,0 +1,390 @@
|
||||
using FaceRecognitionDotNet;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using View_by_Distance.Metadata.Models;
|
||||
using View_by_Distance.Property.Models;
|
||||
using View_by_Distance.Resize.Models;
|
||||
|
||||
namespace View_by_Distance.Instance.Models;
|
||||
|
||||
/// <summary>
|
||||
// List<D_Faces>
|
||||
/// </summary>
|
||||
|
||||
internal class E_Distance
|
||||
{
|
||||
|
||||
private readonly Serilog.ILogger? _Log;
|
||||
private readonly Configuration _Configuration;
|
||||
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
|
||||
|
||||
internal E_Distance(Configuration configuration)
|
||||
{
|
||||
_Configuration = configuration;
|
||||
_Log = Serilog.Log.ForContext<E_Distance>();
|
||||
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void LoadFaceEncodingCollections(string[] subFiles, List<List<D_Face>> faceCollections, List<int[]> locationIndicesCollection, List<FaceEncoding> faceEncodingCollection, List<List<FaceEncoding>> faceEncodingCollections)
|
||||
{
|
||||
List<D_Face> faceCollection;
|
||||
FaceEncoding faceEncoding;
|
||||
for (int i = 0; i < subFiles.Length; i++)
|
||||
{
|
||||
faceCollection = faceCollections[i];
|
||||
if (!faceCollection.Any())
|
||||
throw new Exception();
|
||||
faceEncodingCollections.Add(new List<FaceEncoding>());
|
||||
for (int j = 0; j < faceCollection.Count; j++)
|
||||
{
|
||||
if (!faceCollection[j].Populated)
|
||||
continue;
|
||||
faceEncoding = FaceRecognition.LoadFaceEncoding(faceCollection[j].FaceEncoding.RawEncoding);
|
||||
faceEncodingCollection.Add(faceEncoding);
|
||||
faceEncodingCollections[i].Add(faceEncoding);
|
||||
locationIndicesCollection.Add(new int[] { i, j });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Tuple<Shared.Models.Properties.IFace, string>> GetOrderedNoFaceCollection(List<List<D_Face>> faceCollections, int i, D_Face face)
|
||||
{
|
||||
List<Tuple<Shared.Models.Properties.IFace, string>> results = new() { new(face, string.Empty) };
|
||||
if (_Configuration.MaxItemsInDistanceCollection is null)
|
||||
throw new Exception();
|
||||
for (int n = 0; n < faceCollections.Count; n++)
|
||||
{
|
||||
if (i == n)
|
||||
continue;
|
||||
for (int j = 0; j < faceCollections[n].Count; j++)
|
||||
results.Add(new(faceCollections[n][j], string.Empty));
|
||||
}
|
||||
for (int r = results.Count - 1; r > _Configuration.MaxItemsInDistanceCollection.Value; r--)
|
||||
results.RemoveAt(r);
|
||||
return results;
|
||||
}
|
||||
|
||||
private List<double[]> GetValues(List<List<D_Face>> faceCollections, List<int[]> locationIndicesCollection, double[] faceDistances)
|
||||
{
|
||||
List<double[]> results = new();
|
||||
if (_Configuration.LocationConfidenceFactor is null)
|
||||
throw new Exception();
|
||||
if (_Configuration.DistanceFactor is null)
|
||||
throw new Exception();
|
||||
D_Face face;
|
||||
int[] locationIndices;
|
||||
for (int d = 0; d < faceDistances.Length; d++)
|
||||
{
|
||||
locationIndices = locationIndicesCollection[d];
|
||||
face = faceCollections[locationIndices[0]][locationIndices[1]];
|
||||
if (face.Populated && face.LocationIndex is not null && locationIndices[1] != face.LocationIndex)
|
||||
throw new Exception();
|
||||
results.Add(new double[] { d, faceDistances[d], (faceDistances[d] * _Configuration.DistanceFactor.Value) + face.Location.Confidence * _Configuration.LocationConfidenceFactor.Value / 10 });
|
||||
}
|
||||
results = (from l in results orderby l[2] select l).ToList();
|
||||
return results;
|
||||
}
|
||||
|
||||
private List<Tuple<Shared.Models.Properties.IFace, string>> GetOrderedFaceCollection(List<List<D_Face>> faceCollections, List<int[]> locationIndicesCollection, List<double[]> indicesAndValues)
|
||||
{
|
||||
List<Tuple<Shared.Models.Properties.IFace, string>> results = new();
|
||||
if (_Configuration.MaxItemsInDistanceCollection is null)
|
||||
throw new Exception();
|
||||
int[] locationIndices;
|
||||
for (int t = 0; t < indicesAndValues.Count; t++)
|
||||
{
|
||||
locationIndices = locationIndicesCollection[(int)indicesAndValues[t][0]];
|
||||
results.Add(new(faceCollections[locationIndices[0]][locationIndices[1]], string.Join('|', (from l in indicesAndValues[t] select l.ToString("0.000")).ToArray(), 1, indicesAndValues[t].Length - 1)));
|
||||
}
|
||||
for (int r = results.Count - 1; r > _Configuration.MaxItemsInDistanceCollection.Value; r--)
|
||||
results.RemoveAt(r);
|
||||
return results;
|
||||
}
|
||||
|
||||
private static string GetText(string fileNameWithoutExtension, List<List<D_Face>> faceCollections, List<int[]> locationIndicesCollection, List<double[]> indicesAndValues)
|
||||
{
|
||||
string result;
|
||||
D_Face face;
|
||||
int[] locationIndices;
|
||||
StringBuilder tvs = new();
|
||||
_ = tvs.Append("FileNameWithoutExtension").Append('\t').Append("LocationIndex").Append('\t').Append("FaceConfidence").Append('\t').Append("FaceDistance").Append('\t').Append("FactoredValue").AppendLine();
|
||||
for (int t = 0; t < indicesAndValues.Count; t++)
|
||||
{
|
||||
locationIndices = locationIndicesCollection[(int)indicesAndValues[t][0]];
|
||||
face = faceCollections[locationIndices[0]][locationIndices[1]];
|
||||
if (face.Populated && face.LocationIndex is not null && locationIndices[1] != face.LocationIndex)
|
||||
throw new Exception();
|
||||
_ = tvs.Append(fileNameWithoutExtension).Append('\t').Append(face.LocationIndex).Append('\t').Append(face.Location.Confidence).Append('\t').Append(indicesAndValues[t][1]).Append('\t').Append(indicesAndValues[t][2]).AppendLine();
|
||||
}
|
||||
result = tvs.ToString();
|
||||
return result;
|
||||
}
|
||||
|
||||
private void LoadOrCreateThenSaveDistanceResultsLoop(Property.Models.Configuration configuration, List<List<D_Face>> faceCollections, int subFilesCount, int i, List<D_Face> faceCollection, List<int[]> locationIndicesCollection, List<Tuple<string, DateTime>> subFileTuples, List<FaceEncoding> faceEncodingCollection, List<FaceEncoding> faceEncodingCollections, string fileNameWithoutExtension, string jsonDirectory, string tvsDirectory)
|
||||
{
|
||||
string text;
|
||||
string json;
|
||||
string jsonFile;
|
||||
List<Tuple<Shared.Models.Properties.IFace, string>> orderedFaceCollection;
|
||||
if (!Directory.Exists(jsonDirectory))
|
||||
_ = Directory.CreateDirectory(jsonDirectory);
|
||||
if (!Directory.Exists(tvsDirectory))
|
||||
_ = Directory.CreateDirectory(tvsDirectory);
|
||||
if (!faceEncodingCollections.Any())
|
||||
{
|
||||
int j = 0;
|
||||
orderedFaceCollection = GetOrderedNoFaceCollection(faceCollections, i, faceCollection[j]);
|
||||
json = JsonSerializer.Serialize(orderedFaceCollection, _WriteIndentedJsonSerializerOptions);
|
||||
jsonFile = Path.Combine(jsonDirectory, $"{j} - {fileNameWithoutExtension}.json");
|
||||
if (Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: true))
|
||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now));
|
||||
}
|
||||
else
|
||||
{
|
||||
string tvsFile;
|
||||
double[] faceDistances;
|
||||
List<double[]> indicesAndValues;
|
||||
for (int j = 0; j < faceEncodingCollections.Count; j++)
|
||||
{
|
||||
if (!faceCollection[j].Populated)
|
||||
continue;
|
||||
tvsFile = Path.Combine(tvsDirectory, $"{j} - {fileNameWithoutExtension}.tvs");
|
||||
jsonFile = Path.Combine(jsonDirectory, $"{j} - {fileNameWithoutExtension}.json");
|
||||
faceDistances = FaceRecognition.FaceDistances(faceEncodingCollection, faceEncodingCollections[j]).ToArray();
|
||||
indicesAndValues = GetValues(faceCollections, locationIndicesCollection, faceDistances);
|
||||
orderedFaceCollection = GetOrderedFaceCollection(faceCollections, locationIndicesCollection, indicesAndValues);
|
||||
text = GetText(fileNameWithoutExtension, faceCollections, locationIndicesCollection, indicesAndValues);
|
||||
if (Property.Models.Stateless.IPath.WriteAllText(tvsFile, text, compareBeforeWrite: true))
|
||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now));
|
||||
json = JsonSerializer.Serialize(orderedFaceCollection, _WriteIndentedJsonSerializerOptions);
|
||||
if (Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: true))
|
||||
subFileTuples.Add(new Tuple<string, DateTime>(nameof(E_Distance), DateTime.Now));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadOrCreateThenSaveDistanceResults(Property.Models.Configuration configuration, string[] subFiles, List<List<D_Face>> faceCollections, List<string[]> directories)
|
||||
{
|
||||
string fileNameWithoutExtension;
|
||||
List<int[]> locationIndicesCollection = new();
|
||||
List<Tuple<string, DateTime>> subFileTuples = new();
|
||||
List<FaceEncoding> faceEncodingCollection = new();
|
||||
List<List<FaceEncoding>> faceEncodingCollections = new();
|
||||
LoadFaceEncodingCollections(subFiles, faceCollections, locationIndicesCollection, faceEncodingCollection, faceEncodingCollections);
|
||||
if (faceEncodingCollections.Count != faceCollections.Count)
|
||||
throw new Exception();
|
||||
if (locationIndicesCollection.Count != faceEncodingCollection.Count)
|
||||
throw new Exception();
|
||||
for (int i = 0; i < subFiles.Length; i++)
|
||||
{
|
||||
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(subFiles[i]);
|
||||
LoadOrCreateThenSaveDistanceResultsLoop(configuration, faceCollections, subFiles.Length, i, faceCollections[i], locationIndicesCollection, subFileTuples, faceEncodingCollection, faceEncodingCollections[i], fileNameWithoutExtension, directories[i][0], directories[i][1]);
|
||||
}
|
||||
}
|
||||
|
||||
internal void LoadOrCreateThenSaveDistanceResults(Property.Models.Configuration configuration, string sourceDirectory, string outputResolution, List<Tuple<string, DateTime>> sourceDirectoryChanges, string[] subFiles, List<List<D_Face>> faceCollections)
|
||||
{
|
||||
if (_Configuration.CheckJsonForDistanceResults is null)
|
||||
throw new Exception();
|
||||
if (_Configuration.PropertiesChangedForDistance is null)
|
||||
throw new Exception();
|
||||
string json;
|
||||
bool check = false;
|
||||
string parentCheck;
|
||||
DirectoryInfo directoryInfo;
|
||||
DirectoryInfo tvsDirectoryInfo;
|
||||
string fileNameWithoutExtension;
|
||||
List<string[]> directories = new();
|
||||
string[] changesFrom = new string[] { nameof(A_Property), nameof(B_Metadata), nameof(C_Resize), nameof(D_Face) };
|
||||
List<DateTime> dateTimes = (from l in sourceDirectoryChanges where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
||||
List<string> directoryInfoCollection = Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration,
|
||||
sourceDirectory,
|
||||
nameof(E_Distance),
|
||||
outputResolution,
|
||||
includeResizeGroup: true,
|
||||
includeModel: true,
|
||||
includePredictorModel: true,
|
||||
contentDescription: ".tvs File",
|
||||
singletonDescription: string.Empty,
|
||||
collectionDescription: "n json file(s) for each face found (one to many)");
|
||||
for (int i = 0; i < subFiles.Length; i++)
|
||||
{
|
||||
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(subFiles[i]);
|
||||
directoryInfo = new DirectoryInfo(Path.Combine(directoryInfoCollection[0].Replace("<>", "[]"), fileNameWithoutExtension));
|
||||
if (!directoryInfo.Exists)
|
||||
{
|
||||
if (directoryInfo.Parent?.Parent is null)
|
||||
throw new Exception();
|
||||
parentCheck = Path.Combine(directoryInfo.Parent.Parent.FullName, directoryInfo.Name);
|
||||
if (Directory.Exists(parentCheck))
|
||||
{
|
||||
foreach (string file in Directory.GetFiles(parentCheck))
|
||||
File.Delete(file);
|
||||
Directory.Delete(parentCheck);
|
||||
}
|
||||
}
|
||||
tvsDirectoryInfo = new DirectoryInfo(Path.Combine(directoryInfoCollection[0].Replace("<>", "()"), fileNameWithoutExtension));
|
||||
directories.Add(new string[] { directoryInfo.FullName, tvsDirectoryInfo.FullName });
|
||||
if (_Configuration.CheckJsonForDistanceResults.Value && directoryInfo.Exists)
|
||||
{
|
||||
foreach (FileInfo fileInfo in directoryInfo.GetFiles("*.json", SearchOption.AllDirectories))
|
||||
{
|
||||
json = Shared.Models.Stateless.Methods.IIndex.GetJson(fileInfo.FullName, fileInfo);
|
||||
if (!_Configuration.PropertiesChangedForDistance.Value && Shared.Models.Stateless.Methods.IFace.GetFace(fileInfo.FullName) is null)
|
||||
check = true;
|
||||
}
|
||||
}
|
||||
if (check)
|
||||
continue;
|
||||
if (_Configuration.PropertiesChangedForDistance.Value)
|
||||
check = true;
|
||||
else if (!directoryInfo.Exists)
|
||||
check = true;
|
||||
else if (!tvsDirectoryInfo.Exists)
|
||||
check = true;
|
||||
else if (dateTimes.Any() && dateTimes.Max() > directoryInfo.LastWriteTime)
|
||||
check = true;
|
||||
}
|
||||
if (check)
|
||||
LoadOrCreateThenSaveDistanceResults(configuration, subFiles, faceCollections, directories);
|
||||
_ = Property.Models.Stateless.IPath.DeleteEmptyDirectories(directoryInfoCollection[0].Replace("<>", "()"));
|
||||
}
|
||||
|
||||
private List<(string, List<KeyValuePair<string, Shared.Models.Face[]>>)> GetFiles(Property.Models.Configuration configuration, string outputResolution)
|
||||
{
|
||||
string json;
|
||||
List<KeyValuePair<string, Shared.Models.Face[]>>? facesKeyValuePairCollection;
|
||||
List<(string, List<KeyValuePair<string, Shared.Models.Face[]>>)> results = new();
|
||||
string dFacesCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(D_Face), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[[]]");
|
||||
string[] dFacesCollectionFiles = Directory.GetFiles(dFacesCollectionDirectory, "*.json", SearchOption.TopDirectoryOnly);
|
||||
foreach (string dFacesCollectionFile in dFacesCollectionFiles)
|
||||
{
|
||||
json = File.ReadAllText(dFacesCollectionFile);
|
||||
facesKeyValuePairCollection = JsonSerializer.Deserialize<List<KeyValuePair<string, Shared.Models.Face[]>>>(json);
|
||||
if (facesKeyValuePairCollection is null)
|
||||
continue;
|
||||
results.Add(new(dFacesCollectionFile, facesKeyValuePairCollection));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<(string, List<Shared.Models.Face>, List<FaceEncoding>)> GetMatches(List<(string, List<KeyValuePair<string, Shared.Models.Face[]>>)> files)
|
||||
{
|
||||
List<(string, List<Shared.Models.Face>, List<FaceEncoding>)> results = new();
|
||||
List<Shared.Models.Face> faces;
|
||||
FaceEncoding faceEncoding;
|
||||
List<FaceEncoding> faceEncodings;
|
||||
foreach ((string, List<KeyValuePair<string, Shared.Models.Face[]>>) file in files)
|
||||
{
|
||||
faces = new();
|
||||
faceEncodings = new();
|
||||
foreach (KeyValuePair<string, Shared.Models.Face[]> keyValuePair in file.Item2)
|
||||
{
|
||||
foreach (Shared.Models.Face face in keyValuePair.Value)
|
||||
{
|
||||
if (!face.Populated)
|
||||
continue;
|
||||
faces.Add(face);
|
||||
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
||||
faceEncodings.Add(faceEncoding);
|
||||
}
|
||||
}
|
||||
results.Add(new(file.Item1, faces, faceEncodings));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static int GetIndex(double[] faceDistances)
|
||||
{
|
||||
int result;
|
||||
List<double[]> faceDistancesWithIndex = new();
|
||||
for (int y = 0; y < faceDistances.Length; y++)
|
||||
faceDistancesWithIndex.Add(new double[] { faceDistances[y], y });
|
||||
faceDistancesWithIndex = (from l in faceDistancesWithIndex orderby l[0] select l).ToList();
|
||||
result = (int)faceDistancesWithIndex[0][1];
|
||||
return result;
|
||||
}
|
||||
|
||||
private void Save(Property.Models.Configuration configuration, string outputResolution, string eDistanceCollectionDirectory, int k, string relativePath, Shared.Models.Face face, List<Tuple<Shared.Models.Face, string>> faceAndFaceDistanceCollection)
|
||||
{
|
||||
if (string.IsNullOrEmpty(eDistanceCollectionDirectory))
|
||||
eDistanceCollectionDirectory = Path.Combine(Property.Models.Stateless.IResult.GetResultsFullGroupDirectory(configuration, nameof(E_Distance), outputResolution, includeResizeGroup: true, includeModel: true, includePredictorModel: true), "[]");
|
||||
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(face.RelativePath);
|
||||
string jsonDirectory = string.Concat(eDistanceCollectionDirectory, Path.Combine(relativePath, fileNameWithoutExtension));
|
||||
if (!Directory.Exists(jsonDirectory))
|
||||
_ = Directory.CreateDirectory(jsonDirectory);
|
||||
string json = JsonSerializer.Serialize(faceAndFaceDistanceCollection, _WriteIndentedJsonSerializerOptions);
|
||||
string jsonFile = Path.Combine(jsonDirectory, $"{k} - {fileNameWithoutExtension}.nosj");
|
||||
_ = Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: true);
|
||||
}
|
||||
|
||||
private static Tuple<Shared.Models.Face, double> Get(FaceEncoding faceEncoding, (string, List<Shared.Models.Face>, List<FaceEncoding>) match)
|
||||
{
|
||||
Tuple<Shared.Models.Face, double> result;
|
||||
double[] faceDistances = FaceRecognition.FaceDistances(match.Item3, faceEncoding).ToArray();
|
||||
int index = GetIndex(faceDistances);
|
||||
result = new(match.Item2[index], faceDistances[index]);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void LoadOrCreateThenSaveDirectoryDistanceResults(Property.Models.Configuration configuration, string outputResolution)
|
||||
{
|
||||
if (_Log is null)
|
||||
throw new Exception($"{nameof(_Log)} is null!");
|
||||
string? relativePath;
|
||||
Shared.Models.Face face;
|
||||
ParallelOptions parallelOptions = new();
|
||||
FaceEncoding faceEncoding;
|
||||
string eDistanceCollectionDirectory = string.Empty;
|
||||
Tuple<Shared.Models.Face, double> faceAndFaceDistance;
|
||||
List<Tuple<Shared.Models.Face, string>> faceAndFaceDistanceCollection;
|
||||
List<(string, List<KeyValuePair<string, Shared.Models.Face[]>>)> files = GetFiles(configuration, outputResolution);
|
||||
List<(string, List<Shared.Models.Face>, List<FaceEncoding>)> matches = GetMatches(files);
|
||||
if (files.Count != matches.Count)
|
||||
throw new Exception();
|
||||
int filesCount = files.Count;
|
||||
for (int i = 0; i < filesCount; i++)
|
||||
{
|
||||
if (_Configuration.CrossDirectoryMaxItemsInDistanceCollection is null)
|
||||
continue;
|
||||
_Log.Debug(string.Concat("LoadOrCreateThenSaveDirectoryDistanceResults - ", nameof(outputResolution), ' ', outputResolution, " - ", i, " of ", filesCount));
|
||||
for (int j = 0; j < files[i].Item2.Count; j++)
|
||||
{
|
||||
if (!matches[i].Item2.Any())
|
||||
continue;
|
||||
for (int k = 0; k < files[i].Item2[j].Value.Length; k++)
|
||||
{
|
||||
if (!files[i].Item2[j].Value[k].Populated)
|
||||
continue;
|
||||
face = files[i].Item2[j].Value[k];
|
||||
faceAndFaceDistanceCollection = new(matches.Count);
|
||||
relativePath = Path.GetDirectoryName(face.RelativePath);
|
||||
if (string.IsNullOrEmpty(relativePath))
|
||||
continue;
|
||||
faceEncoding = FaceRecognition.LoadFaceEncoding(face.FaceEncoding.RawEncoding);
|
||||
_ = Parallel.For(0, matches.Count, parallelOptions, z =>
|
||||
{
|
||||
if (z != i && matches[z].Item2.Any())
|
||||
{
|
||||
faceAndFaceDistance = Get(faceEncoding, matches[z]);
|
||||
// if (faceAndFaceDistance.Item2 < _Configuration.)
|
||||
faceAndFaceDistanceCollection.Add(new(faceAndFaceDistance.Item1, faceAndFaceDistance.Item2.ToString("0.000")));
|
||||
}
|
||||
});
|
||||
if (faceAndFaceDistanceCollection.Any())
|
||||
{
|
||||
faceAndFaceDistanceCollection = (from l in faceAndFaceDistanceCollection orderby l.Item2 select l).Take(_Configuration.CrossDirectoryMaxItemsInDistanceCollection.Value).ToList();
|
||||
Save(configuration, outputResolution, eDistanceCollectionDirectory, k, relativePath, face, faceAndFaceDistanceCollection);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
90
Instance/Models/_F_Random.cs
Normal file
90
Instance/Models/_F_Random.cs
Normal file
@ -0,0 +1,90 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace View_by_Distance.Instance.Models;
|
||||
|
||||
/// <summary>
|
||||
// List<string>
|
||||
/// </summary>
|
||||
internal class F_Random
|
||||
{
|
||||
|
||||
private readonly Serilog.ILogger? _Log;
|
||||
private readonly Configuration _Configuration;
|
||||
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
|
||||
|
||||
internal F_Random(Configuration configuration)
|
||||
{
|
||||
_Configuration = configuration;
|
||||
_Log = Serilog.Log.ForContext<F_Random>();
|
||||
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = false };
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
return result;
|
||||
}
|
||||
|
||||
private bool IsIgnoreRelativePath(string directory)
|
||||
{
|
||||
bool result = false;
|
||||
if (_Configuration?.PropertyConfiguration is null)
|
||||
throw new Exception($"{nameof(_Configuration.PropertyConfiguration)} must be set!");
|
||||
string? checkDirectory = Path.GetFullPath(directory);
|
||||
for (int i = 0; i < int.MaxValue; i++)
|
||||
{
|
||||
if (_Configuration.IgnoreRelativePaths.Contains(Path.GetFileName(checkDirectory)))
|
||||
{
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
checkDirectory = Path.GetDirectoryName(checkDirectory);
|
||||
if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == _Configuration.PropertyConfiguration.RootDirectory)
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void Random(Property.Models.Configuration configuration, string outputResolution, List<KeyValuePair<string, string>> fileKeyValuePairs)
|
||||
{
|
||||
if (_Configuration.SaveFullYearOfRandomFiles is null)
|
||||
throw new Exception();
|
||||
string json;
|
||||
string jsonFile;
|
||||
Random random = new();
|
||||
List<string> relativePaths = new();
|
||||
List<string> ignoreRelativePaths = new();
|
||||
DateTime dateTime = new(2024, 1, 1); //Leap year
|
||||
string fRandomCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(F_Random), "[]");
|
||||
string[] files = Directory.GetFiles(fRandomCollectionDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
foreach (string file in files)
|
||||
File.Delete(file);
|
||||
foreach (KeyValuePair<string, string> keyValuePair in fileKeyValuePairs)
|
||||
{
|
||||
if (!(from l in _Configuration.IgnoreRelativePaths where keyValuePair.Key.Contains(l) && IsIgnoreRelativePath(keyValuePair.Key) select true).Any())
|
||||
relativePaths.Add(keyValuePair.Value);
|
||||
else
|
||||
ignoreRelativePaths.Add(keyValuePair.Value);
|
||||
}
|
||||
if (relativePaths.Any())
|
||||
{
|
||||
for (int i = 0; i < 366; i++)
|
||||
{
|
||||
relativePaths = (from l in relativePaths orderby random.NextDouble() select l).ToList();
|
||||
jsonFile = Path.Combine(fRandomCollectionDirectory, $"{dateTime.AddDays(i):MM-dd}.json");
|
||||
json = JsonSerializer.Serialize(relativePaths, _WriteIndentedJsonSerializerOptions);
|
||||
_ = Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: false);
|
||||
if (!_Configuration.SaveFullYearOfRandomFiles.Value)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ignoreRelativePaths.Any())
|
||||
{
|
||||
ignoreRelativePaths = (from l in ignoreRelativePaths orderby random.NextDouble() select l).ToList();
|
||||
jsonFile = Path.Combine(fRandomCollectionDirectory, "01-01.txt");
|
||||
json = JsonSerializer.Serialize(ignoreRelativePaths, _WriteIndentedJsonSerializerOptions);
|
||||
_ = Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
229
Instance/Models/_G2_Identify.cs
Normal file
229
Instance/Models/_G2_Identify.cs
Normal file
@ -0,0 +1,229 @@
|
||||
using Phares.Shared;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using View_by_Distance.Property.Models;
|
||||
using View_by_Distance.Shared.Models;
|
||||
using View_by_Distance.Shared.Models.Methods;
|
||||
|
||||
namespace View_by_Distance.Instance.Models;
|
||||
|
||||
/// <summary>
|
||||
// List<G2_Identify>
|
||||
/// </summary>
|
||||
public class G2_Identify : Shared.Models.Properties.IIdentify, IIdentify
|
||||
{
|
||||
|
||||
protected int _DirectoryCount;
|
||||
protected string _ParentDirectoryName;
|
||||
protected string _Person;
|
||||
protected string _PossibleYear;
|
||||
protected string _RelativePath;
|
||||
public int DirectoryCount => _DirectoryCount;
|
||||
public string ParentDirectoryName => _ParentDirectoryName;
|
||||
public string Person => _Person;
|
||||
public string PossibleYear => _PossibleYear;
|
||||
public string RelativePath => _RelativePath;
|
||||
|
||||
private readonly Serilog.ILogger? _Log;
|
||||
private readonly Configuration _Configuration;
|
||||
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
|
||||
|
||||
#nullable disable
|
||||
[JsonConstructor]
|
||||
public G2_Identify(int directoryCount, string parentDirectoryName, string person, string possibleYear, string relativePath)
|
||||
{
|
||||
_DirectoryCount = directoryCount;
|
||||
_ParentDirectoryName = parentDirectoryName;
|
||||
_Person = person;
|
||||
_PossibleYear = possibleYear;
|
||||
_RelativePath = relativePath;
|
||||
}
|
||||
|
||||
internal G2_Identify(Configuration configuration)
|
||||
{
|
||||
_DirectoryCount = 0;
|
||||
_ParentDirectoryName = string.Empty;
|
||||
_Person = string.Empty;
|
||||
_PossibleYear = string.Empty;
|
||||
_RelativePath = string.Empty;
|
||||
_Configuration = configuration;
|
||||
_Log = Serilog.Log.ForContext<G2_Identify>();
|
||||
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
return result;
|
||||
}
|
||||
|
||||
private FileInfo GetNamed()
|
||||
{
|
||||
FileInfo result;
|
||||
string[] jsonFiles = Directory.GetFiles(_Configuration.PropertyConfiguration.RootDirectory, "*Named*.json", SearchOption.TopDirectoryOnly);
|
||||
if (!jsonFiles.Any())
|
||||
result = null;
|
||||
else
|
||||
result = new FileInfo(jsonFiles[0]);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void CheckLastWriteTimes(Property.Models.Configuration configuration, IsEnvironment isEnvironment, A2_People a2People, FileInfo named, string g2IdentifySingletonDirectory)
|
||||
{
|
||||
string json;
|
||||
FileInfo fileInfo;
|
||||
DateTime dateTime = DateTime.MinValue;
|
||||
string[] jsonFiles = Directory.GetFiles(g2IdentifySingletonDirectory, "*.json", SearchOption.AllDirectories);
|
||||
foreach (string jsonFile in jsonFiles)
|
||||
{
|
||||
fileInfo = new(jsonFile);
|
||||
if (dateTime < fileInfo.LastWriteTime)
|
||||
dateTime = fileInfo.LastWriteTime;
|
||||
}
|
||||
if (named.LastWriteTime > dateTime)
|
||||
{
|
||||
if (!isEnvironment.DebuggerWasAttachedDuringConstructor)
|
||||
throw new Exception("Only allowed when debugger is attached during constructor!");
|
||||
foreach (string file in jsonFiles)
|
||||
File.Delete(file);
|
||||
}
|
||||
json = File.ReadAllText(named.FullName);
|
||||
Person[] people = a2People.GetPeople(configuration);
|
||||
Dictionary<string, string[]> resultKeyValuePairs = new();
|
||||
string[] peopleBirthdates = (from l in people select Shared.Models.Stateless.Methods.IPersonBirthday.GetFormated(l.Birthday)).ToArray();
|
||||
Dictionary<string, string[]> sourceKeyValuePairs = JsonSerializer.Deserialize<Dictionary<string, string[]>>(json);
|
||||
foreach (KeyValuePair<string, string[]> keyValuePair in sourceKeyValuePairs)
|
||||
{
|
||||
if (!(from l in keyValuePair.Value where peopleBirthdates.Contains(l) select false).Any())
|
||||
continue;
|
||||
resultKeyValuePairs.Add(keyValuePair.Key, keyValuePair.Value);
|
||||
}
|
||||
if (resultKeyValuePairs.Count != sourceKeyValuePairs.Count)
|
||||
{
|
||||
json = JsonSerializer.Serialize(resultKeyValuePairs, _WriteIndentedJsonSerializerOptions);
|
||||
if (!isEnvironment.DebuggerWasAttachedDuringConstructor)
|
||||
throw new Exception("Only allowed when debugger is attached during constructor!");
|
||||
_ = Property.Models.Stateless.IPath.WriteAllText(named.FullName, json, compareBeforeWrite: true);
|
||||
}
|
||||
}
|
||||
|
||||
internal List<G2_Identify> GetIdentifiedCollection(Property.Models.Configuration configuration, IsEnvironment isEnvironment, A2_People a2People)
|
||||
{
|
||||
List<G2_Identify> results = new();
|
||||
string json;
|
||||
string[] people;
|
||||
string[] jsonFiles;
|
||||
int directoryCount;
|
||||
string possibleYear;
|
||||
G2_Identify identify;
|
||||
FileInfo named = GetNamed();
|
||||
string testDirectoryFullName;
|
||||
string checkDirectoryFullName;
|
||||
Dictionary<int, string[]> keyValuePairs;
|
||||
List<string> missing = new();
|
||||
List<G_Index> indices = new();
|
||||
string directoryName = Path.GetFileName(_Configuration.PropertyConfiguration.RootDirectory);
|
||||
string g2IdentifySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(G2_Identify), "[]");
|
||||
string jsonRootDirectory = Path.Combine(string.Concat(_Configuration.PropertyConfiguration.RootDirectory, " - Copied"), string.Concat(directoryName, " - 4) Info"), _Configuration.PropertyConfiguration.DateGroup, "[]");
|
||||
if (named is not null && named.Exists)
|
||||
CheckLastWriteTimes(configuration, isEnvironment, a2People, named, g2IdentifySingletonDirectory);
|
||||
if (Directory.Exists(jsonRootDirectory))
|
||||
{
|
||||
jsonFiles = Directory.GetFiles(jsonRootDirectory, "*.json", SearchOption.AllDirectories);
|
||||
for (int i = 0; i < jsonFiles.Length; i++)
|
||||
{
|
||||
json = Shared.Models.Stateless.Methods.IIndex.GetJson(jsonFiles[i], fileInfo: null);
|
||||
indices.AddRange(JsonSerializer.Deserialize<List<G_Index>>(json));
|
||||
}
|
||||
if (named is not null && named.Exists)
|
||||
{
|
||||
json = File.ReadAllText(named.FullName);
|
||||
keyValuePairs = JsonSerializer.Deserialize<Dictionary<int, string[]>>(json);
|
||||
foreach (G_Index index in indices)
|
||||
{
|
||||
if (index?.Index is null)
|
||||
continue;
|
||||
if (!keyValuePairs.ContainsKey(index.Index.Value))
|
||||
{
|
||||
missing.Add(index.Index.Value.ToString());
|
||||
continue;
|
||||
}
|
||||
if (index.RelativePaths is null)
|
||||
{
|
||||
missing.Add(index.Index.Value.ToString());
|
||||
continue;
|
||||
}
|
||||
people = keyValuePairs[index.Index.Value];
|
||||
foreach (string relativePath in index.RelativePaths)
|
||||
{
|
||||
foreach (string person in people)
|
||||
{
|
||||
directoryCount = 0;
|
||||
checkDirectoryFullName = string.Concat(_Configuration.PropertyConfiguration.RootDirectory, relativePath);
|
||||
for (int i = 0; i < int.MaxValue; i++)
|
||||
{
|
||||
testDirectoryFullName = Path.GetDirectoryName(checkDirectoryFullName);
|
||||
if (testDirectoryFullName == _Configuration.PropertyConfiguration.RootDirectory)
|
||||
break;
|
||||
directoryCount += 1;
|
||||
checkDirectoryFullName = testDirectoryFullName;
|
||||
}
|
||||
possibleYear = checkDirectoryFullName.Split(' ').Last();
|
||||
if (possibleYear.Length != 4)
|
||||
possibleYear = "0000";
|
||||
identify = new G2_Identify(directoryCount, Path.GetFileName(checkDirectoryFullName), person, possibleYear, relativePath);
|
||||
results.Add(identify);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
results = (from l in results orderby l.PossibleYear descending, l.DirectoryCount, l.ParentDirectoryName, l.RelativePath select l).ToList();
|
||||
return results;
|
||||
}
|
||||
|
||||
internal void WriteAllText(Property.Models.Configuration configuration, string outputResolution, List<G2_Identify> identifiedCollection)
|
||||
{
|
||||
string key;
|
||||
string json;
|
||||
string jsonFile;
|
||||
string directoryFullName;
|
||||
string fileNameWithoutExtension;
|
||||
string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(A_Property), "{}");
|
||||
string g2IdentifyCollectionDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(configuration, nameof(G2_Identify), "[]");
|
||||
Dictionary<string, List<KeyValuePair<string, string>>> keyValuePairs = new();
|
||||
foreach (G2_Identify identified in identifiedCollection)
|
||||
{
|
||||
key = Path.GetDirectoryName(identified.RelativePath);
|
||||
if (!keyValuePairs.ContainsKey(key))
|
||||
keyValuePairs.Add(key, new List<KeyValuePair<string, string>>());
|
||||
keyValuePairs[key].Add(new KeyValuePair<string, string>(identified.RelativePath, identified.Person));
|
||||
}
|
||||
foreach (KeyValuePair<string, List<KeyValuePair<string, string>>> keyValuePair in keyValuePairs)
|
||||
{
|
||||
directoryFullName = string.Concat(aPropertySingletonDirectory, keyValuePair.Key);
|
||||
if (!Directory.Exists(directoryFullName))
|
||||
continue;
|
||||
foreach (KeyValuePair<string, string> keyValue in keyValuePair.Value)
|
||||
{
|
||||
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(keyValue.Key);
|
||||
jsonFile = Path.Combine(directoryFullName, $"{fileNameWithoutExtension}.json");
|
||||
if (!File.Exists(jsonFile))
|
||||
{
|
||||
directoryFullName = string.Empty;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (string.IsNullOrEmpty(directoryFullName))
|
||||
continue;
|
||||
directoryFullName = Path.GetDirectoryName(string.Concat(g2IdentifyCollectionDirectory, keyValuePair.Key));
|
||||
if (!Directory.Exists(directoryFullName))
|
||||
_ = Directory.CreateDirectory(directoryFullName);
|
||||
jsonFile = string.Concat(g2IdentifyCollectionDirectory, keyValuePair.Key, ".json");
|
||||
json = JsonSerializer.Serialize(keyValuePair.Value, _WriteIndentedJsonSerializerOptions);
|
||||
if (!Property.Models.Stateless.IPath.WriteAllText(jsonFile, json, compareBeforeWrite: true))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
213
Instance/Models/_G_Index.cs
Normal file
213
Instance/Models/_G_Index.cs
Normal file
@ -0,0 +1,213 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using View_by_Distance.Property.Models;
|
||||
using View_by_Distance.Shared.Models.Methods;
|
||||
|
||||
namespace View_by_Distance.Instance.Models;
|
||||
|
||||
/// <summary>
|
||||
// G_Index && G_Index[]
|
||||
/// </summary>
|
||||
public class G_Index : Shared.Models.Properties.IIndex, IIndex
|
||||
{
|
||||
|
||||
private readonly Serilog.ILogger? _Log;
|
||||
private readonly Configuration _Configuration;
|
||||
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
|
||||
|
||||
protected DateTime? _DateTime;
|
||||
protected int? _Index;
|
||||
protected List<string> _RelativePaths;
|
||||
public DateTime? DateTime => _DateTime;
|
||||
public int? Index => _Index;
|
||||
public List<string> RelativePaths => _RelativePaths;
|
||||
|
||||
#nullable disable
|
||||
[JsonConstructor]
|
||||
public G_Index(DateTime? dateTime, int? index, List<string> relativePaths)
|
||||
{
|
||||
_DateTime = dateTime;
|
||||
_Index = index;
|
||||
_RelativePaths = relativePaths;
|
||||
}
|
||||
|
||||
internal G_Index()
|
||||
{
|
||||
_DateTime = null;
|
||||
_Index = null;
|
||||
_RelativePaths = new();
|
||||
}
|
||||
|
||||
internal G_Index(Configuration configuration)
|
||||
{
|
||||
_Configuration = configuration;
|
||||
_Log = Serilog.Log.ForContext<G_Index>();
|
||||
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||
return result;
|
||||
}
|
||||
|
||||
private G_Index GetIndexInfo(FileInfo fileInfo, List<string> parseExceptions)
|
||||
{
|
||||
G_Index result;
|
||||
List<int> indices = new();
|
||||
string json = File.ReadAllText(fileInfo.FullName);
|
||||
try
|
||||
{
|
||||
result = JsonSerializer.Deserialize<G_Index>(json);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
result = null;
|
||||
parseExceptions.Add(nameof(G_Index));
|
||||
}
|
||||
if (_Configuration.MappedMaxIndex.HasValue && result.Index.HasValue && _Configuration.MappedMaxIndex.Value < result.Index.Value)
|
||||
{
|
||||
result = null;
|
||||
File.Delete(fileInfo.FullName);
|
||||
}
|
||||
else if (result.Index is null)
|
||||
result = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
private void WriteNeeded(List<int> indices, List<Tuple<List<string>, string, A_Property>> neededTuples)
|
||||
{
|
||||
string json;
|
||||
DateTime dateTime;
|
||||
A_Property property;
|
||||
G_Index indexInfo;
|
||||
int maxIndexPlusOne;
|
||||
DateTime?[] dateTimes;
|
||||
if (indices.Any())
|
||||
maxIndexPlusOne = indices.Max() + 1;
|
||||
else
|
||||
{
|
||||
maxIndexPlusOne = 1000000;
|
||||
throw new Exception("Are you sure exception. Use debugger to step over.");
|
||||
}
|
||||
foreach (Tuple<List<string>, string, A_Property> tuple in neededTuples)
|
||||
{
|
||||
maxIndexPlusOne += 1;
|
||||
property = tuple.Item3;
|
||||
dateTimes = new DateTime?[] { property.CreationTime, property.LastWriteTime, property.DateTime, property.DateTimeDigitized, property.DateTimeOriginal, property.GPSDateStamp };
|
||||
dateTime = (from l in dateTimes where l.HasValue select l.Value).Min();
|
||||
indexInfo = new(dateTime, maxIndexPlusOne, tuple.Item1);
|
||||
json = JsonSerializer.Serialize(indexInfo, _WriteIndentedJsonSerializerOptions);
|
||||
if (!Property.Models.Stateless.IPath.WriteAllText(tuple.Item2, json, compareBeforeWrite: true))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteGroup(Property.Models.Configuration configuration, string outputResolution, List<Tuple<string, Dictionary<int, G_Index>>> indexInfoTuples)
|
||||
{
|
||||
string json;
|
||||
G_Index[] indices;
|
||||
List<string> directoryInfoCollection;
|
||||
foreach (Tuple<string, Dictionary<int, G_Index>> tuple in indexInfoTuples)
|
||||
{
|
||||
indices = (from l in tuple.Item2 select l.Value).ToArray();
|
||||
directoryInfoCollection = Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, tuple.Item1, nameof(G_Index), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false, contentDescription: string.Empty, singletonDescription: string.Empty, collectionDescription: "Unknown A");
|
||||
json = JsonSerializer.Serialize(indices, _WriteIndentedJsonSerializerOptions);
|
||||
if (!Property.Models.Stateless.IPath.WriteAllText(string.Concat(directoryInfoCollection[0].Replace("<>", "[]"), ".json"), json, compareBeforeWrite: true))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
private void AppendTSV(Property.Models.Configuration configuration, string outputResolution, Dictionary<string, List<Tuple<string, A_Property>>> filePropertiesKeyValuePairs)
|
||||
{
|
||||
A_Property property;
|
||||
DateTime?[] dateTimes;
|
||||
DateTime? maximumDateTime;
|
||||
DateTime? minimumDateTime;
|
||||
List<string> directoryInfoCollection;
|
||||
long ticks = System.DateTime.Now.Ticks;
|
||||
foreach (KeyValuePair<string, List<Tuple<string, A_Property>>> tuples in filePropertiesKeyValuePairs)
|
||||
{
|
||||
maximumDateTime = null;
|
||||
minimumDateTime = null;
|
||||
foreach (Tuple<string, A_Property> tuple in tuples.Value)
|
||||
{
|
||||
property = tuple.Item2;
|
||||
dateTimes = new DateTime?[] { maximumDateTime, minimumDateTime, property.CreationTime, property.LastWriteTime, property.DateTime, property.DateTimeDigitized, property.DateTimeOriginal, property.GPSDateStamp };
|
||||
maximumDateTime = (from l in dateTimes where l.HasValue select l.Value).Max();
|
||||
minimumDateTime = (from l in dateTimes where l.HasValue select l.Value).Min();
|
||||
}
|
||||
directoryInfoCollection = Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, tuples.Key, nameof(G_Index), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false, contentDescription: string.Empty, singletonDescription: "Unkown B", collectionDescription: string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetIndex(Property.Models.Configuration configuration, string outputResolution, Dictionary<string, List<Tuple<string, A_Property>>> filePropertiesKeyValuePairs)
|
||||
{
|
||||
if (_Configuration.PropertiesChangedForIndex is null)
|
||||
throw new Exception();
|
||||
FileInfo fileInfo;
|
||||
G_Index indexInfo;
|
||||
string parentCheck;
|
||||
List<int> indices = new();
|
||||
Dictionary<int, G_Index> valuePairs;
|
||||
List<string> directoryInfoCollection;
|
||||
List<string> parseExceptions = new();
|
||||
List<Tuple<List<string>, string, A_Property>> neededTuples = new();
|
||||
List<Tuple<string, Dictionary<int, G_Index>>> indexInfoTuples = new();
|
||||
for (short i = 0; i < short.MaxValue; i++)
|
||||
{
|
||||
if (i != 0)
|
||||
{
|
||||
if (!neededTuples.Any() && !parseExceptions.Any())
|
||||
break;
|
||||
indices.Clear();
|
||||
indexInfoTuples.Clear();
|
||||
parseExceptions.Clear();
|
||||
}
|
||||
neededTuples.Clear();
|
||||
foreach (KeyValuePair<string, List<Tuple<string, A_Property>>> tuples in filePropertiesKeyValuePairs)
|
||||
{
|
||||
valuePairs = new Dictionary<int, G_Index>();
|
||||
directoryInfoCollection = Property.Models.Stateless.IResult.GetDirectoryInfoCollection(configuration, tuples.Key, nameof(G_Index), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false, contentDescription: string.Empty, singletonDescription: "Unknown C", collectionDescription: string.Empty);
|
||||
foreach (Tuple<string, A_Property> tuple in tuples.Value)
|
||||
{
|
||||
fileInfo = new FileInfo(Path.Combine(directoryInfoCollection[0].Replace("<>", "{}"), string.Concat(Path.GetFileNameWithoutExtension(tuple.Item1), ".json")));
|
||||
if (!fileInfo.Exists)
|
||||
{
|
||||
if (fileInfo.Directory?.Parent is null)
|
||||
throw new Exception();
|
||||
parentCheck = Path.Combine(fileInfo.Directory.Parent.FullName, fileInfo.Name);
|
||||
if (File.Exists(parentCheck))
|
||||
File.Delete(parentCheck);
|
||||
}
|
||||
if (_Configuration.PropertiesChangedForIndex.Value)
|
||||
indexInfo = null;
|
||||
else if (!fileInfo.Exists)
|
||||
indexInfo = null;
|
||||
else
|
||||
indexInfo = GetIndexInfo(fileInfo, parseExceptions);
|
||||
if (indexInfo?.Index is not null)
|
||||
{
|
||||
indices.Add(indexInfo.Index.Value);
|
||||
valuePairs.Add(indexInfo.Index.Value, indexInfo);
|
||||
}
|
||||
else
|
||||
neededTuples.Add(new Tuple<List<string>, string, A_Property>(new List<string> { tuple.Item1 }, fileInfo.FullName, tuple.Item2));
|
||||
}
|
||||
indexInfoTuples.Add(new Tuple<string, Dictionary<int, G_Index>>(tuples.Key, valuePairs));
|
||||
}
|
||||
if (_Configuration.MappedMaxIndex.HasValue)
|
||||
break;
|
||||
WriteNeeded(indices, neededTuples);
|
||||
}
|
||||
if (parseExceptions.Any())
|
||||
throw new Exception(string.Join(Environment.NewLine, parseExceptions));
|
||||
if (neededTuples.Any())
|
||||
throw new Exception();
|
||||
WriteGroup(configuration, outputResolution, indexInfoTuples);
|
||||
AppendTSV(configuration, outputResolution, filePropertiesKeyValuePairs);
|
||||
}
|
||||
|
||||
string Shared.Models.Stateless.Methods.IIndex.TestStatic_GetJson(string jsonFileFullName, FileInfo fileInfo) => throw new NotImplementedException();
|
||||
|
||||
}
|
Reference in New Issue
Block a user