Filter same id
RelationLogic LookForAbandoned
This commit is contained in:
parent
331d98793e
commit
4b8b942528
@ -12,13 +12,7 @@ namespace View_by_Distance.Distance.Models;
|
|||||||
public partial class E_Distance : IDistance<MetadataExtractor.Directory>
|
public partial class E_Distance : IDistance<MetadataExtractor.Directory>
|
||||||
{
|
{
|
||||||
|
|
||||||
internal record Mapped(string File,
|
internal record Record(string File, FaceRecognitionDotNet.FaceEncoding FaceRecognitionDotNetFaceEncoding);
|
||||||
double? Length,
|
|
||||||
string Link,
|
|
||||||
string Image);
|
|
||||||
|
|
||||||
internal record Record(string File,
|
|
||||||
FaceRecognitionDotNet.FaceEncoding FaceRecognitionDotNetFaceEncoding);
|
|
||||||
|
|
||||||
private readonly List<string> _Moved;
|
private readonly List<string> _Moved;
|
||||||
private readonly List<double?> _Debug;
|
private readonly List<double?> _Debug;
|
||||||
@ -446,10 +440,10 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
|
|||||||
continue;
|
continue;
|
||||||
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.InSkipCollection is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPre.InSkipCollection.Value)
|
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.InSkipCollection is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPre.InSkipCollection.Value)
|
||||||
throw new NotSupportedException(nameof(PreFilterSetFaceDistances));
|
throw new NotSupportedException(nameof(PreFilterSetFaceDistances));
|
||||||
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusModel is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusModel.Value)
|
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusModel is not null && !faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusModel.Value)
|
||||||
throw new NotSupportedException(nameof(PreFilterSetFaceDistances));
|
continue;
|
||||||
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
|
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && !faceDistanceContainer.Face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
|
||||||
throw new NotSupportedException(nameof(PreFilterSetFaceDistances));
|
continue;
|
||||||
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPost.InSkipCollection is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPost.InSkipCollection.Value)
|
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPost.InSkipCollection is not null && faceDistanceContainer.Face.Mapping.MappingFromFilterPost.InSkipCollection.Value)
|
||||||
continue;
|
continue;
|
||||||
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPost.IsFocusPerson is not null && !faceDistanceContainer.Face.Mapping.MappingFromFilterPost.IsFocusPerson.Value)
|
if (faceDistanceContainer.Face.Mapping.MappingFromFilterPost.IsFocusPerson is not null && !faceDistanceContainer.Face.Mapping.MappingFromFilterPost.IsFocusPerson.Value)
|
||||||
@ -489,122 +483,27 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
|
|||||||
return new(results);
|
return new(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteVsCodeFiles(string eDistanceContentDirectory, string? displayDirectoryName, string directory)
|
private static ReadOnlyCollection<RelationContainer> GetRelationCollections(int faceDistancePermyriad, int locationContainerDistanceTake, float distanceTolerance, List<Record> records)
|
||||||
{
|
{
|
||||||
string json;
|
List<RelationContainer> results = new();
|
||||||
string vsCodeDirectory = Path.Combine(directory, ".vscode");
|
|
||||||
if (!Directory.Exists(vsCodeDirectory))
|
|
||||||
_ = Directory.CreateDirectory(vsCodeDirectory);
|
|
||||||
if (displayDirectoryName is not null)
|
|
||||||
File.WriteAllText(Path.Combine(directory, $"_ {displayDirectoryName}.txt"), string.Empty);
|
|
||||||
json = "{ \"[markdown]\": { \"editor.wordWrap\": \"off\" }, \"foam.links.hover.enable\": false, \"foam.graph.style\": { \"background\": \"#202020\", \"node\": { \"note\": \"#f2cb1d\", \"distance\": \"green\", \"image\": \"orange\", \"placeholder\": \"white\", } } }";
|
|
||||||
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(vsCodeDirectory, "settings.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
|
|
||||||
json = string.Concat("{ \"version\": \"2.0.0\", \"tasks\": [ { \"label\": \"MKLink\", \"type\": \"shell\", \"command\": \"New-Item\", \"args\": [ \"-ItemType\", \"Junction\", \"-Path\", \"'", directory.Replace('\\', '/'), "/()'\", \"-Target\", \"'", eDistanceContentDirectory.Replace('\\', '/'), "'\" ], \"problemMatcher\": [] } ] }");
|
|
||||||
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(vsCodeDirectory, "tasks.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void MoveFiles(string locationContainerDebugDirectory, bool isCounterPersonYear, string? displayDirectoryName, Dictionary<string, int> keyValuePairs, List<string> linkedOnce, List<string> linkedTwice, List<string> linkedThrice, List<string> linkedFour, List<string> linkedFive)
|
|
||||||
{
|
|
||||||
string checkFile;
|
|
||||||
string debugFile;
|
|
||||||
string checkDirectory;
|
|
||||||
string? yearDirectory;
|
|
||||||
string? personNameDirectory;
|
|
||||||
string? maybeTicksDirectoryName;
|
|
||||||
string? personNameDirectoryName;
|
|
||||||
string? personKeyFormattedDirectory;
|
|
||||||
foreach (string file in linkedOnce)
|
|
||||||
keyValuePairs[file] += 1;
|
|
||||||
foreach (string file in linkedTwice)
|
|
||||||
keyValuePairs[file] += 1;
|
|
||||||
foreach (string file in linkedThrice)
|
|
||||||
keyValuePairs[file] += 1;
|
|
||||||
foreach (string file in linkedFour)
|
|
||||||
keyValuePairs[file] += 1;
|
|
||||||
foreach (string file in linkedFive)
|
|
||||||
keyValuePairs[file] += 1;
|
|
||||||
foreach (KeyValuePair<string, int> keyValuePair in keyValuePairs)
|
|
||||||
{
|
|
||||||
personNameDirectory = Path.GetDirectoryName(keyValuePair.Key);
|
|
||||||
yearDirectory = Path.GetDirectoryName(personNameDirectory);
|
|
||||||
personNameDirectoryName = Path.GetFileName(personNameDirectory);
|
|
||||||
personKeyFormattedDirectory = Path.GetDirectoryName(yearDirectory);
|
|
||||||
maybeTicksDirectoryName = Path.GetFileName(personKeyFormattedDirectory);
|
|
||||||
if (string.IsNullOrEmpty(personNameDirectory) || string.IsNullOrEmpty(yearDirectory) || string.IsNullOrEmpty(personKeyFormattedDirectory) || string.IsNullOrEmpty(personNameDirectoryName))
|
|
||||||
continue;
|
|
||||||
if (maybeTicksDirectoryName == locationContainerDebugDirectory)
|
|
||||||
checkDirectory = Path.Combine(yearDirectory, $"{keyValuePair.Value}{new string(Convert.ToChar(65 + keyValuePair.Value), 7)}");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(locationContainerDebugDirectory))
|
|
||||||
continue;
|
|
||||||
checkDirectory = Path.Combine(personKeyFormattedDirectory, $"{keyValuePair.Value}{new string(Convert.ToChar(65 + keyValuePair.Value), 7)}");
|
|
||||||
}
|
|
||||||
if (maybeTicksDirectoryName != locationContainerDebugDirectory)
|
|
||||||
{
|
|
||||||
if (isCounterPersonYear || string.IsNullOrEmpty(displayDirectoryName))
|
|
||||||
checkDirectory = Path.Combine(checkDirectory, personNameDirectoryName);
|
|
||||||
else
|
|
||||||
checkDirectory = Path.Combine(checkDirectory, displayDirectoryName[0].ToString());
|
|
||||||
}
|
|
||||||
if (checkDirectory == personNameDirectory)
|
|
||||||
continue;
|
|
||||||
if (!Directory.Exists(checkDirectory))
|
|
||||||
_ = Directory.CreateDirectory(checkDirectory);
|
|
||||||
checkFile = Path.Combine(checkDirectory, Path.GetFileName(keyValuePair.Key));
|
|
||||||
if (File.Exists(checkFile))
|
|
||||||
continue;
|
|
||||||
File.Move(keyValuePair.Key, checkFile);
|
|
||||||
debugFile = $"{keyValuePair.Key[..^4]}.gif";
|
|
||||||
if (File.Exists(debugFile))
|
|
||||||
{
|
|
||||||
checkFile = Path.Combine(checkDirectory, $"{Path.GetFileName(keyValuePair.Key)[..^4]}.gif");
|
|
||||||
if (File.Exists(checkFile))
|
|
||||||
continue;
|
|
||||||
File.Move(debugFile, checkFile);
|
|
||||||
}
|
|
||||||
if (maybeTicksDirectoryName == locationContainerDebugDirectory && !string.IsNullOrEmpty(displayDirectoryName))
|
|
||||||
{
|
|
||||||
checkDirectory = Path.Combine(checkDirectory, displayDirectoryName);
|
|
||||||
if (!Directory.Exists(checkDirectory))
|
|
||||||
_ = Directory.CreateDirectory(checkDirectory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void SaveMappedForOutputResolutions(string locationContainerDebugDirectory, string eDistanceContentDirectory, float distanceTolerance, long personKey, bool isCounterPersonYear, string personKeyFormatted, string? displayDirectoryName, List<Record> records, string directory)
|
|
||||||
{
|
|
||||||
int years;
|
|
||||||
string text;
|
|
||||||
string fileName;
|
string fileName;
|
||||||
FileInfo fileInfo;
|
FileHolder fileHolder;
|
||||||
|
int distancePermyriad;
|
||||||
List<string> files = new();
|
List<string> files = new();
|
||||||
List<string> lines = new();
|
|
||||||
List<Mapped> results = new();
|
|
||||||
List<string> linkedFive = new();
|
|
||||||
List<string> linkedFour = new();
|
|
||||||
List<string> linkedOnce = new();
|
|
||||||
long ticks = DateTime.Now.Ticks;
|
long ticks = DateTime.Now.Ticks;
|
||||||
string fileNameWithoutExtension;
|
|
||||||
List<string> linkedTwice = new();
|
|
||||||
List<string> linkedThrice = new();
|
|
||||||
FaceDistance? faceDistanceEncoding;
|
FaceDistance? faceDistanceEncoding;
|
||||||
List<string> relativePaths = new();
|
List<Relation> mappedRelations;
|
||||||
List<FaceDistance> faceDistanceLengths;
|
List<FaceDistance> faceDistanceLengths;
|
||||||
Uri uri = new(eDistanceContentDirectory);
|
|
||||||
Dictionary<string, int> keyValuePairs = new();
|
|
||||||
List<FaceDistance> faceDistanceEncodings = new();
|
List<FaceDistance> faceDistanceEncodings = new();
|
||||||
foreach (Record record in records)
|
foreach (Record record in records)
|
||||||
{
|
{
|
||||||
files.Add(record.File);
|
files.Add(record.File);
|
||||||
relativePaths.Add(uri.MakeRelativeUri(new(record.File)).OriginalString);
|
|
||||||
faceDistanceEncodings.Add(new(record.FaceRecognitionDotNetFaceEncoding));
|
faceDistanceEncodings.Add(new(record.FaceRecognitionDotNetFaceEncoding));
|
||||||
}
|
}
|
||||||
foreach (Record record in records)
|
foreach (Record record in records)
|
||||||
{
|
{
|
||||||
lines.Clear();
|
mappedRelations = new();
|
||||||
results.Clear();
|
fileHolder = new(record.File);
|
||||||
fileInfo = new(record.File);
|
|
||||||
if (files.Count > 1)
|
if (files.Count > 1)
|
||||||
{
|
{
|
||||||
faceDistanceEncoding = new(record.FaceRecognitionDotNetFaceEncoding);
|
faceDistanceEncoding = new(record.FaceRecognitionDotNetFaceEncoding);
|
||||||
@ -613,77 +512,25 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
|
|||||||
faceDistanceLengths = FaceRecognition.FaceDistances(new(faceDistanceEncodings), faceDistanceEncoding);
|
faceDistanceLengths = FaceRecognition.FaceDistances(new(faceDistanceEncodings), faceDistanceEncoding);
|
||||||
for (int i = 0; i < faceDistanceLengths.Count; i++)
|
for (int i = 0; i < faceDistanceLengths.Count; i++)
|
||||||
{
|
{
|
||||||
fileName = Path.GetFileName(relativePaths[i]);
|
fileName = Path.GetFileName(files[i]);
|
||||||
if (fileName == fileInfo.Name)
|
if (fileName == fileHolder.Name)
|
||||||
continue;
|
continue;
|
||||||
FaceDistance faceDistance = faceDistanceLengths[i];
|
FaceDistance faceDistance = faceDistanceLengths[i];
|
||||||
if (faceDistance.Length > distanceTolerance)
|
if (faceDistance.Length is null || faceDistance.Length.Value > distanceTolerance)
|
||||||
continue;
|
continue;
|
||||||
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(fileName));
|
distancePermyriad = (int)(faceDistance.Length.Value * faceDistancePermyriad);
|
||||||
results.Add(new(files[i], faceDistance.Length, $"[[{fileNameWithoutExtension}]]", $""));
|
mappedRelations.Add(new(distancePermyriad, files[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
results = (from l in results orderby l.Length select l).Take(3).ToList();
|
mappedRelations = (from l in mappedRelations orderby l.DistancePermyriad select l).Take(locationContainerDistanceTake).ToList();
|
||||||
keyValuePairs.Add(record.File, results.Count);
|
results.Add(new(fileHolder, new(mappedRelations)));
|
||||||
foreach (Mapped mapped in results)
|
|
||||||
{
|
|
||||||
if (!linkedOnce.Contains(mapped.File))
|
|
||||||
{
|
|
||||||
linkedOnce.Add(mapped.File);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if (!linkedTwice.Contains(mapped.File))
|
return new(results);
|
||||||
{
|
|
||||||
linkedTwice.Add(mapped.File);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!linkedThrice.Contains(mapped.File))
|
|
||||||
{
|
|
||||||
linkedThrice.Add(mapped.File);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!linkedFour.Contains(mapped.File))
|
|
||||||
{
|
|
||||||
linkedFour.Add(mapped.File);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!linkedFive.Contains(mapped.File))
|
|
||||||
{
|
|
||||||
linkedFive.Add(mapped.File);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isCounterPersonYear)
|
|
||||||
(years, _) = Shared.Models.Stateless.Methods.IAge.GetAge(ticks, fileInfo.CreationTime.Ticks);
|
|
||||||
else
|
|
||||||
(years, _) = Shared.Models.Stateless.Methods.IAge.GetAge(fileInfo.CreationTime.Ticks, personKey);
|
|
||||||
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(fileInfo.Name));
|
|
||||||
lines.Add("---");
|
|
||||||
lines.Add("type: \"distance\"");
|
|
||||||
lines.Add("---");
|
|
||||||
lines.Add(string.Empty);
|
|
||||||
if (displayDirectoryName is null)
|
|
||||||
lines.Add($"## {personKeyFormatted}");
|
|
||||||
else
|
|
||||||
lines.Add($"## {displayDirectoryName}");
|
|
||||||
lines.Add(string.Empty);
|
|
||||||
lines.Add($").OriginalString})");
|
|
||||||
lines.Add($"__{fileNameWithoutExtension}__");
|
|
||||||
if (isCounterPersonYear)
|
|
||||||
lines.Add($"#{years}yrs-ago");
|
|
||||||
else
|
|
||||||
lines.Add($"#{years}yrs-old");
|
|
||||||
lines.Add(string.Empty);
|
|
||||||
lines.AddRange(results.Select(l => $"{l.Image}{Environment.NewLine}{l.Link}{Environment.NewLine}"));
|
|
||||||
text = string.Join(Environment.NewLine, lines);
|
|
||||||
if (!Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(directory, $"{fileNameWithoutExtension}.md"), text, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
MoveFiles(locationContainerDebugDirectory, isCounterPersonYear, displayDirectoryName, keyValuePairs, linkedOnce, linkedTwice, linkedThrice, linkedFour, linkedFive);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IDistance<MetadataExtractor.Directory>.SaveMappedForOutputResolutions(string locationContainerDebugDirectory, string a2PeopleContentDirectory, string eDistanceContentDirectory, float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers, long personKey, bool isCounterPersonYear, string personKeyFormatted, string? displayDirectoryName)
|
ReadOnlyCollection<RelationContainer> IDistance<MetadataExtractor.Directory>.GetRelationContainers(int faceDistancePermyriad, int locationContainerDistanceTake, float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers)
|
||||||
{
|
{
|
||||||
|
ReadOnlyCollection<RelationContainer> result;
|
||||||
string? json;
|
string? json;
|
||||||
List<Record> records = new();
|
List<Record> records = new();
|
||||||
Shared.Models.FaceEncoding? modelsFaceEncoding;
|
Shared.Models.FaceEncoding? modelsFaceEncoding;
|
||||||
@ -699,15 +546,8 @@ public partial class E_Distance : IDistance<MetadataExtractor.Directory>
|
|||||||
faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding);
|
faceRecognitionDotNetFaceEncoding = FaceRecognition.LoadFaceEncoding(modelsFaceEncoding.RawEncoding);
|
||||||
records.Add(new(locationContainer.File, faceRecognitionDotNetFaceEncoding));
|
records.Add(new(locationContainer.File, faceRecognitionDotNetFaceEncoding));
|
||||||
}
|
}
|
||||||
string directory = Path.Combine(a2PeopleContentDirectory, locationContainerDistanceTolerance.ToString(), personKeyFormatted);
|
result = GetRelationCollections(faceDistancePermyriad, locationContainerDistanceTake, locationContainerDistanceTolerance, records);
|
||||||
if (!Directory.Exists(directory))
|
return result;
|
||||||
_ = Directory.CreateDirectory(directory);
|
|
||||||
if (records.Count > 0)
|
|
||||||
{
|
|
||||||
WriteVsCodeFiles(eDistanceContentDirectory, displayDirectoryName, directory);
|
|
||||||
SaveMappedForOutputResolutions(locationContainerDebugDirectory, eDistanceContentDirectory, locationContainerDistanceTolerance, personKey, isCounterPersonYear, personKeyFormatted, displayDirectoryName, records, directory);
|
|
||||||
}
|
|
||||||
_ = Shared.Models.Stateless.Methods.IPath.DeleteEmptyDirectories(directory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -843,6 +843,7 @@ public partial class DlibDotNet
|
|||||||
configuration.FaceConfidencePercent,
|
configuration.FaceConfidencePercent,
|
||||||
configuration.FaceDistancePermyriad,
|
configuration.FaceDistancePermyriad,
|
||||||
configuration.LocationContainerDebugDirectory,
|
configuration.LocationContainerDebugDirectory,
|
||||||
|
configuration.LocationContainerDistanceTake,
|
||||||
configuration.LocationContainerDistanceTolerance,
|
configuration.LocationContainerDistanceTolerance,
|
||||||
configuration.LocationDigits,
|
configuration.LocationDigits,
|
||||||
configuration.MappingDefaultName,
|
configuration.MappingDefaultName,
|
||||||
|
@ -33,6 +33,7 @@ public class Configuration
|
|||||||
public string[]? LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { get; set; }
|
public string[]? LoadOrCreateThenSaveImageFacesResultsForOutputResolutions { get; set; }
|
||||||
public bool? LoadPhotoPrismLocations { get; set; }
|
public bool? LoadPhotoPrismLocations { get; set; }
|
||||||
public string? LocationContainerDebugDirectory { get; set; }
|
public string? LocationContainerDebugDirectory { get; set; }
|
||||||
|
public int? LocationContainerDistanceTake { get; set; }
|
||||||
public float? LocationContainerDistanceTolerance { get; set; }
|
public float? LocationContainerDistanceTolerance { get; set; }
|
||||||
public int? LocationDigits { get; set; }
|
public int? LocationDigits { get; set; }
|
||||||
public int? LocationFactor { get; set; }
|
public int? LocationFactor { get; set; }
|
||||||
@ -132,6 +133,7 @@ public class Configuration
|
|||||||
// if (configuration?.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions));
|
// if (configuration?.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions is null) throw new NullReferenceException(nameof(configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions));
|
||||||
if (configuration?.LoadPhotoPrismLocations is null) throw new NullReferenceException(nameof(configuration.LoadPhotoPrismLocations));
|
if (configuration?.LoadPhotoPrismLocations is null) throw new NullReferenceException(nameof(configuration.LoadPhotoPrismLocations));
|
||||||
if (configuration?.LocationContainerDebugDirectory is null) throw new NullReferenceException(nameof(configuration.LocationContainerDebugDirectory));
|
if (configuration?.LocationContainerDebugDirectory is null) throw new NullReferenceException(nameof(configuration.LocationContainerDebugDirectory));
|
||||||
|
if (configuration?.LocationContainerDistanceTake is null) throw new NullReferenceException(nameof(configuration.LocationContainerDistanceTake));
|
||||||
// if (configuration?.LocationContainerDistanceTolerance is null) throw new NullReferenceException(nameof(configuration.LocationContainerDistanceTolerance));
|
// if (configuration?.LocationContainerDistanceTolerance is null) throw new NullReferenceException(nameof(configuration.LocationContainerDistanceTolerance));
|
||||||
if (configuration?.LocationDigits is null) throw new NullReferenceException(nameof(configuration.LocationDigits));
|
if (configuration?.LocationDigits is null) throw new NullReferenceException(nameof(configuration.LocationDigits));
|
||||||
if (configuration?.LocationFactor is null) throw new NullReferenceException(nameof(configuration.LocationFactor));
|
if (configuration?.LocationFactor is null) throw new NullReferenceException(nameof(configuration.LocationFactor));
|
||||||
@ -218,6 +220,7 @@ public class Configuration
|
|||||||
configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions ?? Array.Empty<string>(),
|
configuration.LoadOrCreateThenSaveImageFacesResultsForOutputResolutions ?? Array.Empty<string>(),
|
||||||
configuration.LoadPhotoPrismLocations.Value,
|
configuration.LoadPhotoPrismLocations.Value,
|
||||||
configuration.LocationContainerDebugDirectory,
|
configuration.LocationContainerDebugDirectory,
|
||||||
|
configuration.LocationContainerDistanceTake.Value,
|
||||||
configuration.LocationContainerDistanceTolerance,
|
configuration.LocationContainerDistanceTolerance,
|
||||||
configuration.LocationDigits.Value,
|
configuration.LocationDigits.Value,
|
||||||
configuration.LocationFactor.Value,
|
configuration.LocationFactor.Value,
|
||||||
|
@ -27,6 +27,7 @@ public record Configuration(Property.Models.Configuration PropertyConfiguration,
|
|||||||
string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions,
|
string[] LoadOrCreateThenSaveImageFacesResultsForOutputResolutions,
|
||||||
bool LoadPhotoPrismLocations,
|
bool LoadPhotoPrismLocations,
|
||||||
string LocationContainerDebugDirectory,
|
string LocationContainerDebugDirectory,
|
||||||
|
int LocationContainerDistanceTake,
|
||||||
float? LocationContainerDistanceTolerance,
|
float? LocationContainerDistanceTolerance,
|
||||||
int LocationDigits,
|
int LocationDigits,
|
||||||
int LocationFactor,
|
int LocationFactor,
|
||||||
|
@ -6,6 +6,7 @@ public record Configuration(bool DeletePossibleDuplicates,
|
|||||||
int FaceConfidencePercent,
|
int FaceConfidencePercent,
|
||||||
int FaceDistancePermyriad,
|
int FaceDistancePermyriad,
|
||||||
string LocationContainerDebugDirectory,
|
string LocationContainerDebugDirectory,
|
||||||
|
int LocationContainerDistanceTake,
|
||||||
float? LocationContainerDistanceTolerance,
|
float? LocationContainerDistanceTolerance,
|
||||||
int LocationDigits,
|
int LocationDigits,
|
||||||
string MappingDefaultName,
|
string MappingDefaultName,
|
||||||
|
@ -315,7 +315,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
if (lossCount != 0 || unableToMatchCount != 0)
|
if (lossCount != 0 || unableToMatchCount != 0)
|
||||||
{ }
|
{ }
|
||||||
if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && configuration.LocationContainerDistanceTolerance is not null)
|
if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && configuration.LocationContainerDistanceTolerance is not null)
|
||||||
Stateless.MapLogic.SaveMappedRelations(configuration, distance, a2PeopleContentDirectory, eDistanceContentDirectory, ticks, locationContainers, readOnlyPersonKeyFormattedToPersonContainer, readOnlyPersonKeyToPersonContainerCollection);
|
Stateless.RelationLogic.SaveMappedRelations(configuration, distance, a2PeopleContentDirectory, eDistanceContentDirectory, ticks, locationContainers, readOnlyPersonKeyFormattedToPersonContainer, readOnlyPersonKeyToPersonContainerCollection);
|
||||||
if (!string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory))
|
if (!string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory))
|
||||||
throw new Exception($"{nameof(configuration.LocationContainerDebugDirectory)} is not IsNullOrEmpty!");
|
throw new Exception($"{nameof(configuration.LocationContainerDebugDirectory)} is not IsNullOrEmpty!");
|
||||||
}
|
}
|
||||||
@ -681,9 +681,9 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
continue;
|
continue;
|
||||||
if (face.Mapping.MappingFromFilterPre.InSkipCollection is not null && face.Mapping.MappingFromFilterPre.InSkipCollection.Value)
|
if (face.Mapping.MappingFromFilterPre.InSkipCollection is not null && face.Mapping.MappingFromFilterPre.InSkipCollection.Value)
|
||||||
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>));
|
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>));
|
||||||
if (face.Mapping.MappingFromFilterPre.IsFocusModel is not null && face.Mapping.MappingFromFilterPre.IsFocusModel.Value)
|
if (face.Mapping.MappingFromFilterPre.IsFocusModel is not null && !face.Mapping.MappingFromFilterPre.IsFocusModel.Value)
|
||||||
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>));
|
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>));
|
||||||
if (face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
|
if (face.Mapping.MappingFromFilterPre.IsFocusRelativePath is not null && !face.Mapping.MappingFromFilterPre.IsFocusRelativePath.Value)
|
||||||
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>));
|
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>));
|
||||||
if (face.Mapping.MappingFromFilterPost.InSkipCollection is not null && face.Mapping.MappingFromFilterPost.InSkipCollection.Value)
|
if (face.Mapping.MappingFromFilterPost.InSkipCollection is not null && face.Mapping.MappingFromFilterPost.InSkipCollection.Value)
|
||||||
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>));
|
throw new NotSupportedException(nameof(Shared.Models.Methods.IDistance<object>));
|
||||||
@ -696,6 +696,8 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
if (faceDistanceLength.Length == 0)
|
if (faceDistanceLength.Length == 0)
|
||||||
continue;
|
continue;
|
||||||
|
if (faceDistanceLength.Id == faceDistanceEncoding.Id)
|
||||||
|
continue;
|
||||||
if (faceDistanceLength.MappingFromFilterPost is null)
|
if (faceDistanceLength.MappingFromFilterPost is null)
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
if (faceDistanceLength.MappingFromFilterPost.CanReMap is not null && !_Configuration.ReMap)
|
if (faceDistanceLength.MappingFromFilterPost.CanReMap is not null && !_Configuration.ReMap)
|
||||||
@ -890,9 +892,9 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
mappingFromFilterPost = sortingContainer.Source.MappingFromFilterPost;
|
mappingFromFilterPost = sortingContainer.Source.MappingFromFilterPost;
|
||||||
if (sortingContainer.Source.MappingFromFilterPre.InSkipCollection is not null && sortingContainer.Source.MappingFromFilterPre.InSkipCollection.Value)
|
if (sortingContainer.Source.MappingFromFilterPre.InSkipCollection is not null && sortingContainer.Source.MappingFromFilterPre.InSkipCollection.Value)
|
||||||
throw new NotSupportedException(nameof(GetSortingCollection));
|
throw new NotSupportedException(nameof(GetSortingCollection));
|
||||||
if (sortingContainer.Source.MappingFromFilterPre.IsFocusModel is not null && sortingContainer.Source.MappingFromFilterPre.IsFocusModel.Value)
|
if (sortingContainer.Source.MappingFromFilterPre.IsFocusModel is not null && !sortingContainer.Source.MappingFromFilterPre.IsFocusModel.Value)
|
||||||
throw new NotSupportedException(nameof(GetSortingCollection));
|
throw new NotSupportedException(nameof(GetSortingCollection));
|
||||||
if (sortingContainer.Source.MappingFromFilterPre.IsFocusRelativePath is not null && sortingContainer.Source.MappingFromFilterPre.IsFocusRelativePath.Value)
|
if (sortingContainer.Source.MappingFromFilterPre.IsFocusRelativePath is not null && !sortingContainer.Source.MappingFromFilterPre.IsFocusRelativePath.Value)
|
||||||
throw new NotSupportedException(nameof(GetSortingCollection));
|
throw new NotSupportedException(nameof(GetSortingCollection));
|
||||||
if (sortingContainer.Source.MappingFromFilterPost.InSkipCollection is not null && sortingContainer.Source.MappingFromFilterPost.InSkipCollection.Value)
|
if (sortingContainer.Source.MappingFromFilterPost.InSkipCollection is not null && sortingContainer.Source.MappingFromFilterPost.InSkipCollection.Value)
|
||||||
throw new NotSupportedException(nameof(GetSortingCollection));
|
throw new NotSupportedException(nameof(GetSortingCollection));
|
||||||
@ -905,6 +907,8 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
if (!wholePercentagesToMapping.TryGetValue(sorting.WholePercentages, out keyMapping))
|
if (!wholePercentagesToMapping.TryGetValue(sorting.WholePercentages, out keyMapping))
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
|
if (sortingContainer.Source.MappingFromItem.Id == keyMapping.MappingFromItem.Id)
|
||||||
|
throw new NotSupportedException(nameof(GetSortingCollection));
|
||||||
if (keyMapping.MappingFromFilterPost.CanReMap is not null && !_Configuration.ReMap)
|
if (keyMapping.MappingFromFilterPost.CanReMap is not null && !_Configuration.ReMap)
|
||||||
throw new NotSupportedException(nameof(GetSortingCollection));
|
throw new NotSupportedException(nameof(GetSortingCollection));
|
||||||
if (keyMapping.MappingFromFilterPost.CanReMap is not null && !keyMapping.MappingFromFilterPost.CanReMap.Value)
|
if (keyMapping.MappingFromFilterPost.CanReMap is not null && !keyMapping.MappingFromFilterPost.CanReMap.Value)
|
||||||
@ -1337,14 +1341,14 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
string? directoryName;
|
string? directoryName;
|
||||||
List<int> distinctFilteredIds = IContainer.GetFilteredDistinctIds(propertyConfiguration, containers);
|
List<int> distinctFilteredIds = IContainer.GetFilteredDistinctIds(propertyConfiguration, containers);
|
||||||
LookForAbandoned(propertyConfiguration, distinctFilteredIds);
|
LookForAbandoned(propertyConfiguration, distinctFilteredIds);
|
||||||
Stateless.MapLogic.LookForAbandoned(bResultsFullGroupDirectory, distinctFilteredIds);
|
Stateless.LookForAbandonedLogic.LookForAbandoned(bResultsFullGroupDirectory, distinctFilteredIds);
|
||||||
directories = Directory.GetDirectories(cResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
|
directories = Directory.GetDirectories(cResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
{
|
{
|
||||||
directoryName = Path.GetFileName(directory);
|
directoryName = Path.GetFileName(directory);
|
||||||
if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4)
|
if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4)
|
||||||
continue;
|
continue;
|
||||||
Stateless.MapLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName);
|
Stateless.LookForAbandonedLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName);
|
||||||
}
|
}
|
||||||
directories = Directory.GetDirectories(dResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
|
directories = Directory.GetDirectories(dResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
@ -1352,7 +1356,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
directoryName = Path.GetFileName(directory);
|
directoryName = Path.GetFileName(directory);
|
||||||
if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4)
|
if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4)
|
||||||
continue;
|
continue;
|
||||||
Stateless.MapLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName);
|
Stateless.LookForAbandonedLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName);
|
||||||
}
|
}
|
||||||
directories = Directory.GetDirectories(d2ResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
|
directories = Directory.GetDirectories(d2ResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
@ -1360,7 +1364,7 @@ public partial class MapLogic : Shared.Models.Methods.IMapLogic
|
|||||||
directoryName = Path.GetFileName(directory);
|
directoryName = Path.GetFileName(directory);
|
||||||
if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4)
|
if (string.IsNullOrEmpty(directoryName) || directoryName.Length != 2 && directoryName.Length != 4)
|
||||||
continue;
|
continue;
|
||||||
Stateless.MapLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName);
|
Stateless.LookForAbandonedLogic.LookForAbandoned(distinctFilteredIds, directory, directoryName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
72
Map/Models/Stateless/DecadeLogic.cs
Normal file
72
Map/Models/Stateless/DecadeLogic.cs
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Map.Models.Stateless;
|
||||||
|
|
||||||
|
internal abstract class DecadeLogic
|
||||||
|
{
|
||||||
|
|
||||||
|
internal static string GetDecade(MappingFromItem mappingFromItem)
|
||||||
|
{
|
||||||
|
string result;
|
||||||
|
string year;
|
||||||
|
if (mappingFromItem.DateTimeOriginal is null)
|
||||||
|
{
|
||||||
|
year = mappingFromItem.MinimumDateTime.Year.ToString();
|
||||||
|
result = year[3] > '4' ? $"#{year[..3]}+" : $"#{year[..3]}-";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
year = mappingFromItem.DateTimeOriginal.Value.Year.ToString();
|
||||||
|
result = year[3] > '4' ? $"^{year[..3]}+" : $"^{year[..3]}-";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, MappingFromItem mappingFromItem, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers)
|
||||||
|
{
|
||||||
|
DateTime dateTime;
|
||||||
|
FileInfo fileInfo;
|
||||||
|
string halfDecade;
|
||||||
|
string checkDirectory;
|
||||||
|
string? yearDirectory;
|
||||||
|
string yearDirectoryName;
|
||||||
|
string? personNameDirectory;
|
||||||
|
string personNameDirectoryName;
|
||||||
|
string? personKeyFormattedDirectory;
|
||||||
|
string? personKeyFormattedDirectoryName;
|
||||||
|
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
|
||||||
|
{
|
||||||
|
fileInfo = new(locationContainer.File);
|
||||||
|
if (!fileInfo.Exists)
|
||||||
|
continue;
|
||||||
|
dateTime = mappingFromItem.DateTimeOriginal is null ? mappingFromItem.MinimumDateTime : mappingFromItem.DateTimeOriginal.Value;
|
||||||
|
if (fileInfo.CreationTime != dateTime)
|
||||||
|
File.SetCreationTime(locationContainer.File, dateTime);
|
||||||
|
if (!moveToDecade)
|
||||||
|
continue;
|
||||||
|
personNameDirectory = Path.GetDirectoryName(locationContainer.File);
|
||||||
|
if (string.IsNullOrEmpty(personNameDirectory))
|
||||||
|
continue;
|
||||||
|
personNameDirectoryName = Path.GetFileName(personNameDirectory);
|
||||||
|
yearDirectory = Path.GetDirectoryName(personNameDirectory);
|
||||||
|
if (string.IsNullOrEmpty(yearDirectory))
|
||||||
|
continue;
|
||||||
|
yearDirectoryName = Path.GetFileName(yearDirectory);
|
||||||
|
personKeyFormattedDirectory = Path.GetDirectoryName(yearDirectory);
|
||||||
|
if (string.IsNullOrEmpty(personKeyFormattedDirectory))
|
||||||
|
continue;
|
||||||
|
personKeyFormattedDirectoryName = Path.GetFileName(personKeyFormattedDirectory);
|
||||||
|
if (personKeyFormattedDirectoryName.Length != propertyConfiguration.PersonBirthdayFormat.Length)
|
||||||
|
break;
|
||||||
|
halfDecade = GetDecade(mappingFromItem);
|
||||||
|
if (halfDecade == yearDirectoryName)
|
||||||
|
continue;
|
||||||
|
checkDirectory = Path.Combine(personKeyFormattedDirectory, halfDecade, personNameDirectoryName);
|
||||||
|
if (!Directory.Exists(checkDirectory))
|
||||||
|
_ = Directory.CreateDirectory(checkDirectory);
|
||||||
|
File.Move(locationContainer.File, Path.Combine(checkDirectory, Path.GetFileName(locationContainer.File)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
51
Map/Models/Stateless/LookForAbandonedLogic.cs
Normal file
51
Map/Models/Stateless/LookForAbandonedLogic.cs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
using View_by_Distance.Shared.Models.Stateless.Methods;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Map.Models.Stateless;
|
||||||
|
|
||||||
|
internal abstract class LookForAbandonedLogic
|
||||||
|
{
|
||||||
|
|
||||||
|
internal static void LookForAbandoned(List<int> distinctFilteredIds, string directory, string directoryName)
|
||||||
|
{
|
||||||
|
string fileNameWithoutExtension;
|
||||||
|
bool nameWithoutExtensionIsIdFormat;
|
||||||
|
List<string> renameCollection = new();
|
||||||
|
bool nameWithoutExtensionIsPaddedIdFormat;
|
||||||
|
int sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex();
|
||||||
|
string[] distinctFilteredIdsValues = distinctFilteredIds.Select(l => l.ToString()).ToArray();
|
||||||
|
string[] files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
|
||||||
|
foreach (string file in files)
|
||||||
|
{
|
||||||
|
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(file)));
|
||||||
|
nameWithoutExtensionIsIdFormat = IProperty.NameWithoutExtensionIsIdFormat(fileNameWithoutExtension);
|
||||||
|
nameWithoutExtensionIsPaddedIdFormat = IDirectory.NameWithoutExtensionIsPaddedIdFormat(fileNameWithoutExtension, sortOrderOnlyLengthIndex);
|
||||||
|
if (!nameWithoutExtensionIsIdFormat && !nameWithoutExtensionIsPaddedIdFormat)
|
||||||
|
continue;
|
||||||
|
if (distinctFilteredIdsValues.Contains(fileNameWithoutExtension))
|
||||||
|
continue;
|
||||||
|
renameCollection.Add(file);
|
||||||
|
}
|
||||||
|
if (renameCollection.Count > 0)
|
||||||
|
{
|
||||||
|
if (directoryName.Length == 2)
|
||||||
|
IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[0]}abd{directoryName[^1]}");
|
||||||
|
else if (directoryName.Length == 4)
|
||||||
|
IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[..2]}abd{directoryName[^2..]}");
|
||||||
|
else
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void LookForAbandoned(string bResultsFullGroupDirectory, List<int> distinctFilteredIds)
|
||||||
|
{
|
||||||
|
string[] directories = Directory.GetDirectories(bResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||||
|
foreach (string directory in directories)
|
||||||
|
{
|
||||||
|
string? directoryName = Path.GetFileName(directory);
|
||||||
|
if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4))
|
||||||
|
continue;
|
||||||
|
LookForAbandoned(distinctFilteredIds, directory, directoryName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -841,37 +841,6 @@ internal abstract class MapLogic
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void LookForAbandoned(List<int> distinctFilteredIds, string directory, string directoryName)
|
|
||||||
{
|
|
||||||
string fileNameWithoutExtension;
|
|
||||||
bool nameWithoutExtensionIsIdFormat;
|
|
||||||
List<string> renameCollection = new();
|
|
||||||
bool nameWithoutExtensionIsPaddedIdFormat;
|
|
||||||
int sortOrderOnlyLengthIndex = IDirectory.GetSortOrderOnlyLengthIndex();
|
|
||||||
string[] distinctFilteredIdsValues = distinctFilteredIds.Select(l => l.ToString()).ToArray();
|
|
||||||
string[] files = Directory.GetFiles(directory, "*", SearchOption.AllDirectories);
|
|
||||||
foreach (string file in files)
|
|
||||||
{
|
|
||||||
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(file)));
|
|
||||||
nameWithoutExtensionIsIdFormat = IProperty.NameWithoutExtensionIsIdFormat(fileNameWithoutExtension);
|
|
||||||
nameWithoutExtensionIsPaddedIdFormat = IDirectory.NameWithoutExtensionIsPaddedIdFormat(fileNameWithoutExtension, sortOrderOnlyLengthIndex);
|
|
||||||
if (!nameWithoutExtensionIsIdFormat && !nameWithoutExtensionIsPaddedIdFormat)
|
|
||||||
continue;
|
|
||||||
if (distinctFilteredIdsValues.Contains(fileNameWithoutExtension))
|
|
||||||
continue;
|
|
||||||
renameCollection.Add(file);
|
|
||||||
}
|
|
||||||
if (renameCollection.Count > 0)
|
|
||||||
{
|
|
||||||
if (directoryName.Length == 2)
|
|
||||||
IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[0]}abd{directoryName[^1]}");
|
|
||||||
else if (directoryName.Length == 4)
|
|
||||||
IDirectory.MoveFiles(renameCollection, directoryName, $"{directoryName[..2]}abd{directoryName[^2..]}");
|
|
||||||
else
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Record> GetRecords(Configuration configuration, bool? isDefault, string[] files, int directoryNumber, string personKeyFormatted, List<string> distinct, string? personDisplayDirectoryName)
|
private static List<Record> GetRecords(Configuration configuration, bool? isDefault, string[] files, int directoryNumber, string personKeyFormatted, List<string> distinct, string? personDisplayDirectoryName)
|
||||||
{
|
{
|
||||||
List<Record> results = new();
|
List<Record> results = new();
|
||||||
@ -1652,18 +1621,6 @@ internal abstract class MapLogic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void LookForAbandoned(string bResultsFullGroupDirectory, List<int> distinctFilteredIds)
|
|
||||||
{
|
|
||||||
string[] directories = Directory.GetDirectories(bResultsFullGroupDirectory, "*", SearchOption.TopDirectoryOnly);
|
|
||||||
foreach (string directory in directories)
|
|
||||||
{
|
|
||||||
string? directoryName = Path.GetFileName(directory);
|
|
||||||
if (string.IsNullOrEmpty(directoryName) || (directoryName.Length != 2 && directoryName.Length != 4))
|
|
||||||
continue;
|
|
||||||
LookForAbandoned(distinctFilteredIds, directory, directoryName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static ReadOnlyDictionary<int, List<int>> ConvertSkip(Dictionary<int, List<(string, int)>> skipCollection)
|
internal static ReadOnlyDictionary<int, List<int>> ConvertSkip(Dictionary<int, List<(string, int)>> skipCollection)
|
||||||
{
|
{
|
||||||
Dictionary<int, List<int>> results = new();
|
Dictionary<int, List<int>> results = new();
|
||||||
@ -1712,168 +1669,6 @@ internal abstract class MapLogic
|
|||||||
return new(results);
|
return new(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static string GetDecade(MappingFromItem mappingFromItem)
|
|
||||||
{
|
|
||||||
string result;
|
|
||||||
string year;
|
|
||||||
if (mappingFromItem.DateTimeOriginal is null)
|
|
||||||
{
|
|
||||||
year = mappingFromItem.MinimumDateTime.Year.ToString();
|
|
||||||
result = year[3] > '4' ? $"#{year[..3]}+" : $"#{year[..3]}-";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
year = mappingFromItem.DateTimeOriginal.Value.Year.ToString();
|
|
||||||
result = year[3] > '4' ? $"^{year[..3]}+" : $"^{year[..3]}-";
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, MappingFromItem mappingFromItem, ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> locationContainers)
|
|
||||||
{
|
|
||||||
DateTime dateTime;
|
|
||||||
FileInfo fileInfo;
|
|
||||||
string halfDecade;
|
|
||||||
string checkDirectory;
|
|
||||||
string? yearDirectory;
|
|
||||||
string yearDirectoryName;
|
|
||||||
string? personNameDirectory;
|
|
||||||
string personNameDirectoryName;
|
|
||||||
string? personKeyFormattedDirectory;
|
|
||||||
string? personKeyFormattedDirectoryName;
|
|
||||||
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
|
|
||||||
{
|
|
||||||
fileInfo = new(locationContainer.File);
|
|
||||||
if (!fileInfo.Exists)
|
|
||||||
continue;
|
|
||||||
dateTime = mappingFromItem.DateTimeOriginal is null ? mappingFromItem.MinimumDateTime : mappingFromItem.DateTimeOriginal.Value;
|
|
||||||
if (fileInfo.CreationTime != dateTime)
|
|
||||||
File.SetCreationTime(locationContainer.File, dateTime);
|
|
||||||
if (!moveToDecade)
|
|
||||||
continue;
|
|
||||||
personNameDirectory = Path.GetDirectoryName(locationContainer.File);
|
|
||||||
if (string.IsNullOrEmpty(personNameDirectory))
|
|
||||||
continue;
|
|
||||||
personNameDirectoryName = Path.GetFileName(personNameDirectory);
|
|
||||||
yearDirectory = Path.GetDirectoryName(personNameDirectory);
|
|
||||||
if (string.IsNullOrEmpty(yearDirectory))
|
|
||||||
continue;
|
|
||||||
yearDirectoryName = Path.GetFileName(yearDirectory);
|
|
||||||
personKeyFormattedDirectory = Path.GetDirectoryName(yearDirectory);
|
|
||||||
if (string.IsNullOrEmpty(personKeyFormattedDirectory))
|
|
||||||
continue;
|
|
||||||
personKeyFormattedDirectoryName = Path.GetFileName(personKeyFormattedDirectory);
|
|
||||||
if (personKeyFormattedDirectoryName.Length != propertyConfiguration.PersonBirthdayFormat.Length)
|
|
||||||
break;
|
|
||||||
halfDecade = GetDecade(mappingFromItem);
|
|
||||||
if (halfDecade == yearDirectoryName)
|
|
||||||
continue;
|
|
||||||
checkDirectory = Path.Combine(personKeyFormattedDirectory, halfDecade, personNameDirectoryName);
|
|
||||||
if (!Directory.Exists(checkDirectory))
|
|
||||||
_ = Directory.CreateDirectory(checkDirectory);
|
|
||||||
File.Move(locationContainer.File, Path.Combine(checkDirectory, Path.GetFileName(locationContainer.File)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ReadOnlyCollection<ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>>> GetCollections(List<LocationContainer<MetadataExtractor.Directory>> locationContainers)
|
|
||||||
{
|
|
||||||
List<ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>>> results = new();
|
|
||||||
List<LocationContainer<MetadataExtractor.Directory>>? collection;
|
|
||||||
Dictionary<long, List<LocationContainer<MetadataExtractor.Directory>>> keyValuePairs = new();
|
|
||||||
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
|
|
||||||
{
|
|
||||||
if (!locationContainer.FromDistanceContent)
|
|
||||||
continue;
|
|
||||||
if (!keyValuePairs.TryGetValue(locationContainer.PersonKey, out collection))
|
|
||||||
{
|
|
||||||
keyValuePairs.Add(locationContainer.PersonKey, new());
|
|
||||||
if (!keyValuePairs.TryGetValue(locationContainer.PersonKey, out collection))
|
|
||||||
throw new Exception();
|
|
||||||
}
|
|
||||||
collection.Add(locationContainer);
|
|
||||||
}
|
|
||||||
foreach (KeyValuePair<long, List<LocationContainer<MetadataExtractor.Directory>>> keyValuePair in keyValuePairs)
|
|
||||||
results.Add(new(keyValuePair.Value));
|
|
||||||
return new(results);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string? GetDisplayDirectoryName(ReadOnlyDictionary<long, List<PersonContainer>> readOnlyPersonKeyToPersonContainerCollection, ReadOnlyDictionary<string, PersonContainer> readOnlyPersonKeyFormattedToPersonContainer, long personKey, string personKeyFormatted)
|
|
||||||
{
|
|
||||||
string? result;
|
|
||||||
PersonContainer? personContainer;
|
|
||||||
List<PersonContainer>? collection;
|
|
||||||
_ = readOnlyPersonKeyToPersonContainerCollection.TryGetValue(personKey, out collection);
|
|
||||||
if (collection is not null)
|
|
||||||
result = collection[0].DisplayDirectoryName;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!readOnlyPersonKeyFormattedToPersonContainer.TryGetValue(personKeyFormatted, out personContainer))
|
|
||||||
result = null;
|
|
||||||
else
|
|
||||||
result = personContainer.DisplayDirectoryName;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void AddDisplayDirectoryNames(Configuration configuration, string eDistanceContentDirectory, ReadOnlyDictionary<string, PersonContainer> readOnlyPersonKeyFormattedToPersonContainer, ReadOnlyDictionary<long, List<PersonContainer>> readOnlyPersonKeyToPersonContainerCollection, ReadOnlyCollection<ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>>> collections)
|
|
||||||
{
|
|
||||||
bool isCounterPersonYear;
|
|
||||||
string personKeyFormatted;
|
|
||||||
string? displayDirectoryName;
|
|
||||||
string? checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory);
|
|
||||||
_ = IPath.DeleteEmptyDirectories(checkDirectory);
|
|
||||||
foreach (ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> collection in collections)
|
|
||||||
{
|
|
||||||
if (configuration.LocationContainerDistanceTolerance is null)
|
|
||||||
break;
|
|
||||||
isCounterPersonYear = IPersonBirthday.IsCounterPersonYear(new DateTime(collection[0].PersonKey).Year);
|
|
||||||
if (isCounterPersonYear)
|
|
||||||
continue;
|
|
||||||
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, collection[0].PersonKey);
|
|
||||||
checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory, personKeyFormatted);
|
|
||||||
if (!Directory.Exists(checkDirectory))
|
|
||||||
continue;
|
|
||||||
displayDirectoryName = GetDisplayDirectoryName(readOnlyPersonKeyToPersonContainerCollection, readOnlyPersonKeyFormattedToPersonContainer, collection[0].PersonKey, personKeyFormatted);
|
|
||||||
if (string.IsNullOrEmpty(displayDirectoryName))
|
|
||||||
continue;
|
|
||||||
foreach (string yearDirectory in Directory.GetDirectories(checkDirectory, "*", SearchOption.TopDirectoryOnly))
|
|
||||||
{
|
|
||||||
checkDirectory = Path.Combine(yearDirectory, displayDirectoryName);
|
|
||||||
if (!Directory.Exists(checkDirectory))
|
|
||||||
_ = Directory.CreateDirectory(checkDirectory);
|
|
||||||
}
|
|
||||||
checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory, personKeyFormatted, displayDirectoryName);
|
|
||||||
if (!Directory.Exists(checkDirectory))
|
|
||||||
_ = Directory.CreateDirectory(checkDirectory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void SaveMappedRelations(Configuration configuration, Shared.Models.Methods.IDistance<MetadataExtractor.Directory> distance, string a2PeopleContentDirectory, string eDistanceContentDirectory, long ticks, List<LocationContainer<MetadataExtractor.Directory>> locationContainers, ReadOnlyDictionary<string, PersonContainer> readOnlyPersonKeyFormattedToPersonContainer, ReadOnlyDictionary<long, List<PersonContainer>> readOnlyPersonKeyToPersonContainerCollection)
|
|
||||||
{
|
|
||||||
bool isCounterPersonYear;
|
|
||||||
string personKeyFormatted;
|
|
||||||
string? displayDirectoryName;
|
|
||||||
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
|
|
||||||
string message = $") Save Mapped Relations - {totalSeconds} total second(s)";
|
|
||||||
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
|
||||||
ReadOnlyCollection<ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>>> collections = GetCollections(locationContainers);
|
|
||||||
using ProgressBar progressBar = new(collections.Count, message, options);
|
|
||||||
foreach (ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> collection in collections)
|
|
||||||
{
|
|
||||||
if (configuration.LocationContainerDistanceTolerance is null)
|
|
||||||
break;
|
|
||||||
progressBar.Tick();
|
|
||||||
if (collection.Count == 0)
|
|
||||||
continue;
|
|
||||||
isCounterPersonYear = IPersonBirthday.IsCounterPersonYear(new DateTime(collection[0].PersonKey).Year);
|
|
||||||
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, collection[0].PersonKey);
|
|
||||||
displayDirectoryName = GetDisplayDirectoryName(readOnlyPersonKeyToPersonContainerCollection, readOnlyPersonKeyFormattedToPersonContainer, collection[0].PersonKey, personKeyFormatted);
|
|
||||||
distance.SaveMappedForOutputResolutions(configuration.LocationContainerDebugDirectory, a2PeopleContentDirectory, eDistanceContentDirectory, configuration.LocationContainerDistanceTolerance.Value, collection, collection[0].PersonKey, isCounterPersonYear, personKeyFormatted, displayDirectoryName);
|
|
||||||
}
|
|
||||||
if (!string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory))
|
|
||||||
AddDisplayDirectoryNames(configuration, eDistanceContentDirectory, readOnlyPersonKeyFormattedToPersonContainer, readOnlyPersonKeyToPersonContainerCollection, collections);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static bool? CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation)
|
internal static bool? CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>? wholePercentagesToPersonContainers, MappingFromLocation mappingFromLocation)
|
||||||
{
|
{
|
||||||
bool? result;
|
bool? result;
|
||||||
|
@ -38,7 +38,7 @@ public interface IMapLogic
|
|||||||
void TestStatic_SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, Shared.Models.MappingFromItem mappingFromItem, ReadOnlyCollection<Shared.Models.LocationContainer<MetadataExtractor.Directory>> locationContainers) =>
|
void TestStatic_SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, Shared.Models.MappingFromItem mappingFromItem, ReadOnlyCollection<Shared.Models.LocationContainer<MetadataExtractor.Directory>> locationContainers) =>
|
||||||
SetCreationTimeMaybeMoveToDecade(propertyConfiguration, moveToDecade, mappingFromItem, locationContainers);
|
SetCreationTimeMaybeMoveToDecade(propertyConfiguration, moveToDecade, mappingFromItem, locationContainers);
|
||||||
static void SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, Shared.Models.MappingFromItem mappingFromItem, ReadOnlyCollection<Shared.Models.LocationContainer<MetadataExtractor.Directory>> locationContainers) =>
|
static void SetCreationTimeMaybeMoveToDecade(Property.Models.Configuration propertyConfiguration, bool moveToDecade, Shared.Models.MappingFromItem mappingFromItem, ReadOnlyCollection<Shared.Models.LocationContainer<MetadataExtractor.Directory>> locationContainers) =>
|
||||||
MapLogic.SetCreationTimeMaybeMoveToDecade(propertyConfiguration, moveToDecade, mappingFromItem, locationContainers);
|
DecadeLogic.SetCreationTimeMaybeMoveToDecade(propertyConfiguration, moveToDecade, mappingFromItem, locationContainers);
|
||||||
|
|
||||||
bool? TestStatic_CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<Shared.Models.PersonContainer>>? wholePercentagesToPersonContainers, Shared.Models.MappingFromLocation mappingFromLocation) =>
|
bool? TestStatic_CanReMap(long[] jLinkResolvedPersonKeys, ReadOnlyDictionary<int, ReadOnlyCollection<Shared.Models.PersonContainer>>? wholePercentagesToPersonContainers, Shared.Models.MappingFromLocation mappingFromLocation) =>
|
||||||
CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
|
CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
|
||||||
@ -48,6 +48,6 @@ public interface IMapLogic
|
|||||||
string TestStatic_GetDecade(Shared.Models.MappingFromItem mappingFromItem) =>
|
string TestStatic_GetDecade(Shared.Models.MappingFromItem mappingFromItem) =>
|
||||||
GetDecade(mappingFromItem);
|
GetDecade(mappingFromItem);
|
||||||
static string GetDecade(Shared.Models.MappingFromItem mappingFromItem) =>
|
static string GetDecade(Shared.Models.MappingFromItem mappingFromItem) =>
|
||||||
MapLogic.GetDecade(mappingFromItem);
|
DecadeLogic.GetDecade(mappingFromItem);
|
||||||
|
|
||||||
}
|
}
|
400
Map/Models/Stateless/RelationLogic.cs
Normal file
400
Map/Models/Stateless/RelationLogic.cs
Normal file
@ -0,0 +1,400 @@
|
|||||||
|
using ShellProgressBar;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using View_by_Distance.Shared.Models;
|
||||||
|
using View_by_Distance.Shared.Models.Stateless.Methods;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Map.Models.Stateless;
|
||||||
|
|
||||||
|
internal abstract class RelationLogic
|
||||||
|
{
|
||||||
|
|
||||||
|
internal record RelationCollection(ReadOnlyCollection<RelationContainer> RelationContainers,
|
||||||
|
ReadOnlyCollection<string> Linked1,
|
||||||
|
ReadOnlyCollection<string> Linked2,
|
||||||
|
ReadOnlyCollection<string> Linked3,
|
||||||
|
ReadOnlyCollection<string> Linked4,
|
||||||
|
ReadOnlyCollection<string> Linked5,
|
||||||
|
ReadOnlyCollection<string> Linked6,
|
||||||
|
ReadOnlyCollection<string> Linked7,
|
||||||
|
ReadOnlyCollection<string> Linked8,
|
||||||
|
ReadOnlyCollection<string> Linked9,
|
||||||
|
ReadOnlyDictionary<string, string> MovedFiles);
|
||||||
|
|
||||||
|
private static ReadOnlyCollection<ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>>> GetCollections(List<LocationContainer<MetadataExtractor.Directory>> locationContainers)
|
||||||
|
{
|
||||||
|
List<ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>>> results = new();
|
||||||
|
List<LocationContainer<MetadataExtractor.Directory>>? collection;
|
||||||
|
Dictionary<long, List<LocationContainer<MetadataExtractor.Directory>>> keyValuePairs = new();
|
||||||
|
foreach (LocationContainer<MetadataExtractor.Directory> locationContainer in locationContainers)
|
||||||
|
{
|
||||||
|
if (!locationContainer.FromDistanceContent)
|
||||||
|
continue;
|
||||||
|
if (!keyValuePairs.TryGetValue(locationContainer.PersonKey, out collection))
|
||||||
|
{
|
||||||
|
keyValuePairs.Add(locationContainer.PersonKey, new());
|
||||||
|
if (!keyValuePairs.TryGetValue(locationContainer.PersonKey, out collection))
|
||||||
|
throw new Exception();
|
||||||
|
}
|
||||||
|
collection.Add(locationContainer);
|
||||||
|
}
|
||||||
|
foreach (KeyValuePair<long, List<LocationContainer<MetadataExtractor.Directory>>> keyValuePair in keyValuePairs)
|
||||||
|
results.Add(new(keyValuePair.Value));
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string? GetDisplayDirectoryName(ReadOnlyDictionary<long, List<PersonContainer>> readOnlyPersonKeyToPersonContainerCollection, ReadOnlyDictionary<string, PersonContainer> readOnlyPersonKeyFormattedToPersonContainer, long personKey, string personKeyFormatted)
|
||||||
|
{
|
||||||
|
string? result;
|
||||||
|
PersonContainer? personContainer;
|
||||||
|
List<PersonContainer>? collection;
|
||||||
|
_ = readOnlyPersonKeyToPersonContainerCollection.TryGetValue(personKey, out collection);
|
||||||
|
if (collection is not null)
|
||||||
|
result = collection[0].DisplayDirectoryName;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!readOnlyPersonKeyFormattedToPersonContainer.TryGetValue(personKeyFormatted, out personContainer))
|
||||||
|
result = null;
|
||||||
|
else
|
||||||
|
result = personContainer.DisplayDirectoryName;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddDisplayDirectoryNames(Configuration configuration, string eDistanceContentDirectory, ReadOnlyDictionary<string, PersonContainer> readOnlyPersonKeyFormattedToPersonContainer, ReadOnlyDictionary<long, List<PersonContainer>> readOnlyPersonKeyToPersonContainerCollection, ReadOnlyCollection<ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>>> collections)
|
||||||
|
{
|
||||||
|
bool isCounterPersonYear;
|
||||||
|
string personKeyFormatted;
|
||||||
|
string? displayDirectoryName;
|
||||||
|
string? checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory);
|
||||||
|
_ = IPath.DeleteEmptyDirectories(checkDirectory);
|
||||||
|
foreach (ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> collection in collections)
|
||||||
|
{
|
||||||
|
if (configuration.LocationContainerDistanceTolerance is null)
|
||||||
|
break;
|
||||||
|
isCounterPersonYear = IPersonBirthday.IsCounterPersonYear(new DateTime(collection[0].PersonKey).Year);
|
||||||
|
if (isCounterPersonYear)
|
||||||
|
continue;
|
||||||
|
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, collection[0].PersonKey);
|
||||||
|
checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory, personKeyFormatted);
|
||||||
|
if (!Directory.Exists(checkDirectory))
|
||||||
|
continue;
|
||||||
|
displayDirectoryName = GetDisplayDirectoryName(readOnlyPersonKeyToPersonContainerCollection, readOnlyPersonKeyFormattedToPersonContainer, collection[0].PersonKey, personKeyFormatted);
|
||||||
|
if (string.IsNullOrEmpty(displayDirectoryName))
|
||||||
|
continue;
|
||||||
|
foreach (string yearDirectory in Directory.GetDirectories(checkDirectory, "*", SearchOption.TopDirectoryOnly))
|
||||||
|
{
|
||||||
|
checkDirectory = Path.Combine(yearDirectory, displayDirectoryName);
|
||||||
|
if (!Directory.Exists(checkDirectory))
|
||||||
|
_ = Directory.CreateDirectory(checkDirectory);
|
||||||
|
}
|
||||||
|
checkDirectory = Path.Combine(eDistanceContentDirectory, configuration.LocationContainerDebugDirectory, personKeyFormatted, displayDirectoryName);
|
||||||
|
if (!Directory.Exists(checkDirectory))
|
||||||
|
_ = Directory.CreateDirectory(checkDirectory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteVsCodeFiles(string eDistanceContentDirectory, string? displayDirectoryName, string directory)
|
||||||
|
{
|
||||||
|
string json;
|
||||||
|
string vsCodeDirectory = Path.Combine(directory, ".vscode");
|
||||||
|
if (!Directory.Exists(vsCodeDirectory))
|
||||||
|
_ = Directory.CreateDirectory(vsCodeDirectory);
|
||||||
|
if (displayDirectoryName is not null)
|
||||||
|
File.WriteAllText(Path.Combine(directory, $"_ {displayDirectoryName}.txt"), string.Empty);
|
||||||
|
json = "{ \"[markdown]\": { \"editor.wordWrap\": \"off\" }, \"foam.links.hover.enable\": false, \"foam.graph.style\": { \"background\": \"#202020\", \"node\": { \"note\": \"#f2cb1d\", \"distance\": \"green\", \"image\": \"orange\", \"placeholder\": \"white\", } } }";
|
||||||
|
_ = IPath.WriteAllText(Path.Combine(vsCodeDirectory, "settings.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
|
||||||
|
json = string.Concat("{ \"version\": \"2.0.0\", \"tasks\": [ { \"label\": \"MKLink\", \"type\": \"shell\", \"command\": \"New-Item\", \"args\": [ \"-ItemType\", \"Junction\", \"-Path\", \"'", directory.Replace('\\', '/'), "/()'\", \"-Target\", \"'", eDistanceContentDirectory.Replace('\\', '/'), "'\" ], \"problemMatcher\": [] } ] }");
|
||||||
|
_ = IPath.WriteAllText(Path.Combine(vsCodeDirectory, "tasks.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyDictionary<string, string> MoveFiles(string locationContainerDebugDirectory, bool isCounterPersonYear, string? displayDirectoryName, List<string> linked1, List<string> linked2, List<string> linked3, List<string> linked4, List<string> linked5, List<string> linked6, List<string> linked7, List<string> linked8, List<string> linked9)
|
||||||
|
{
|
||||||
|
Dictionary<string, string> results = new();
|
||||||
|
char c;
|
||||||
|
string checkFile;
|
||||||
|
string debugFile;
|
||||||
|
string checkDirectory;
|
||||||
|
string? yearDirectory;
|
||||||
|
string? personNameDirectory;
|
||||||
|
string? maybeTicksDirectoryName;
|
||||||
|
string? personNameDirectoryName;
|
||||||
|
string? personKeyFormattedDirectory;
|
||||||
|
Dictionary<string, int> fullNameToCount = new();
|
||||||
|
foreach (string file in linked1)
|
||||||
|
fullNameToCount.Add(file, 1);
|
||||||
|
foreach (string file in linked2)
|
||||||
|
fullNameToCount[file] += 1;
|
||||||
|
foreach (string file in linked3)
|
||||||
|
fullNameToCount[file] += 1;
|
||||||
|
foreach (string file in linked4)
|
||||||
|
fullNameToCount[file] += 1;
|
||||||
|
foreach (string file in linked5)
|
||||||
|
fullNameToCount[file] += 1;
|
||||||
|
foreach (string file in linked6)
|
||||||
|
fullNameToCount[file] += 1;
|
||||||
|
foreach (string file in linked7)
|
||||||
|
fullNameToCount[file] += 1;
|
||||||
|
foreach (string file in linked8)
|
||||||
|
fullNameToCount[file] += 1;
|
||||||
|
foreach (string file in linked9)
|
||||||
|
fullNameToCount[file] += 1;
|
||||||
|
foreach (KeyValuePair<string, int> keyValuePair in fullNameToCount)
|
||||||
|
{
|
||||||
|
personNameDirectory = Path.GetDirectoryName(keyValuePair.Key);
|
||||||
|
yearDirectory = Path.GetDirectoryName(personNameDirectory);
|
||||||
|
personNameDirectoryName = Path.GetFileName(personNameDirectory);
|
||||||
|
personKeyFormattedDirectory = Path.GetDirectoryName(yearDirectory);
|
||||||
|
maybeTicksDirectoryName = Path.GetFileName(personKeyFormattedDirectory);
|
||||||
|
if (string.IsNullOrEmpty(personNameDirectory) || string.IsNullOrEmpty(yearDirectory) || string.IsNullOrEmpty(personKeyFormattedDirectory) || string.IsNullOrEmpty(personNameDirectoryName))
|
||||||
|
continue;
|
||||||
|
c = Convert.ToChar(48 + keyValuePair.Value);
|
||||||
|
if (c is ':' or ';' or '<' or '=' or '>' or '?')
|
||||||
|
c = '_';
|
||||||
|
if (maybeTicksDirectoryName == locationContainerDebugDirectory)
|
||||||
|
checkDirectory = Path.Combine(yearDirectory, $"{keyValuePair.Value}{new string(c, 7)}");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(locationContainerDebugDirectory))
|
||||||
|
continue;
|
||||||
|
checkDirectory = Path.Combine(personKeyFormattedDirectory, $"{keyValuePair.Value}{new string(c, 7)}");
|
||||||
|
}
|
||||||
|
if (maybeTicksDirectoryName != locationContainerDebugDirectory)
|
||||||
|
{
|
||||||
|
if (isCounterPersonYear || string.IsNullOrEmpty(displayDirectoryName))
|
||||||
|
checkDirectory = Path.Combine(checkDirectory, personNameDirectoryName);
|
||||||
|
else
|
||||||
|
checkDirectory = Path.Combine(checkDirectory, displayDirectoryName[0].ToString());
|
||||||
|
}
|
||||||
|
if (checkDirectory == personNameDirectory)
|
||||||
|
continue;
|
||||||
|
if (!Directory.Exists(checkDirectory))
|
||||||
|
_ = Directory.CreateDirectory(checkDirectory);
|
||||||
|
checkFile = Path.Combine(checkDirectory, Path.GetFileName(keyValuePair.Key));
|
||||||
|
if (File.Exists(checkFile))
|
||||||
|
continue;
|
||||||
|
results.Add(keyValuePair.Key, checkFile);
|
||||||
|
File.Move(keyValuePair.Key, checkFile);
|
||||||
|
debugFile = $"{keyValuePair.Key[..^4]}.gif";
|
||||||
|
if (File.Exists(debugFile))
|
||||||
|
{
|
||||||
|
checkFile = Path.Combine(checkDirectory, $"{Path.GetFileName(keyValuePair.Key)[..^4]}.gif");
|
||||||
|
if (File.Exists(checkFile))
|
||||||
|
continue;
|
||||||
|
File.Move(debugFile, checkFile);
|
||||||
|
}
|
||||||
|
if (maybeTicksDirectoryName == locationContainerDebugDirectory && !string.IsNullOrEmpty(displayDirectoryName))
|
||||||
|
{
|
||||||
|
checkDirectory = Path.Combine(checkDirectory, displayDirectoryName);
|
||||||
|
if (!Directory.Exists(checkDirectory))
|
||||||
|
_ = Directory.CreateDirectory(checkDirectory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RelationCollection GetMappedRelationCollection(string locationContainerDebugDirectory, int take, bool isCounterPersonYear, string? displayDirectoryName, ReadOnlyCollection<RelationContainer> relationContainers)
|
||||||
|
{
|
||||||
|
RelationCollection result;
|
||||||
|
List<string> linked1 = new();
|
||||||
|
List<string> linked2 = new();
|
||||||
|
List<string> linked3 = new();
|
||||||
|
List<string> linked4 = new();
|
||||||
|
List<string> linked5 = new();
|
||||||
|
List<string> linked6 = new();
|
||||||
|
List<string> linked7 = new();
|
||||||
|
List<string> linked8 = new();
|
||||||
|
List<string> linked9 = new();
|
||||||
|
foreach ((FileHolder fileHolder, ReadOnlyCollection<Relation> relations) in relationContainers)
|
||||||
|
{
|
||||||
|
foreach (Relation relation in relations.Take(take))
|
||||||
|
{
|
||||||
|
if (!linked1.Contains(relation.File))
|
||||||
|
{
|
||||||
|
linked1.Add(relation.File);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!linked2.Contains(relation.File))
|
||||||
|
{
|
||||||
|
linked2.Add(relation.File);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!linked3.Contains(relation.File))
|
||||||
|
{
|
||||||
|
linked3.Add(relation.File);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!linked4.Contains(relation.File))
|
||||||
|
{
|
||||||
|
linked4.Add(relation.File);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!linked5.Contains(relation.File))
|
||||||
|
{
|
||||||
|
linked5.Add(relation.File);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!linked6.Contains(relation.File))
|
||||||
|
{
|
||||||
|
linked6.Add(relation.File);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!linked7.Contains(relation.File))
|
||||||
|
{
|
||||||
|
linked7.Add(relation.File);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!linked8.Contains(relation.File))
|
||||||
|
{
|
||||||
|
linked8.Add(relation.File);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!linked9.Contains(relation.File))
|
||||||
|
{
|
||||||
|
linked9.Add(relation.File);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ReadOnlyDictionary<string, string> movedFiles = MoveFiles(locationContainerDebugDirectory, isCounterPersonYear, displayDirectoryName, linked1, linked2, linked3, linked4, linked5, linked6, linked7, linked8, linked9);
|
||||||
|
result = new(relationContainers, new(linked1), new(linked2), new(linked3), new(linked4), new(linked5), new(linked6), new(linked7), new(linked8), new(linked9), movedFiles);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteFile(int take, long personKey, bool isCounterPersonYear, string personKeyFormatted, string? displayDirectoryName, string directory, long ticks, Uri uri, RelationCollection relationCollection)
|
||||||
|
{
|
||||||
|
string a;
|
||||||
|
string b;
|
||||||
|
int years;
|
||||||
|
string text;
|
||||||
|
string? file;
|
||||||
|
Relation relation;
|
||||||
|
string markDownFile;
|
||||||
|
FileHolder fileHolder;
|
||||||
|
string originalString;
|
||||||
|
List<string> lines = new();
|
||||||
|
string fileNameWithoutExtension;
|
||||||
|
foreach ((FileHolder relationFileHolder, ReadOnlyCollection<Relation> relations) in relationCollection.RelationContainers)
|
||||||
|
{
|
||||||
|
lines.Clear();
|
||||||
|
if (relationCollection.MovedFiles.TryGetValue(relationFileHolder.FullName, out file))
|
||||||
|
fileHolder = new(file);
|
||||||
|
else
|
||||||
|
fileHolder = new(relationFileHolder.FullName);
|
||||||
|
if (!relationFileHolder.Exists || relationFileHolder.CreationTime is null)
|
||||||
|
continue;
|
||||||
|
if (isCounterPersonYear)
|
||||||
|
(years, _) = IAge.GetAge(ticks, relationFileHolder.CreationTime.Value.Ticks);
|
||||||
|
else
|
||||||
|
(years, _) = IAge.GetAge(relationFileHolder.CreationTime.Value.Ticks, personKey);
|
||||||
|
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileHolder.NameWithoutExtension);
|
||||||
|
markDownFile = $"{fileNameWithoutExtension}.md";
|
||||||
|
lines.Add("---");
|
||||||
|
lines.Add("type: \"distance\"");
|
||||||
|
lines.Add("---");
|
||||||
|
lines.Add(string.Empty);
|
||||||
|
if (displayDirectoryName is null)
|
||||||
|
lines.Add($"## {personKeyFormatted}");
|
||||||
|
else
|
||||||
|
lines.Add($"## {displayDirectoryName}");
|
||||||
|
lines.Add(string.Empty);
|
||||||
|
lines.Add($").OriginalString})");
|
||||||
|
lines.Add($"__{fileNameWithoutExtension}__");
|
||||||
|
if (isCounterPersonYear)
|
||||||
|
lines.Add($"#{years}yrs-ago");
|
||||||
|
else
|
||||||
|
lines.Add($"#{years}yrs-old");
|
||||||
|
lines.Add($"~~{relations.Count}~~");
|
||||||
|
lines.Add(string.Empty);
|
||||||
|
for (int i = 0; i < relations.Count; i++)
|
||||||
|
{
|
||||||
|
relation = relations[i];
|
||||||
|
if (relationCollection.MovedFiles.TryGetValue(relation.File, out file))
|
||||||
|
fileHolder = new(file);
|
||||||
|
else
|
||||||
|
fileHolder = new(relation.File);
|
||||||
|
if (!fileHolder.Exists || fileHolder.CreationTime is null)
|
||||||
|
continue;
|
||||||
|
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileHolder.NameWithoutExtension);
|
||||||
|
originalString = uri.MakeRelativeUri(new(fileHolder.FullName)).OriginalString;
|
||||||
|
if (i < take)
|
||||||
|
(a, b) = ("[[", "]]");
|
||||||
|
else
|
||||||
|
(a, b) = ("~~", "~~");
|
||||||
|
lines.Add($"{Environment.NewLine}{a}{fileNameWithoutExtension}{b}");
|
||||||
|
lines.Add(string.Empty);
|
||||||
|
}
|
||||||
|
text = string.Join(Environment.NewLine, lines);
|
||||||
|
File.WriteAllText(Path.Combine(directory, markDownFile), text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int GetTake(int locationContainerDistanceTake, int count)
|
||||||
|
{
|
||||||
|
int result = locationContainerDistanceTake;
|
||||||
|
int subtract = (int)(locationContainerDistanceTake * .05);
|
||||||
|
if (subtract < 1)
|
||||||
|
subtract = 1;
|
||||||
|
if (count > 9000)
|
||||||
|
result -= subtract;
|
||||||
|
if (count > 8000)
|
||||||
|
result -= subtract;
|
||||||
|
if (count > 7000)
|
||||||
|
result -= subtract;
|
||||||
|
if (count > 6000)
|
||||||
|
result -= subtract;
|
||||||
|
if (count > 5000)
|
||||||
|
result -= subtract;
|
||||||
|
if (count > 4000)
|
||||||
|
result -= subtract;
|
||||||
|
if (count > 3000)
|
||||||
|
result -= subtract;
|
||||||
|
if (count > 2000)
|
||||||
|
result -= subtract;
|
||||||
|
if (count > 1000)
|
||||||
|
result -= subtract;
|
||||||
|
if (result < 3)
|
||||||
|
result = 3;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void SaveMappedRelations(Configuration configuration, Shared.Models.Methods.IDistance<MetadataExtractor.Directory> distance, string a2PeopleContentDirectory, string eDistanceContentDirectory, long ticks, List<LocationContainer<MetadataExtractor.Directory>> locationContainers, ReadOnlyDictionary<string, PersonContainer> readOnlyPersonKeyFormattedToPersonContainer, ReadOnlyDictionary<long, List<PersonContainer>> readOnlyPersonKeyToPersonContainerCollection)
|
||||||
|
{
|
||||||
|
int take;
|
||||||
|
string directory;
|
||||||
|
bool isCounterPersonYear;
|
||||||
|
string personKeyFormatted;
|
||||||
|
string? displayDirectoryName;
|
||||||
|
Uri uri = new(eDistanceContentDirectory);
|
||||||
|
RelationCollection relationCollection;
|
||||||
|
ReadOnlyCollection<RelationContainer> relationContainers;
|
||||||
|
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
|
||||||
|
string message = $") Save Mapped Relations - {totalSeconds} total second(s)";
|
||||||
|
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };
|
||||||
|
ReadOnlyCollection<ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>>> collections = GetCollections(locationContainers);
|
||||||
|
using ProgressBar progressBar = new(collections.Count, message, options);
|
||||||
|
foreach (ReadOnlyCollection<LocationContainer<MetadataExtractor.Directory>> collection in collections)
|
||||||
|
{
|
||||||
|
if (configuration.LocationContainerDistanceTolerance is null)
|
||||||
|
break;
|
||||||
|
progressBar.Tick();
|
||||||
|
if (collection.Count == 0)
|
||||||
|
continue;
|
||||||
|
take = GetTake(configuration.LocationContainerDistanceTake, collection.Count);
|
||||||
|
isCounterPersonYear = IPersonBirthday.IsCounterPersonYear(new DateTime(collection[0].PersonKey).Year);
|
||||||
|
personKeyFormatted = IPersonBirthday.GetFormatted(configuration.PersonBirthdayFormat, collection[0].PersonKey);
|
||||||
|
displayDirectoryName = GetDisplayDirectoryName(readOnlyPersonKeyToPersonContainerCollection, readOnlyPersonKeyFormattedToPersonContainer, collection[0].PersonKey, personKeyFormatted);
|
||||||
|
directory = Path.Combine(a2PeopleContentDirectory, $"{ticks}-{configuration.LocationContainerDistanceTolerance.Value}", personKeyFormatted);
|
||||||
|
if (!Directory.Exists(directory))
|
||||||
|
_ = Directory.CreateDirectory(directory);
|
||||||
|
WriteVsCodeFiles(eDistanceContentDirectory, displayDirectoryName, directory);
|
||||||
|
relationContainers = distance.GetRelationContainers(configuration.FaceDistancePermyriad, configuration.LocationContainerDistanceTake, configuration.LocationContainerDistanceTolerance.Value, collection);
|
||||||
|
relationCollection = GetMappedRelationCollection(configuration.LocationContainerDebugDirectory, take, isCounterPersonYear, displayDirectoryName, relationContainers);
|
||||||
|
WriteFile(take, collection[0].PersonKey, isCounterPersonYear, personKeyFormatted, displayDirectoryName, directory, ticks, uri, relationCollection);
|
||||||
|
}
|
||||||
|
if (string.IsNullOrEmpty(configuration.LocationContainerDebugDirectory))
|
||||||
|
_ = IPath.DeleteEmptyDirectories(eDistanceContentDirectory);
|
||||||
|
else
|
||||||
|
AddDisplayDirectoryNames(configuration, eDistanceContentDirectory, readOnlyPersonKeyFormattedToPersonContainer, readOnlyPersonKeyToPersonContainerCollection, collections);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -15,39 +15,46 @@ taskTemplate: '^+^_${overdue ? ''^R'' : ''''}${name}^: ${relations ? (''\n^-^/^g
|
|||||||
## Backlog
|
## Backlog
|
||||||
|
|
||||||
- [use-photo-prism-to-map](tasks/use-photo-prism-to-map.md)
|
- [use-photo-prism-to-map](tasks/use-photo-prism-to-map.md)
|
||||||
- [google-timeline-for-geo](tasks/google-timeline-for-geo.md)
|
|
||||||
- [import-face-region-metadata](tasks/import-face-region-metadata.md)
|
- [import-face-region-metadata](tasks/import-face-region-metadata.md)
|
||||||
- [setup-syncthing-server](tasks/setup-syncthing-server.md)
|
- [setup-syncthing-server](tasks/setup-syncthing-server.md)
|
||||||
|
- [cluster-questioning](tasks/cluster-questioning.md)
|
||||||
- [photoview-in-docker-for-a-viewer-only](tasks/photoview-in-docker-for-a-viewer-only.md)
|
- [photoview-in-docker-for-a-viewer-only](tasks/photoview-in-docker-for-a-viewer-only.md)
|
||||||
- [image-size-distribution-per-exif-model-directory-when-no-model](tasks/image-size-distribution-per-exif-model-directory-when-no-model.md)
|
- [image-size-distribution-per-exif-model-directory-when-no-model](tasks/image-size-distribution-per-exif-model-directory-when-no-model.md)
|
||||||
- [import-know-faces-into-db](tasks/import-know-faces-into-db.md)
|
- [import-know-faces-into-db](tasks/import-know-faces-into-db.md)
|
||||||
- [skip-metadata-load-after-first-each-day](tasks/skip-metadata-load-after-first-each-day.md)
|
- [skip-metadata-load-after-first-each-day](tasks/skip-metadata-load-after-first-each-day.md)
|
||||||
- [determine-if-location-container-collection-is-needed-in-get-faces](tasks/determine-if-location-container-collection-is-needed-in-get-faces.md)
|
- [determine-if-location-container-collection-is-needed-in-get-faces](tasks/determine-if-location-container-collection-is-needed-in-get-faces.md)
|
||||||
- [cluster-questioning](tasks/cluster-questioning.md)
|
|
||||||
|
|
||||||
## Todo
|
## Todo
|
||||||
|
|
||||||
|
- [verify-camera-model-still-works](tasks/verify-camera-model-still-works.md)
|
||||||
|
- [run-limiting-on-days](tasks/run-limiting-on-days.md)
|
||||||
|
- [update-drag-and-drop-to-work-with-new-resize-location](tasks/update-drag-and-drop-to-work-with-new-resize-location.md)
|
||||||
|
- [triangle-over-person-in-full-image-for-some](tasks/triangle-over-person-in-full-image-for-some.md)
|
||||||
- [use-eyes-to-find-orientation](tasks/use-eyes-to-find-orientation.md)
|
- [use-eyes-to-find-orientation](tasks/use-eyes-to-find-orientation.md)
|
||||||
- [find-incorrectly-mapped-faces](tasks/find-incorrectly-mapped-faces.md)
|
|
||||||
- [nef-support](tasks/nef-support.md)
|
- [nef-support](tasks/nef-support.md)
|
||||||
- [set-date-taken-when-missing](tasks/set-date-taken-when-missing.md)
|
- [set-date-taken-when-missing](tasks/set-date-taken-when-missing.md)
|
||||||
- [triangle-over-person-in-full-image-for-some](tasks/triangle-over-person-in-full-image-for-some.md)
|
- [find-incorrectly-mapped-faces](tasks/find-incorrectly-mapped-faces.md)
|
||||||
|
- [google-timeline-for-geo](tasks/google-timeline-for-geo.md)
|
||||||
|
- [neo4j-db-import](tasks/neo4j-db-import.md)
|
||||||
|
|
||||||
## In Progress
|
## In Progress
|
||||||
|
|
||||||
|
- [name-some-from-638324064000000000-verify-manual-still-works](tasks/name-some-from-638324064000000000-verify-manual-still-works.md)
|
||||||
- [merge-kristy-files](tasks/merge-kristy-files.md)
|
- [merge-kristy-files](tasks/merge-kristy-files.md)
|
||||||
- [review-location-container-distance-tolerance](tasks/review-location-container-distance-tolerance.md)
|
|
||||||
- [can-re-map](tasks/can-re-map.md)
|
|
||||||
|
|
||||||
## Done
|
## Done
|
||||||
|
|
||||||
- [eof-error](tasks/eof-error.md)
|
- [eof-error](tasks/eof-error.md)
|
||||||
- [shrink-percent](tasks/shrink-percent.md)
|
- [shrink-percent](tasks/shrink-percent.md)
|
||||||
- [setup-photo-prism-again-in-wsl-docker](tasks/setup-photo-prism-again-in-wsl-docker.md)
|
- [setup-photo-prism-again-in-wsl-docker](tasks/setup-photo-prism-again-in-wsl-docker.md)
|
||||||
|
- [linked-to-9](tasks/linked-to-9.md)
|
||||||
- [fix-random-logic](tasks/fix-random-logic.md)
|
- [fix-random-logic](tasks/fix-random-logic.md)
|
||||||
|
- [filter-same-id](tasks/filter-same-id.md)
|
||||||
|
- [can-re-map](tasks/can-re-map.md)
|
||||||
- [move-copy-manual-files-to-get-display-directory-all-files](tasks/move-copy-manual-files-to-get-display-directory-all-files.md)
|
- [move-copy-manual-files-to-get-display-directory-all-files](tasks/move-copy-manual-files-to-get-display-directory-all-files.md)
|
||||||
- [rename-files-to-padded-number-string](tasks/rename-files-to-padded-number-string.md)
|
- [rename-files-to-padded-number-string](tasks/rename-files-to-padded-number-string.md)
|
||||||
- [reload-slideshow](tasks/reload-slideshow.md)
|
- [reload-slideshow](tasks/reload-slideshow.md)
|
||||||
|
- [review-location-container-distance-tolerance-needs-to-be-unique](tasks/review-location-container-distance-tolerance-needs-to-be-unique.md)
|
||||||
- [genealogical-data-communication-as-golden](tasks/genealogical-data-communication-as-golden.md)
|
- [genealogical-data-communication-as-golden](tasks/genealogical-data-communication-as-golden.md)
|
||||||
- [look-for-family-from-jlink-in-x-mapped](tasks/look-for-family-from-jlink-in-x-mapped.md)
|
- [look-for-family-from-jlink-in-x-mapped](tasks/look-for-family-from-jlink-in-x-mapped.md)
|
||||||
- [move-over-2023-california-pictures](tasks/move-over-2023-california-pictures.md)
|
- [move-over-2023-california-pictures](tasks/move-over-2023-california-pictures.md)
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
---
|
---
|
||||||
created: 2023-09-06T01:48:53.593Z
|
created: 2023-09-06T01:48:53.593Z
|
||||||
updated: 2023-09-06T01:48:53.588Z
|
updated: 2023-09-09T15:16:04.076Z
|
||||||
assigned: ""
|
assigned: ""
|
||||||
progress: 0
|
progress: 0
|
||||||
tags: []
|
tags: []
|
||||||
started: 2023-09-06T01:48:53.593Z
|
started: 2023-09-06T01:48:53.593Z
|
||||||
|
completed: 2023-09-09T15:16:04.076Z
|
||||||
---
|
---
|
||||||
|
|
||||||
# CanReMap
|
# CanReMap
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
---
|
---
|
||||||
created: "2023-07-17T06:39:53.148Z"
|
created: 2023-07-17T06:39:53.148Z
|
||||||
updated: "2023-07-21T21:36:44.190Z"
|
updated: 2023-09-09T06:30:37.280Z
|
||||||
assigned: ""
|
assigned: ""
|
||||||
progress: 0
|
progress: 0
|
||||||
type: "kanbn"
|
type: kanbn
|
||||||
|
started: 2023-09-09T06:30:28.358Z
|
||||||
---
|
---
|
||||||
|
|
||||||
# Cluster Questioning
|
# Cluster Questioning
|
||||||
|
11
Shared/.kanbn/tasks/filter-same-id.md
Normal file
11
Shared/.kanbn/tasks/filter-same-id.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
created: 2023-09-09T15:00:50.872Z
|
||||||
|
updated: 2023-09-09T15:37:00.549Z
|
||||||
|
assigned: ""
|
||||||
|
progress: 0
|
||||||
|
tags: []
|
||||||
|
started: 2023-09-09T15:00:50.872Z
|
||||||
|
completed: 2023-09-09T15:37:00.549Z
|
||||||
|
---
|
||||||
|
|
||||||
|
# Filter same id
|
@ -1,11 +1,11 @@
|
|||||||
---
|
---
|
||||||
created: "2023-07-21T18:26:38.901Z"
|
created: 2023-07-21T18:26:38.901Z
|
||||||
updated: "2023-07-21T18:26:38.902Z"
|
updated: 2023-09-09T06:30:12.385Z
|
||||||
assigned: ""
|
assigned: ""
|
||||||
progress: 0
|
progress: 0
|
||||||
tags: []
|
tags: []
|
||||||
status: '3-In Progress'
|
status: '3-In Progress'
|
||||||
type: "kanbn"
|
type: kanbn
|
||||||
---
|
---
|
||||||
|
|
||||||
# Find Incorrectly Mapped Faces
|
# Find Incorrectly Mapped Faces
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
created: "2023-07-21T18:26:38.903Z"
|
created: 2023-07-21T18:26:38.903Z
|
||||||
updated: "2023-07-21T18:26:38.903Z"
|
updated: 2023-09-09T06:31:23.591Z
|
||||||
assigned: ""
|
assigned: ""
|
||||||
progress: 0
|
progress: 0
|
||||||
status: "1-Backlog"
|
status: 1-Backlog
|
||||||
type: "kanbn"
|
type: kanbn
|
||||||
---
|
---
|
||||||
|
|
||||||
# Google Timeline for Geo
|
# Google Timeline for Geo
|
||||||
|
13
Shared/.kanbn/tasks/linked-to-9.md
Normal file
13
Shared/.kanbn/tasks/linked-to-9.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
created: 2023-09-09T15:36:54.752Z
|
||||||
|
updated: 2023-09-09T21:51:25.431Z
|
||||||
|
assigned: ""
|
||||||
|
progress: 0
|
||||||
|
tags: []
|
||||||
|
started: 2023-09-09T15:36:54.752Z
|
||||||
|
completed: 2023-09-09T21:51:25.432Z
|
||||||
|
---
|
||||||
|
|
||||||
|
# Linked to 9
|
||||||
|
|
||||||
|
Convert.ToChar(48 + keyValuePair.Value)
|
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
created: 2023-09-09T06:28:12.578Z
|
||||||
|
updated: 2023-09-09T21:51:56.736Z
|
||||||
|
assigned: ""
|
||||||
|
progress: 0
|
||||||
|
tags: []
|
||||||
|
started: 2023-09-08T00:00:00.000Z
|
||||||
|
---
|
||||||
|
|
||||||
|
# Name some from 638324064000000000 verify Manual still works
|
9
Shared/.kanbn/tasks/neo4j-db-import.md
Normal file
9
Shared/.kanbn/tasks/neo4j-db-import.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
created: 2023-09-09T06:33:28.795Z
|
||||||
|
updated: 2023-09-09T06:33:28.790Z
|
||||||
|
assigned: ""
|
||||||
|
progress: 0
|
||||||
|
tags: []
|
||||||
|
---
|
||||||
|
|
||||||
|
# Neo4j DB import
|
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
created: 2023-08-07T00:19:34.160Z
|
||||||
|
updated: 2023-09-09T15:12:01.657Z
|
||||||
|
assigned: ""
|
||||||
|
progress: 1
|
||||||
|
tags: []
|
||||||
|
started: 2023-08-05T00:00:00.000Z
|
||||||
|
completed: 2023-09-08T00:00:00.000Z
|
||||||
|
---
|
||||||
|
|
||||||
|
# ReviewLocationContainerDistanceTolerance needs to be unique
|
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
created: 2023-08-07T00:19:34.160Z
|
|
||||||
updated: 2023-08-07T05:46:42.946Z
|
|
||||||
assigned: ""
|
|
||||||
progress: 0
|
|
||||||
tags: []
|
|
||||||
started: 2023-08-06T00:00:00.000Z
|
|
||||||
---
|
|
||||||
|
|
||||||
# ReviewLocationContainerDistanceTolerance
|
|
10
Shared/.kanbn/tasks/run-limiting-on-days.md
Normal file
10
Shared/.kanbn/tasks/run-limiting-on-days.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
created: 2023-09-09T15:01:12.800Z
|
||||||
|
updated: 2023-09-09T21:51:53.090Z
|
||||||
|
assigned: ""
|
||||||
|
progress: 0
|
||||||
|
tags: []
|
||||||
|
started: 2023-09-09T15:01:12.800Z
|
||||||
|
---
|
||||||
|
|
||||||
|
# Run limiting on days
|
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
created: 2023-08-08T23:48:54.260Z
|
created: 2023-08-08T23:48:54.260Z
|
||||||
updated: 2023-08-08T23:48:54.257Z
|
updated: 2023-09-09T06:31:43.028Z
|
||||||
assigned: ""
|
assigned: ""
|
||||||
progress: 0
|
progress: 0
|
||||||
tags: []
|
tags: []
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
created: 2023-09-09T06:29:03.734Z
|
||||||
|
updated: 2023-09-09T06:31:45.781Z
|
||||||
|
assigned: ""
|
||||||
|
progress: 0
|
||||||
|
tags: []
|
||||||
|
---
|
||||||
|
|
||||||
|
# Update drag and drop to work with new resize location
|
10
Shared/.kanbn/tasks/verify-camera-model-still-works.md
Normal file
10
Shared/.kanbn/tasks/verify-camera-model-still-works.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
created: 2023-09-09T15:01:28.239Z
|
||||||
|
updated: 2023-09-09T21:51:54.599Z
|
||||||
|
assigned: ""
|
||||||
|
progress: 0
|
||||||
|
tags: []
|
||||||
|
started: 2023-09-09T15:01:28.239Z
|
||||||
|
---
|
||||||
|
|
||||||
|
# Verify camera model still works
|
@ -5,6 +5,6 @@ namespace View_by_Distance.Shared.Models.Methods;
|
|||||||
public interface IDistance<T>
|
public interface IDistance<T>
|
||||||
{
|
{
|
||||||
|
|
||||||
void SaveMappedForOutputResolutions(string locationContainerDebugDirectory, string a2PeopleContentDirectory, string eDistanceContentDirectory, float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer<T>> locationContainers, long personKey, bool isCounterPersonYear, string personKeyFormatted, string? displayDirectoryName);
|
ReadOnlyCollection<RelationContainer> GetRelationContainers(int faceDistancePermyriad, int locationContainerDistanceTake, float locationContainerDistanceTolerance, ReadOnlyCollection<LocationContainer<T>> locationContainers);
|
||||||
|
|
||||||
}
|
}
|
14
Shared/Models/Relation.cs
Normal file
14
Shared/Models/Relation.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
|
public record Relation(int DistancePermyriad, string File)
|
||||||
|
{
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
Shared/Models/RelationContainer.cs
Normal file
15
Shared/Models/RelationContainer.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace View_by_Distance.Shared.Models;
|
||||||
|
|
||||||
|
public record RelationContainer(FileHolder FileHolder, ReadOnlyCollection<Relation> RelationCollections)
|
||||||
|
{
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user