|
|
|
@ -936,7 +936,7 @@ public class MapLogic
|
|
|
|
|
return results;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SaveFilteredOriginalImagesFromJLinks(string[] jLinks, string a2PeopleSingletonDirectory, PersonContainer[] personContainers, Mapping[] mappingCollection, Dictionary<long, int> personKeyToCount, int totalNotMapped)
|
|
|
|
|
public void SaveFilteredOriginalImagesFromJLinks(string[] jLinks, PersonContainer[] personContainers, string a2PeopleSingletonDirectory, Mapping[] mappingCollection, Dictionary<long, int> personKeyToCount, int totalNotMapped)
|
|
|
|
|
{
|
|
|
|
|
if (_Configuration is null)
|
|
|
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
|
|
@ -1149,237 +1149,166 @@ public class MapLogic
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private DatabaseFileRoot GetDatabaseFileRoot()
|
|
|
|
|
private static JsonProperty[] GetJsonProperty(string fileName)
|
|
|
|
|
{
|
|
|
|
|
if (_Configuration is null)
|
|
|
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
|
|
|
string file = Path.Combine(_Configuration.PhotoPrismDirectory, "files.json");
|
|
|
|
|
string json = File.ReadAllText(file);
|
|
|
|
|
DatabaseFileRoot? databaseFileRoot = JsonSerializer.Deserialize<DatabaseFileRoot>(json);
|
|
|
|
|
if (databaseFileRoot is null)
|
|
|
|
|
throw new NullReferenceException(nameof(databaseFileRoot));
|
|
|
|
|
return databaseFileRoot;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Marker[] GetMarkers()
|
|
|
|
|
{
|
|
|
|
|
if (_Configuration is null)
|
|
|
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
|
|
|
string file = Path.Combine(_Configuration.PhotoPrismDirectory, "markers.json");
|
|
|
|
|
string json = File.ReadAllText(file);
|
|
|
|
|
Marker[]? markerRoot = JsonSerializer.Deserialize<Marker[]>(json);
|
|
|
|
|
if (markerRoot is null)
|
|
|
|
|
throw new NullReferenceException(nameof(markerRoot));
|
|
|
|
|
return markerRoot;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static Dictionary<string, DatabaseFile> Get(DatabaseFileRoot databaseFileRoot)
|
|
|
|
|
{
|
|
|
|
|
Dictionary<string, DatabaseFile> fileUidToFile = new();
|
|
|
|
|
for (int i = 0; i < databaseFileRoot.Files.Count; i++)
|
|
|
|
|
fileUidToFile.Add(databaseFileRoot.Files[i].FileUid, databaseFileRoot.Files[i]);
|
|
|
|
|
return fileUidToFile;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static MarkerWith GetMarkerWith(int? dlib, DatabaseFile databaseFile, Marker marker, int? count, double? percent, int? normalizedRectangle, long? personKey, string personKeyFormatted)
|
|
|
|
|
{
|
|
|
|
|
return new(marker.MarkerUid,
|
|
|
|
|
marker.FileUid,
|
|
|
|
|
marker.MarkerType,
|
|
|
|
|
marker.MarkerSrc,
|
|
|
|
|
marker.MarkerName,
|
|
|
|
|
marker.MarkerReview,
|
|
|
|
|
marker.MarkerInvalid,
|
|
|
|
|
marker.SubjUid,
|
|
|
|
|
marker.SubjSrc,
|
|
|
|
|
marker.FaceId,
|
|
|
|
|
marker.FaceDist,
|
|
|
|
|
marker.EmbeddingsJson,
|
|
|
|
|
marker.LandmarksJson,
|
|
|
|
|
marker.X,
|
|
|
|
|
marker.Y,
|
|
|
|
|
marker.W,
|
|
|
|
|
marker.H,
|
|
|
|
|
marker.Q,
|
|
|
|
|
marker.Size,
|
|
|
|
|
marker.Score,
|
|
|
|
|
marker.Thumb,
|
|
|
|
|
marker.MatchedAt,
|
|
|
|
|
marker.CreatedAt,
|
|
|
|
|
marker.UpdatedAt,
|
|
|
|
|
databaseFile.Id,
|
|
|
|
|
databaseFile.FileName,
|
|
|
|
|
dlib,
|
|
|
|
|
count,
|
|
|
|
|
percent,
|
|
|
|
|
normalizedRectangle,
|
|
|
|
|
personKey,
|
|
|
|
|
personKeyFormatted);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static Dictionary<string, List<Face>> GetFacesByFileName(List<Item> filteredItems)
|
|
|
|
|
{
|
|
|
|
|
Dictionary<string, List<Face>> results = new();
|
|
|
|
|
string key;
|
|
|
|
|
foreach (Item item in filteredItems)
|
|
|
|
|
{
|
|
|
|
|
foreach (Face face in item.Faces)
|
|
|
|
|
{
|
|
|
|
|
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null || face.Mapping is null)
|
|
|
|
|
continue;
|
|
|
|
|
key = Path.GetFileNameWithoutExtension(face.Mapping.MappingFromItem.RelativePath);
|
|
|
|
|
if (!results.ContainsKey(key))
|
|
|
|
|
results.Add(key, new());
|
|
|
|
|
results[key].Add(face);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
JsonProperty[] results;
|
|
|
|
|
string json = File.ReadAllText(fileName);
|
|
|
|
|
JsonElement? jsonElement = JsonSerializer.Deserialize<JsonElement>(json);
|
|
|
|
|
results = jsonElement.Value.EnumerateObject().ToArray();
|
|
|
|
|
return results;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void FindMatch(List<Item> filteredItems)
|
|
|
|
|
private static Marker[]? GetMarkers(string photoPrismDirectory)
|
|
|
|
|
{
|
|
|
|
|
if (_Configuration is null)
|
|
|
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
|
|
|
int? dlib;
|
|
|
|
|
double? percent;
|
|
|
|
|
long? personKey;
|
|
|
|
|
const int zero = 0;
|
|
|
|
|
List<Face>? matches;
|
|
|
|
|
MarkerWith markerWith;
|
|
|
|
|
int? normalizedRectangle;
|
|
|
|
|
string personKeyFormatted;
|
|
|
|
|
DatabaseFile? databaseFile;
|
|
|
|
|
PersonBirthday personBirthday;
|
|
|
|
|
Marker[] markers = GetMarkers();
|
|
|
|
|
string fileNameWithoutExtension;
|
|
|
|
|
PersonContainer[]? personContainers;
|
|
|
|
|
System.Drawing.Rectangle dlibRectangle;
|
|
|
|
|
System.Drawing.Rectangle prismRectangle;
|
|
|
|
|
System.Drawing.Rectangle intersectRectangle;
|
|
|
|
|
(Face Face, double Percent)[] sortedCollection;
|
|
|
|
|
List<(Face Face, double Percent)> collection = new();
|
|
|
|
|
DatabaseFileRoot databaseFileRoot = GetDatabaseFileRoot();
|
|
|
|
|
Dictionary<string, DatabaseFile> fileUidToFile = Get(databaseFileRoot);
|
|
|
|
|
Dictionary<int, PersonContainer[]>? normalizedRectangleToPersonContainers;
|
|
|
|
|
Dictionary<string, List<Face>> keyValuePairs = GetFacesByFileName(filteredItems);
|
|
|
|
|
foreach (Marker marker in markers)
|
|
|
|
|
{
|
|
|
|
|
dlib = null;
|
|
|
|
|
personKey = null;
|
|
|
|
|
collection.Clear();
|
|
|
|
|
normalizedRectangle = null;
|
|
|
|
|
personKeyFormatted = string.Empty;
|
|
|
|
|
normalizedRectangleToPersonContainers = null;
|
|
|
|
|
if (!fileUidToFile.TryGetValue(marker.FileUid, out databaseFile))
|
|
|
|
|
continue;
|
|
|
|
|
fileNameWithoutExtension = Path.GetFileNameWithoutExtension(Path.Combine("C:", databaseFile.FileName));
|
|
|
|
|
prismRectangle = new((int)(marker.X * databaseFile.FileWidth), (int)(marker.Y * databaseFile.FileHeight), (int)(marker.W * databaseFile.FileWidth), (int)(marker.H * databaseFile.FileHeight));
|
|
|
|
|
if (!keyValuePairs.TryGetValue(fileNameWithoutExtension, out matches) || !int.TryParse(fileNameWithoutExtension, out int id))
|
|
|
|
|
percent = null;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
dlib = id;
|
|
|
|
|
_ = _IdThenNormalizedRectangleToPersonContainers.TryGetValue(dlib.Value, out normalizedRectangleToPersonContainers);
|
|
|
|
|
foreach (Face face in matches)
|
|
|
|
|
{
|
|
|
|
|
if (face.Location is null || face.OutputResolution is null)
|
|
|
|
|
continue;
|
|
|
|
|
dlibRectangle = new(face.Location.Left, face.Location.Top, face.Location.Right - face.Location.Left, face.Location.Bottom - face.Location.Top);
|
|
|
|
|
intersectRectangle = System.Drawing.Rectangle.Intersect(prismRectangle, dlibRectangle);
|
|
|
|
|
if (intersectRectangle.Width == 0 || intersectRectangle.Height == 0)
|
|
|
|
|
continue;
|
|
|
|
|
percent = (double)intersectRectangle.Width * intersectRectangle.Height / (dlibRectangle.Width * dlibRectangle.Height);
|
|
|
|
|
if (percent < 0.000001)
|
|
|
|
|
continue;
|
|
|
|
|
collection.Add(new(face, percent.Value));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!collection.Any())
|
|
|
|
|
percent = null;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sortedCollection = collection.OrderByDescending(l => l.Percent).ToArray();
|
|
|
|
|
percent = sortedCollection[zero].Percent;
|
|
|
|
|
normalizedRectangle = sortedCollection[zero].Face.Mapping?.MappingFromLocation.NormalizedRectangle;
|
|
|
|
|
if (normalizedRectangleToPersonContainers is null || normalizedRectangle is null || !normalizedRectangleToPersonContainers.TryGetValue(normalizedRectangle.Value, out personContainers))
|
|
|
|
|
personContainers = null;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
foreach (PersonContainer personContainer in personContainers)
|
|
|
|
|
{
|
|
|
|
|
if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
|
|
|
|
|
continue;
|
|
|
|
|
personBirthday = personContainer.Birthdays[zero];
|
|
|
|
|
personKey = personBirthday.Value.Ticks;
|
|
|
|
|
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
markerWith = GetMarkerWith(dlib, databaseFile, marker, collection.Count, percent, normalizedRectangle, personKey, personKeyFormatted);
|
|
|
|
|
string json = JsonSerializer.Serialize(markerWith, new JsonSerializerOptions() { WriteIndented = true });
|
|
|
|
|
if (IPath.WriteAllText(Path.Combine(_Configuration.PhotoPrismDirectory, "With", $"{marker.MarkerUid}.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true))
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
Marker[]? results;
|
|
|
|
|
string file = Path.Combine(photoPrismDirectory, "markers.json");
|
|
|
|
|
JsonProperty[] jsonProperties = GetJsonProperty(file);
|
|
|
|
|
results = JsonSerializer.Deserialize<Marker[]>(jsonProperties[1].Value);
|
|
|
|
|
return results;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SaveMarkers()
|
|
|
|
|
public static void SaveMarkers(string photoPrismDirectory)
|
|
|
|
|
{
|
|
|
|
|
if (_Configuration is null)
|
|
|
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
|
|
|
double[]? encoding;
|
|
|
|
|
string file = Path.Combine(_Configuration.PhotoPrismDirectory, "markers.json");
|
|
|
|
|
string json = File.ReadAllText(file);
|
|
|
|
|
Marker[]? markers = JsonSerializer.Deserialize<Marker[]>(json);
|
|
|
|
|
if (string.IsNullOrEmpty(photoPrismDirectory))
|
|
|
|
|
throw new Exception();
|
|
|
|
|
// double[]? encoding;
|
|
|
|
|
// Marker[]? markers = GetMarkers(photoPrismDirectory);
|
|
|
|
|
// if (markers is null)
|
|
|
|
|
// throw new NullReferenceException(nameof(markers));
|
|
|
|
|
// foreach (Marker marker in markers)
|
|
|
|
|
// {
|
|
|
|
|
// encoding = JsonSerializer.Deserialize<double[]>(marker.EmbeddingsJson[1..^1]);
|
|
|
|
|
// File.WriteAllText(Path.Combine(photoPrismDirectory, "EmbeddingsJson", $"{marker.MarkerUid}.json"), marker.EmbeddingsJson);
|
|
|
|
|
// if (encoding is null)
|
|
|
|
|
// continue;
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static Dictionary<string, List<Marker>> GetFileUIdToMarkers(string photoPrismDirectory)
|
|
|
|
|
{
|
|
|
|
|
Dictionary<string, List<Marker>> results = new();
|
|
|
|
|
Marker[]? markers = GetMarkers(photoPrismDirectory);
|
|
|
|
|
if (markers is null)
|
|
|
|
|
throw new NullReferenceException(nameof(markers));
|
|
|
|
|
foreach (Marker marker in markers)
|
|
|
|
|
{
|
|
|
|
|
encoding = JsonSerializer.Deserialize<double[]>(marker.EmbeddingsJson[1..^1]);
|
|
|
|
|
File.WriteAllText(Path.Combine(_Configuration.PhotoPrismDirectory, "EmbeddingsJson", $"{marker.MarkerUid}.json"), marker.EmbeddingsJson);
|
|
|
|
|
if (encoding is null)
|
|
|
|
|
continue;
|
|
|
|
|
if (!results.ContainsKey(marker.FileUid))
|
|
|
|
|
results.Add(marker.FileUid, new());
|
|
|
|
|
results[marker.FileUid].Add(marker);
|
|
|
|
|
}
|
|
|
|
|
return results;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void LoadMatches()
|
|
|
|
|
private static DatabaseFile[]? GetDatabaseFiles(string photoPrismDirectory)
|
|
|
|
|
{
|
|
|
|
|
DatabaseFile[]? results;
|
|
|
|
|
string file = Path.Combine(photoPrismDirectory, "files.json");
|
|
|
|
|
JsonProperty[] jsonProperties = GetJsonProperty(file);
|
|
|
|
|
results = JsonSerializer.Deserialize<DatabaseFile[]>(jsonProperties[1].Value);
|
|
|
|
|
return results;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Dictionary<string, List<MappingFromPhotoPrism>> GetFileNameToCollection(string photoPrismDirectory)
|
|
|
|
|
{
|
|
|
|
|
Dictionary<string, List<MappingFromPhotoPrism>> results = new();
|
|
|
|
|
List<Marker>? makers;
|
|
|
|
|
MappingFromPhotoPrism mappingFromPhotoPrism;
|
|
|
|
|
List<MappingFromPhotoPrism>? mappingFromPhotoPrismCollection;
|
|
|
|
|
DatabaseFile[]? databaseFiles = GetDatabaseFiles(photoPrismDirectory);
|
|
|
|
|
if (databaseFiles is null)
|
|
|
|
|
throw new NullReferenceException(nameof(databaseFiles));
|
|
|
|
|
Dictionary<string, List<Marker>> fileUIdToMarkers = GetFileUIdToMarkers(photoPrismDirectory);
|
|
|
|
|
foreach (DatabaseFile databaseFile in databaseFiles)
|
|
|
|
|
{
|
|
|
|
|
if (!results.TryGetValue(databaseFile.FileName, out mappingFromPhotoPrismCollection))
|
|
|
|
|
{
|
|
|
|
|
results.Add(databaseFile.FileName, new());
|
|
|
|
|
if (!results.TryGetValue(databaseFile.FileName, out mappingFromPhotoPrismCollection))
|
|
|
|
|
throw new Exception();
|
|
|
|
|
}
|
|
|
|
|
if (!fileUIdToMarkers.TryGetValue(databaseFile.FileUid, out makers))
|
|
|
|
|
mappingFromPhotoPrism = new(databaseFile, new());
|
|
|
|
|
else
|
|
|
|
|
mappingFromPhotoPrism = new(databaseFile, makers);
|
|
|
|
|
mappingFromPhotoPrismCollection.Add(mappingFromPhotoPrism);
|
|
|
|
|
}
|
|
|
|
|
return results;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void WriteMatches(long ticks, Face[] distinctFilteredFaces)
|
|
|
|
|
{
|
|
|
|
|
if (_Configuration is null)
|
|
|
|
|
throw new NullReferenceException(nameof(_Configuration));
|
|
|
|
|
string json;
|
|
|
|
|
MarkerWith? markerWith;
|
|
|
|
|
List<MarkerWith> collection = new();
|
|
|
|
|
long? personKey;
|
|
|
|
|
const int zero = 0;
|
|
|
|
|
int? normalizedRectangle;
|
|
|
|
|
string personKeyFormatted;
|
|
|
|
|
List<string> subjects = new();
|
|
|
|
|
PersonBirthday personBirthday;
|
|
|
|
|
string personDisplayDirectoryName;
|
|
|
|
|
StringBuilder stringBuilder = new();
|
|
|
|
|
List<(int Count, MarkerWith MarkerWith)> countCollection = new();
|
|
|
|
|
List<(double Percent, MarkerWith MarkerWith)> percentCollection = new();
|
|
|
|
|
string[] files = Directory.GetFiles(Path.Combine(_Configuration.PhotoPrismDirectory, "With"), "*.json", SearchOption.TopDirectoryOnly);
|
|
|
|
|
foreach (string file in files)
|
|
|
|
|
PersonContainer[]? personContainers;
|
|
|
|
|
System.Drawing.Rectangle dlibRectangle;
|
|
|
|
|
System.Drawing.Rectangle? prismRectangle;
|
|
|
|
|
System.Drawing.Rectangle intersectRectangle;
|
|
|
|
|
Dictionary<int, PersonContainer[]>? normalizedRectangleToPersonContainers;
|
|
|
|
|
(MappingFromPhotoPrism MappingFromPhotoPrism, Marker Marker, double Percent)[] sortedCollection;
|
|
|
|
|
List<(MappingFromPhotoPrism MappingFromPhotoPrism, Marker Marker, double Percent)> collection = new();
|
|
|
|
|
foreach (Face face in distinctFilteredFaces)
|
|
|
|
|
{
|
|
|
|
|
json = File.ReadAllText(file);
|
|
|
|
|
markerWith = JsonSerializer.Deserialize<MarkerWith>(json);
|
|
|
|
|
if (markerWith is null || markerWith.DlibId is null)
|
|
|
|
|
collection.Clear();
|
|
|
|
|
normalizedRectangle = face.Mapping?.MappingFromLocation.NormalizedRectangle;
|
|
|
|
|
if (normalizedRectangle is null)
|
|
|
|
|
continue;
|
|
|
|
|
collection.Add(markerWith);
|
|
|
|
|
if (markerWith.Count is null || markerWith.Count.Value == 0)
|
|
|
|
|
if (face.FaceEncoding is null || face.Location is null || face.OutputResolution is null || face.Mapping is null)
|
|
|
|
|
continue;
|
|
|
|
|
countCollection.Add(new(markerWith.Count.Value, markerWith));
|
|
|
|
|
if (markerWith.Percent is null)
|
|
|
|
|
if (face.Mapping.MappingFromPhotoPrismCollection is null)
|
|
|
|
|
continue;
|
|
|
|
|
percentCollection.Add(new(markerWith.Percent.Value, markerWith));
|
|
|
|
|
if (string.IsNullOrEmpty(markerWith.PersonKeyFormatted))
|
|
|
|
|
_ = _IdThenNormalizedRectangleToPersonContainers.TryGetValue(face.Mapping.MappingFromItem.Id, out normalizedRectangleToPersonContainers);
|
|
|
|
|
if (normalizedRectangleToPersonContainers is null || !normalizedRectangleToPersonContainers.TryGetValue(normalizedRectangle.Value, out personContainers))
|
|
|
|
|
continue;
|
|
|
|
|
_ = stringBuilder.
|
|
|
|
|
Append("update `markers` set subj_src = 'manual' marker_name = '").
|
|
|
|
|
Append(markerWith.PersonKeyFormatted).
|
|
|
|
|
Append("' where marker_uid = '").
|
|
|
|
|
Append(markerWith.MarkerUid).
|
|
|
|
|
AppendLine("';");
|
|
|
|
|
dlibRectangle = new(face.Location.Left, face.Location.Top, face.Location.Right - face.Location.Left, face.Location.Bottom - face.Location.Top);
|
|
|
|
|
foreach (MappingFromPhotoPrism mappingFromPhotoPrism in face.Mapping.MappingFromPhotoPrismCollection)
|
|
|
|
|
{
|
|
|
|
|
foreach (Marker marker in mappingFromPhotoPrism.Markers)
|
|
|
|
|
{
|
|
|
|
|
prismRectangle = ILocation.GetRectangle(face.OutputResolution, mappingFromPhotoPrism.DatabaseFile, marker);
|
|
|
|
|
if (prismRectangle is null)
|
|
|
|
|
continue;
|
|
|
|
|
intersectRectangle = System.Drawing.Rectangle.Intersect(dlibRectangle, prismRectangle.Value);
|
|
|
|
|
if (intersectRectangle.Width == 0 || intersectRectangle.Height == 0)
|
|
|
|
|
continue;
|
|
|
|
|
double percent = (double)intersectRectangle.Width * intersectRectangle.Height / (dlibRectangle.Width * dlibRectangle.Height);
|
|
|
|
|
if (percent < 0.000001)
|
|
|
|
|
continue;
|
|
|
|
|
collection.Add(new(mappingFromPhotoPrism, marker, percent));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!collection.Any())
|
|
|
|
|
continue;
|
|
|
|
|
sortedCollection = collection.OrderByDescending(l => l.Percent).ToArray();
|
|
|
|
|
foreach ((MappingFromPhotoPrism mappingFromPhotoPrism, Marker marker, double percent) in sortedCollection)
|
|
|
|
|
{
|
|
|
|
|
foreach (PersonContainer personContainer in personContainers)
|
|
|
|
|
{
|
|
|
|
|
if (personContainer.Key is null || personContainer.Birthdays is null || !personContainer.Birthdays.Any())
|
|
|
|
|
continue;
|
|
|
|
|
personBirthday = personContainer.Birthdays[zero];
|
|
|
|
|
personKey = personBirthday.Value.Ticks;
|
|
|
|
|
personDisplayDirectoryName = personContainer.DisplayDirectoryName;
|
|
|
|
|
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday);
|
|
|
|
|
subjects.Add($"update `subjects` set subj_alias = '{personKeyFormatted}' where subj_name = '{personDisplayDirectoryName}';");
|
|
|
|
|
_ = stringBuilder.
|
|
|
|
|
Append("update `markers` set subj_src = 'manual', marker_name = '").
|
|
|
|
|
Append(personDisplayDirectoryName).
|
|
|
|
|
Append("' where marker_uid = '").
|
|
|
|
|
Append(marker.MarkerUid).
|
|
|
|
|
AppendLine("';");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
(int, MarkerWith)[] countSorted = countCollection.OrderByDescending(l => l.Count).ToArray();
|
|
|
|
|
(double, MarkerWith)[] percentSorted = percentCollection.OrderBy(l => l.Percent).ToArray();
|
|
|
|
|
if (collection.Any())
|
|
|
|
|
{ }
|
|
|
|
|
File.WriteAllText(Path.Combine(_Configuration.PhotoPrismDirectory, "marker_name_update.sql"), stringBuilder.ToString());
|
|
|
|
|
File.WriteAllLines(Path.Combine(_Configuration.PhotoPrismDirectory, $"{ticks}-subject_alias_update.sql"), subjects.Distinct());
|
|
|
|
|
File.WriteAllText(Path.Combine(_Configuration.PhotoPrismDirectory, $"{ticks}-marker_name_update.sql"), stringBuilder.ToString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Dictionary<int, Dictionary<int, PersonContainer[]>> GetMissing(Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping)
|
|
|
|
|