Individually with Explorer

This commit is contained in:
Mike Phares 2023-04-10 09:10:20 -07:00
parent da2c5b5e78
commit dd2c51a093
8 changed files with 231 additions and 125 deletions

View File

@ -765,9 +765,8 @@ public partial class DlibDotNet
E_Distance.SaveFaceDistances(_Configuration.PropertyConfiguration, sortingContainers); E_Distance.SaveFaceDistances(_Configuration.PropertyConfiguration, sortingContainers);
if (filteredFaceDistanceContainers.Length > 0) if (filteredFaceDistanceContainers.Length > 0)
{ {
bool forIndividually = true; int updated = mapLogic.UpdateFromSortingContainers(_Configuration.SaveIndividually, distanceLimits, sortingContainers);
int updated = mapLogic.UpdateFromSortingContainers(distanceLimits, sortingContainers); List<SaveContainer> saveContainers = mapLogic.GetSaveContainers(_Configuration.SaveIndividually, dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, mappingCollection, idToNormalizedRectangleToMapping, useFiltersCounter, sortingContainers.Any());
List<SaveContainer> saveContainers = mapLogic.GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, mappingCollection, idToNormalizedRectangleToMapping, useFiltersCounter, forIndividually, sortingContainers.Any());
mapLogic.SaveContainers(filteredFaceDistanceContainers.Length, updated, saveContainers); mapLogic.SaveContainers(filteredFaceDistanceContainers.Length, updated, saveContainers);
} }
} }
@ -1058,7 +1057,7 @@ public partial class DlibDotNet
fPhotoPrismContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(F_PhotoPrism), "()"); fPhotoPrismContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(F_PhotoPrism), "()");
fPhotoPrismSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(F_PhotoPrism), "{}"); fPhotoPrismSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(F_PhotoPrism), "{}");
propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse, aResultsFullGroupDirectory); propertyLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Resize.FileNameExtension, _Configuration.Reverse, aResultsFullGroupDirectory);
MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _PersonContainers, ticks, a2PeopleSingletonDirectory, eDistanceContentDirectory); MapLogic mapLogic = new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _Configuration.SaveIndividually, _MapConfiguration, _PersonContainers, ticks, a2PeopleSingletonDirectory, eDistanceContentDirectory);
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds); int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
string message = $") Building Container(s) - {totalSeconds} total second(s)"; string message = $") Building Container(s) - {totalSeconds} total second(s)";
ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true }; ProgressBarOptions options = new() { ProgressCharacter = '─', ProgressBarOnBottom = true, DisableBottomPercentage = true };

View File

@ -72,6 +72,7 @@ public class Configuration
[Display(Name = "Save Full Year Of Random Files"), Required] public bool? SaveFullYearOfRandomFiles { get; set; } [Display(Name = "Save Full Year Of Random Files"), Required] public bool? SaveFullYearOfRandomFiles { get; set; }
[Display(Name = "Save Mapped"), Required] public string[] SaveMappedForOutputResolutions { get; set; } [Display(Name = "Save Mapped"), Required] public string[] SaveMappedForOutputResolutions { get; set; }
[Display(Name = "Save Resized Images by Person Key Formatted"), Required] public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { get; set; } [Display(Name = "Save Resized Images by Person Key Formatted"), Required] public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { get; set; }
[Display(Name = "Save For Individually"), Required] public bool? SaveIndividually { get; set; }
[Display(Name = "Save Random For Output Resolutions"), Required] public string[] SaveRandomForOutputResolutions { get; set; } [Display(Name = "Save Random For Output Resolutions"), Required] public string[] SaveRandomForOutputResolutions { get; set; }
[Display(Name = "Save Resized Subfiles"), Required] public bool? SaveResizedSubfiles { get; set; } [Display(Name = "Save Resized Subfiles"), Required] public bool? SaveResizedSubfiles { get; set; }
[Display(Name = "Save Shortcuts"), Required] public string[] SaveShortcutsForOutputResolutions { get; set; } [Display(Name = "Save Shortcuts"), Required] public string[] SaveShortcutsForOutputResolutions { get; set; }
@ -203,6 +204,8 @@ public class Configuration
throw new NullReferenceException(nameof(configuration.SaveFullYearOfRandomFiles)); throw new NullReferenceException(nameof(configuration.SaveFullYearOfRandomFiles));
configuration.SaveMappedForOutputResolutions ??= Array.Empty<string>(); configuration.SaveMappedForOutputResolutions ??= Array.Empty<string>();
configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions ??= Array.Empty<string>(); configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions ??= Array.Empty<string>();
if (configuration.SaveIndividually is null)
throw new NullReferenceException(nameof(configuration.SaveIndividually));
configuration.SaveRandomForOutputResolutions ??= Array.Empty<string>(); configuration.SaveRandomForOutputResolutions ??= Array.Empty<string>();
if (configuration.SaveResizedSubfiles is null) if (configuration.SaveResizedSubfiles is null)
throw new NullReferenceException(nameof(configuration.SaveResizedSubfiles)); throw new NullReferenceException(nameof(configuration.SaveResizedSubfiles));
@ -284,6 +287,7 @@ public class Configuration
configuration.SaveFaceDistancesForOutputResolutions, configuration.SaveFaceDistancesForOutputResolutions,
configuration.SaveFaceLandmarkForOutputResolutions, configuration.SaveFaceLandmarkForOutputResolutions,
configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions, configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions,
configuration.SaveIndividually.Value,
configuration.SaveFullYearOfRandomFiles.Value, configuration.SaveFullYearOfRandomFiles.Value,
configuration.SaveMappedForOutputResolutions, configuration.SaveMappedForOutputResolutions,
configuration.SaveRandomForOutputResolutions, configuration.SaveRandomForOutputResolutions,

View File

@ -66,6 +66,7 @@ public class Configuration
public string[] SaveFaceDistancesForOutputResolutions { init; get; } public string[] SaveFaceDistancesForOutputResolutions { init; get; }
public string[] SaveFaceLandmarkForOutputResolutions { init; get; } public string[] SaveFaceLandmarkForOutputResolutions { init; get; }
public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { init; get; } public string[] SaveFilteredOriginalImagesFromJLinksForOutputResolutions { init; get; }
public bool SaveIndividually { init; get; }
public bool SaveFullYearOfRandomFiles { init; get; } public bool SaveFullYearOfRandomFiles { init; get; }
public string[] SaveMappedForOutputResolutions { init; get; } public string[] SaveMappedForOutputResolutions { init; get; }
public string[] SaveRandomForOutputResolutions { init; get; } public string[] SaveRandomForOutputResolutions { init; get; }
@ -141,6 +142,7 @@ public class Configuration
string[] saveFaceDistancesForOutputResolutions, string[] saveFaceDistancesForOutputResolutions,
string[] saveFaceLandmarkForOutputResolutions, string[] saveFaceLandmarkForOutputResolutions,
string[] saveFilteredOriginalImagesFromJLinksForOutputResolutions, string[] saveFilteredOriginalImagesFromJLinksForOutputResolutions,
bool saveIndividually,
bool saveFullYearOfRandomFiles, bool saveFullYearOfRandomFiles,
string[] saveMappedForOutputResolutions, string[] saveMappedForOutputResolutions,
string[] saveRandomForOutputResolutions, string[] saveRandomForOutputResolutions,
@ -208,17 +210,18 @@ public class Configuration
PropertiesChangedForMetadata = propertiesChangedForMetadata; PropertiesChangedForMetadata = propertiesChangedForMetadata;
PropertiesChangedForResize = propertiesChangedForResize; PropertiesChangedForResize = propertiesChangedForResize;
RangeDaysDeltaTolerance = rangeDaysDeltaTolerance; RangeDaysDeltaTolerance = rangeDaysDeltaTolerance;
RangeDistanceTolerance = rangeDistanceTolerance;
RangeFaceAreaTolerance = rangeFaceAreaPermyriadTolerance; RangeFaceAreaTolerance = rangeFaceAreaPermyriadTolerance;
RangeFaceConfidence = rangeFaceConfidence; RangeFaceConfidence = rangeFaceConfidence;
RangeDistanceTolerance = rangeDistanceTolerance;
Reverse = reverse; Reverse = reverse;
SaveFaceDistancesForOutputResolutions = saveFaceDistancesForOutputResolutions; SaveFaceDistancesForOutputResolutions = saveFaceDistancesForOutputResolutions;
SaveFaceLandmarkForOutputResolutions = saveFaceLandmarkForOutputResolutions; SaveFaceLandmarkForOutputResolutions = saveFaceLandmarkForOutputResolutions;
SaveFilteredOriginalImagesFromJLinksForOutputResolutions = saveFilteredOriginalImagesFromJLinksForOutputResolutions;
SaveIndividually = saveIndividually;
SaveFullYearOfRandomFiles = saveFullYearOfRandomFiles; SaveFullYearOfRandomFiles = saveFullYearOfRandomFiles;
SaveMappedForOutputResolutions = saveMappedForOutputResolutions; SaveMappedForOutputResolutions = saveMappedForOutputResolutions;
SaveFilteredOriginalImagesFromJLinksForOutputResolutions = saveFilteredOriginalImagesFromJLinksForOutputResolutions;
SaveResizedSubfiles = saveResizedSubfiles;
SaveRandomForOutputResolutions = saveRandomForOutputResolutions; SaveRandomForOutputResolutions = saveRandomForOutputResolutions;
SaveResizedSubfiles = saveResizedSubfiles;
SaveShortcutsForOutputResolutions = saveShortcutsForOutputResolutions; SaveShortcutsForOutputResolutions = saveShortcutsForOutputResolutions;
SaveSortingWithoutPerson = saveSortingWithoutPerson; SaveSortingWithoutPerson = saveSortingWithoutPerson;
SkipNotSkipDirectories = skipNotSkipDirectories; SkipNotSkipDirectories = skipNotSkipDirectories;

View File

@ -29,6 +29,7 @@
"xxxRootDirectory": "D:/2) Images B/Not-Copy-Copy-9b89679", "xxxRootDirectory": "D:/2) Images B/Not-Copy-Copy-9b89679",
"RootDirectory": "D:/1) Images A/Images-9b89679", "RootDirectory": "D:/1) Images A/Images-9b89679",
"xxxxxRootDirectory": "D:/1) Images A/Images-9b89679/Facebook/2023.2 Facebook", "xxxxxRootDirectory": "D:/1) Images A/Images-9b89679/Facebook/2023.2 Facebook",
"SaveIndividually": true,
"SaveSortingWithoutPerson": true, "SaveSortingWithoutPerson": true,
"SkipOlderThanDays": null, "SkipOlderThanDays": null,
"xSkipOlderThanDays": 2200, "xSkipOlderThanDays": 2200,

View File

@ -106,6 +106,7 @@
"ResultSingleton": "{}", "ResultSingleton": "{}",
"Reverse": false, "Reverse": false,
"RootDirectory": "D:/Images", "RootDirectory": "D:/Images",
"SaveIndividually": false,
"SaveFullYearOfRandomFiles": true, "SaveFullYearOfRandomFiles": true,
"SaveResizedSubFiles": true, "SaveResizedSubFiles": true,
"SaveSortingWithoutPerson": false, "SaveSortingWithoutPerson": false,

View File

@ -28,7 +28,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
private readonly string _EDistanceContentTicksDirectory; private readonly string _EDistanceContentTicksDirectory;
private readonly Shared.Models.Properties.IPropertyConfiguration _PropertyConfiguration; private readonly Shared.Models.Properties.IPropertyConfiguration _PropertyConfiguration;
public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, Configuration? configuration, PersonContainer[] personContainers, long ticks, string a2PeopleSingletonDirectory, string eDistanceContentDirectory) public MapLogic(int maxDegreeOfParallelism, Shared.Models.Properties.IPropertyConfiguration propertyConfiguration, bool saveIndividually, Configuration? configuration, PersonContainer[] personContainers, long ticks, string a2PeopleSingletonDirectory, string eDistanceContentDirectory)
{ {
_Ticks = ticks; _Ticks = ticks;
_Configuration = configuration; _Configuration = configuration;
@ -51,15 +51,16 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
string? rootDirectoryParent = Path.GetDirectoryName(propertyConfiguration.RootDirectory); string? rootDirectoryParent = Path.GetDirectoryName(propertyConfiguration.RootDirectory);
string eDistanceContentTicksDirectory = Path.Combine(eDistanceContentDirectory, $"({ticks})"); string eDistanceContentTicksDirectory = Path.Combine(eDistanceContentDirectory, $"({ticks})");
Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedRectangleToPersonContainers = new(); Dictionary<int, Dictionary<int, PersonContainer[]>> idThenNormalizedRectangleToPersonContainers = new();
for (int i = 1; i < 5; i++) if (!saveIndividually)
{
for (int i = 1; i < 5; i++)
_ = IPath.DeleteEmptyDirectories(eDistanceContentDirectory);
_ = IPath.DeleteEmptyDirectories(eDistanceContentDirectory); _ = IPath.DeleteEmptyDirectories(eDistanceContentDirectory);
_ = IPath.DeleteEmptyDirectories(eDistanceContentDirectory); }
if (string.IsNullOrEmpty(rootDirectoryParent)) if (string.IsNullOrEmpty(rootDirectoryParent))
throw new NullReferenceException(nameof(rootDirectoryParent)); throw new NullReferenceException(nameof(rootDirectoryParent));
if (!Directory.Exists(eDistanceContentDirectory)) if (!Directory.Exists(eDistanceContentDirectory))
_ = Directory.CreateDirectory(eDistanceContentDirectory); _ = Directory.CreateDirectory(eDistanceContentDirectory);
if (!Directory.Exists(eDistanceContentTicksDirectory))
_ = Directory.CreateDirectory(eDistanceContentTicksDirectory);
if (configuration is not null) if (configuration is not null)
{ {
List<PersonContainer> personContainerCollection = new(personContainers); List<PersonContainer> personContainerCollection = new(personContainers);
@ -335,40 +336,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
return result; return result;
} }
private static (string, bool, bool) Get(int? useFiltersCounter, bool forIndividually, bool sortingContainersAny, string forceSingleImageHumanized, Mapping mapping) private string GetDirectory(bool saveIndividually, int padLeft, string? segmentC, string by, MappingFromItem mappingFromItem, SortingContainer sortingContainer)
{
string by;
bool isByMapping;
bool isBySorting;
if (mapping.By is null)
{
isByMapping = false;
isBySorting = !sortingContainersAny;
by = $"{nameof(Shared.Models.Stateless.IMapLogic.Mapping)}Null";
}
else
{
isByMapping = mapping.By == Shared.Models.Stateless.IMapLogic.Mapping;
isBySorting = mapping.By == Shared.Models.Stateless.IMapLogic.Sorting;
if (isBySorting && mapping.MappingFromPerson is null)
by = forIndividually ? nameof(Shared.Models.Stateless.IMapLogic.Individually) : $"{nameof(Shared.Models.Stateless.IMapLogic.Sorting)} Without Person";
else if (isBySorting && useFiltersCounter.HasValue)
by = $"{nameof(Shared.Models.Stateless.IMapLogic.Sorting)} Modified Filters - {useFiltersCounter.Value}";
else
{
by = mapping.By.Value switch
{
Shared.Models.Stateless.IMapLogic.Mapping => nameof(Shared.Models.Stateless.IMapLogic.Mapping),
Shared.Models.Stateless.IMapLogic.Sorting => forIndividually ? nameof(Shared.Models.Stateless.IMapLogic.Individually) : nameof(Shared.Models.Stateless.IMapLogic.Sorting),
Shared.Models.Stateless.IMapLogic.ForceSingleImage => forceSingleImageHumanized,
_ => throw new NotImplementedException()
};
}
}
return new(by, isByMapping, isBySorting);
}
private string GetDirectory(string by, MappingFromItem mappingFromItem, SortingContainer sortingContainer)
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
@ -387,19 +355,23 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
personBirthday = personContainer.Birthdays[zero]; personBirthday = personContainer.Birthdays[zero];
mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, mappingFromItem); mappingSegmentB = Stateless.MapLogic.GetMappingSegmentB(_Ticks, personBirthday, personContainer.ApproximateYears, mappingFromItem);
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday); personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, personBirthday);
result = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, mappingSegmentB); if (!saveIndividually || segmentC is null)
result = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, mappingSegmentB);
else
result = Path.Combine(_EDistanceContentTicksDirectory, by, segmentC.PadLeft(padLeft, '0'), personKeyFormatted, mappingSegmentB);
_NotMappedPersonContainers.RemoveAt(i); _NotMappedPersonContainers.RemoveAt(i);
break; break;
} }
return result; return result;
} }
private List<SaveContainer> GetSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, Mapping[] mappingCollection, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping, Dictionary<long, List<int>> personKeyToIds, int? useFiltersCounter, bool saveMapped, bool forIndividually, bool sortingContainersAny) private List<SaveContainer> GetSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, Mapping[] mappingCollection, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping, Dictionary<long, List<int>> personKeyToIds, int? useFiltersCounter, bool saveMapped, bool saveIndividually, bool sortingContainersAny)
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
List<SaveContainer> results = new(); List<SaveContainer> results = new();
string by; string by;
long ticks;
List<int>? ids; List<int>? ids;
long personKey; long personKey;
bool isByMapping; bool isByMapping;
@ -420,6 +392,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
FileHolder hiddenFaceFileHolder; FileHolder hiddenFaceFileHolder;
string? facePartsContentCollectionFile; string? facePartsContentCollectionFile;
Dictionary<int, Mapping>? normalizedRectangleToMapping; Dictionary<int, Mapping>? normalizedRectangleToMapping;
int padLeft = _Configuration.FaceDistancePermyriad.ToString().Length;
string forceSingleImageHumanized = nameof(Shared.Models.Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title); string forceSingleImageHumanized = nameof(Shared.Models.Stateless.IMapLogic.ForceSingleImage).Humanize(LetterCasing.Title);
foreach (Mapping mapping in mappingCollection) foreach (Mapping mapping in mappingCollection)
{ {
@ -430,7 +403,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
throw new NotSupportedException(); throw new NotSupportedException();
if (mapping.MappingFromFilter.InSkipCollection is not null && mapping.MappingFromFilter.InSkipCollection.Value) if (mapping.MappingFromFilter.InSkipCollection is not null && mapping.MappingFromFilter.InSkipCollection.Value)
continue; continue;
(by, isByMapping, isBySorting) = Get(useFiltersCounter, forIndividually, sortingContainersAny, forceSingleImageHumanized, mapping); (by, isByMapping, isBySorting) = Stateless.MapLogic.Get(useFiltersCounter, saveIndividually, sortingContainersAny, forceSingleImageHumanized, mapping);
if (isByMapping && !saveMapped) if (isByMapping && !saveMapped)
continue; continue;
if (mapping.MappingFromPerson is null) if (mapping.MappingFromPerson is null)
@ -449,10 +422,14 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
continue; continue;
if (distinct.Contains(mapping.SortingContainer.Sorting.Id)) if (distinct.Contains(mapping.SortingContainer.Sorting.Id))
continue; continue;
directory = GetDirectory(by, mapping.MappingFromItem, mapping.SortingContainer); ticks = DateTime.Now.Ticks;
personDirectory = Path.Combine(directory, $"Z]{DateTime.Now.Ticks}"); directory = GetDirectory(saveIndividually, padLeft, mapping.SegmentC, by, mapping.MappingFromItem, mapping.SortingContainer);
if (forIndividually) personDirectory = Path.Combine(directory, $"Z]{ticks}");
if (saveIndividually)
{
directory = Path.Combine(directory, mapping.MappingFromItem.Id.ToString()); directory = Path.Combine(directory, mapping.MappingFromItem.Id.ToString());
results.Add(new(Path.Combine(directory, $"Z]{ticks}")));
}
distinct.Add(mapping.MappingFromItem.Id); distinct.Add(mapping.MappingFromItem.Id);
distinct.Add(mapping.SortingContainer.Sorting.Id); distinct.Add(mapping.SortingContainer.Sorting.Id);
} }
@ -464,8 +441,10 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
throw new NotSupportedException(); throw new NotSupportedException();
personKey = mapping.MappingFromPerson.PersonBirthday.Value.Ticks; personKey = mapping.MappingFromPerson.PersonBirthday.Value.Ticks;
personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonBirthday); personKeyFormatted = IPersonBirthday.GetFormatted(_Configuration.PersonBirthdayFormat, mapping.MappingFromPerson.PersonBirthday);
if (forIndividually || string.IsNullOrEmpty(mapping.SegmentC)) if (string.IsNullOrEmpty(mapping.SegmentC))
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, mapping.MappingFromPerson.SegmentB); directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, mapping.MappingFromPerson.SegmentB);
else if (saveIndividually)
directory = Path.Combine(_EDistanceContentTicksDirectory, by, mapping.SegmentC.PadLeft(padLeft, '0'), personKeyFormatted, mapping.MappingFromPerson.SegmentB);
else else
directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, mapping.MappingFromPerson.SegmentB, mapping.SegmentC); directory = Path.Combine(_EDistanceContentTicksDirectory, by, personKeyFormatted, mapping.MappingFromPerson.SegmentB, mapping.SegmentC);
if (isByMapping) if (isByMapping)
@ -474,16 +453,15 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, "lnk"); personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, "lnk");
else else
personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName[..1], "lnk"); personDirectory = Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName[..1], "lnk");
if (forIndividually) if (saveIndividually)
directory = Path.Combine(directory, mapping.MappingFromItem.Id.ToString());
if (isByMapping && personKeyToIds.TryGetValue(personKey, out ids))
{ {
saveContainer = new(Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, $"{ids.Count} Face(s)")); directory = Path.Combine(directory, mapping.MappingFromItem.Id.ToString());
results.Add(saveContainer); results.Add(new(Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName)));
} }
if (isByMapping && personKeyToIds.TryGetValue(personKey, out ids))
results.Add(new(Path.Combine(directory, mapping.MappingFromPerson.DisplayDirectoryName, $"{ids.Count} Face(s)")));
} }
saveContainer = new(personDirectory); results.Add(new(personDirectory));
results.Add(saveContainer);
if (!isBySorting || mapping.SortingContainer is null) if (!isBySorting || mapping.SortingContainer is null)
keyMapping = null; keyMapping = null;
else else
@ -496,10 +474,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
if (keyMapping.MappingFromLocation is null) if (keyMapping.MappingFromLocation is null)
continue; continue;
if (keyMapping.MappingFromLocation.NormalizedRectangle == mapping.MappingFromLocation.NormalizedRectangle) if (keyMapping.MappingFromLocation.NormalizedRectangle == mapping.MappingFromLocation.NormalizedRectangle)
{ results.Add(new(Path.Combine(directory, "Maybe")));
saveContainer = new(Path.Combine(directory, "Maybe"));
results.Add(saveContainer);
}
} }
facesDirectory = Stateless.MapLogic.GetFacesDirectory(dFacesContentDirectory, mapping.MappingFromItem); facesDirectory = Stateless.MapLogic.GetFacesDirectory(dFacesContentDirectory, mapping.MappingFromItem);
if (facesDirectory is null) if (facesDirectory is null)
@ -514,7 +489,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
} }
else else
{ {
if (forIndividually) if (saveIndividually)
{ {
facePartsContentCollectionFile = Stateless.MapLogic.GetFacePartsContentCollectionFile(_Configuration.FacePartsFileNameExtension, d2FacePartsContentCollectionDirectory, mapping.MappingFromItem); facePartsContentCollectionFile = Stateless.MapLogic.GetFacePartsContentCollectionFile(_Configuration.FacePartsFileNameExtension, d2FacePartsContentCollectionDirectory, mapping.MappingFromItem);
if (facePartsContentCollectionFile is null) if (facePartsContentCollectionFile is null)
@ -537,13 +512,13 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
results.Add(saveContainer); results.Add(saveContainer);
if (!isBySorting || mapping.SortingContainer is null || keyMapping is null) if (!isBySorting || mapping.SortingContainer is null || keyMapping is null)
continue; continue;
if (!forIndividually && isBySorting && mapping.MappingFromPerson is null) if (!saveIndividually && isBySorting && mapping.MappingFromPerson is null)
{ {
saveContainer = GetMatchSaveContainer(dFacesContentDirectory, d2FacePartsContentDirectory, directory, keyMapping); saveContainer = GetMatchSaveContainer(dFacesContentDirectory, d2FacePartsContentDirectory, directory, keyMapping);
if (saveContainer is not null) if (saveContainer is not null)
results.Add(saveContainer); results.Add(saveContainer);
} }
if (!forIndividually) if (!saveIndividually)
saveContainer = Stateless.MapLogic.GetDebugSaveContainer(directory, mapping.SortingContainer, keyMapping); saveContainer = Stateless.MapLogic.GetDebugSaveContainer(directory, mapping.SortingContainer, keyMapping);
else else
{ {
@ -557,14 +532,14 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
return results; return results;
} }
public List<SaveContainer> GetSaveContainers(string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, Mapping[] mappingCollection, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping, int? useFiltersCounter, bool forIndividually, bool sortingContainersAny) public List<SaveContainer> GetSaveContainers(bool saveIndividually, string dFacesContentDirectory, string d2FacePartsContentDirectory, string d2FacePartsContentCollectionDirectory, Mapping[] mappingCollection, Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping, int? useFiltersCounter, bool sortingContainersAny)
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
List<SaveContainer> results; List<SaveContainer> results;
bool saveMapped = false; bool saveMapped = false;
Dictionary<long, List<int>> personKeyToIds = new(); Dictionary<long, List<int>> personKeyToIds = new();
results = GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, mappingCollection, idToNormalizedRectangleToMapping, personKeyToIds, useFiltersCounter, saveMapped, forIndividually, sortingContainersAny); results = GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, mappingCollection, idToNormalizedRectangleToMapping, personKeyToIds, useFiltersCounter, saveMapped, saveIndividually, sortingContainersAny);
return results; return results;
} }
@ -576,7 +551,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
bool saveMapped = true; bool saveMapped = true;
int? useFiltersCounter = null; int? useFiltersCounter = null;
string mappingDirectory = Path.Combine(_EDistanceContentTicksDirectory, nameof(Shared.Models.Stateless.IMapLogic.Mapping)); string mappingDirectory = Path.Combine(_EDistanceContentTicksDirectory, nameof(Shared.Models.Stateless.IMapLogic.Mapping));
List<SaveContainer> saveContainers = GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, mappingCollection, idToNormalizedRectangleToMapping, personKeyToIds, useFiltersCounter, saveMapped, sortingContainersAny: true, forIndividually: false); List<SaveContainer> saveContainers = GetSaveContainers(dFacesContentDirectory, d2FacePartsContentDirectory, d2FacePartsContentCollectionDirectory, mappingCollection, idToNormalizedRectangleToMapping, personKeyToIds, useFiltersCounter, saveMapped, sortingContainersAny: true, saveIndividually: false);
SaveContainers(totalNotMapped, updated, saveContainers); SaveContainers(totalNotMapped, updated, saveContainers);
if (!string.IsNullOrEmpty(_EDistanceContentTicksDirectory) && Directory.Exists(mappingDirectory)) if (!string.IsNullOrEmpty(_EDistanceContentTicksDirectory) && Directory.Exists(mappingDirectory))
Stateless.MapLogic.SaveMappingShortcuts(mappingDirectory); Stateless.MapLogic.SaveMappingShortcuts(mappingDirectory);
@ -643,7 +618,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
return results; return results;
} }
public int UpdateFromSortingContainers(Shared.Models.Methods.IDistanceLimits distanceLimits, SortingContainer[] sortingContainers) public int UpdateFromSortingContainers(bool saveIndividually, Shared.Models.Methods.IDistanceLimits distanceLimits, SortingContainer[] sortingContainers)
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
@ -710,7 +685,7 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
if (!keyToSegmentC.ContainsKey(key)) if (!keyToSegmentC.ContainsKey(key))
keyToSegmentC.Add(key, string.Empty); keyToSegmentC.Add(key, string.Empty);
keyToCount[key]++; keyToCount[key]++;
if (keyToCount[key] > _Configuration.SortingMaximumPerKey) if (saveIndividually || keyToCount[key] > _Configuration.SortingMaximumPerKey)
{ {
keyToCount[key] = 0; keyToCount[key] = 0;
keyToSegmentC[key] = sortingContainer.Sorting.DistancePermyriad.ToString(); keyToSegmentC[key] = sortingContainer.Sorting.DistancePermyriad.ToString();
@ -1037,64 +1012,13 @@ public class MapLogic : Shared.Models.Methods.IMapLogic
return results; return results;
} }
private static bool TryToFind(string a2PeopleSingletonDirectory, string file, string path)
{
bool result = false;
string? pathName = Path.GetFileName(path);
string? group = Path.GetDirectoryName(path);
string? groupName = Path.GetFileName(group);
if (pathName is not null && group is not null && groupName is not null)
{
WindowsShortcut windowsShortcut;
string checkDirectory = Path.Combine(a2PeopleSingletonDirectory, groupName, pathName);
if (Directory.Exists(checkDirectory))
{
try
{
windowsShortcut = new() { Path = checkDirectory };
windowsShortcut.Save(file);
windowsShortcut.Dispose();
result = true;
}
catch (Exception)
{ }
}
}
return result;
}
private static void BeforeSaveFilteredOriginalImagesFromJLinks(string[] jLinks, string a2PeopleContentDirectory)
{
string[] files;
string checkDirectory;
WindowsShortcut windowsShortcut;
foreach (string directoryName in jLinks)
{
checkDirectory = Path.Combine(a2PeopleContentDirectory, directoryName);
if (!Directory.Exists(checkDirectory))
continue;
files = Directory.GetFiles(checkDirectory, "*.lnk", SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
windowsShortcut = WindowsShortcut.Load(file);
if (windowsShortcut.Path is null)
continue;
if (!Directory.Exists(windowsShortcut.Path))
{
if (!TryToFind(a2PeopleContentDirectory, file, windowsShortcut.Path))
continue;
}
}
}
}
public void SaveFilteredOriginalImagesFromJLinks(string[] jLinks, PersonContainer[] personContainers, string a2PeopleContentDirectory, Dictionary<long, List<int>> personKeyToIds, Mapping[] mappingCollection, int totalNotMapped) public void SaveFilteredOriginalImagesFromJLinks(string[] jLinks, PersonContainer[] personContainers, string a2PeopleContentDirectory, Dictionary<long, List<int>> personKeyToIds, Mapping[] mappingCollection, int totalNotMapped)
{ {
if (_Configuration is null) if (_Configuration is null)
throw new NullReferenceException(nameof(_Configuration)); throw new NullReferenceException(nameof(_Configuration));
SaveContainer? saveContainer; SaveContainer? saveContainer;
List<SaveContainer> saveContainers = new(); List<SaveContainer> saveContainers = new();
BeforeSaveFilteredOriginalImagesFromJLinks(jLinks, a2PeopleContentDirectory); Stateless.MapLogic.BeforeSaveFilteredOriginalImagesFromJLinks(jLinks, a2PeopleContentDirectory);
(int, FileHolder, int, string, string, string, string)[] collection = GetCollectionForSaveFilteredOriginalImagesFromJLinks(jLinks, a2PeopleContentDirectory, personContainers, mappingCollection, personKeyToIds); (int, FileHolder, int, string, string, string, string)[] collection = GetCollectionForSaveFilteredOriginalImagesFromJLinks(jLinks, a2PeopleContentDirectory, personContainers, mappingCollection, personKeyToIds);
foreach ((int id, FileHolder imageFileHolder, int approximateYears, string personKeyFormatted, string directory, string personDirectory, string checkFile) in collection) foreach ((int id, FileHolder imageFileHolder, int approximateYears, string personKeyFormatted, string directory, string personDirectory, string checkFile) in collection)
{ {

View File

@ -87,6 +87,90 @@ internal abstract class MapLogic
} }
} }
private static void MoveTo(string actionDirectory, string ticksDirectory, string directory, string personKeyFormatted, string yearDirectoryName, string alphaDirectoryName, string[] files, string[] matchFaceFile)
{
string checkFile;
string actionDirectoryName = Path.GetFileName(actionDirectory);
string checkDirectory = actionDirectoryName.StartsWith("y", StringComparison.CurrentCultureIgnoreCase) ? Path.Combine(ticksDirectory, personKeyFormatted, yearDirectoryName, alphaDirectoryName) : Path.Combine(directory, actionDirectoryName);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
foreach (string file in files)
{
if (matchFaceFile.Contains(file))
{
checkFile = Path.Combine(checkDirectory, Path.GetFileName(file));
if (File.Exists(checkFile))
continue;
File.Move(file, checkFile);
continue;
}
File.Delete(file);
}
}
private static void Individually(Configuration configuration, string ticksDirectory, string directory)
{
string[] files;
FileInfo[] collection;
string[] matchFaceFile;
string yearDirectoryName;
string[] yearDirectories;
string alphaDirectoryName;
string matchDirectoryName;
string personKeyFormatted;
string[] alphaDirectories;
string[] matchDirectories;
string[] actionDirectories;
string personDisplayDirectory;
string[] personKeyDirectories;
string[] segmentCDirectories = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly);
foreach (string segmentCDirectory in segmentCDirectories)
{
personKeyDirectories = Directory.GetDirectories(segmentCDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string personKeyDirectory in personKeyDirectories)
{
personKeyFormatted = Path.GetFileName(personKeyDirectory);
yearDirectories = Directory.GetDirectories(personKeyDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string yearDirectory in yearDirectories)
{
yearDirectoryName = Path.GetFileName(yearDirectory);
matchDirectories = Directory.GetDirectories(yearDirectory, "*", SearchOption.TopDirectoryOnly);
alphaDirectories = matchDirectories.Where(l => !long.TryParse(Path.GetFileName(l), out long a)).ToArray();
if (!alphaDirectories.Any())
continue;
foreach (string matchDirectory in matchDirectories)
{
matchDirectoryName = Path.GetFileName(matchDirectory);
files = Directory.GetFiles(matchDirectory, "*", SearchOption.TopDirectoryOnly);
if (files.Length != 4)
continue;
collection = files.Select(l => new FileInfo(l)).ToArray();
matchFaceFile = (from l in collection where l.Extension == configuration.FacesFileNameExtension && l.Name.Contains(matchDirectoryName) select l.FullName).ToArray();
if (!matchFaceFile.Any())
continue;
alphaDirectoryName = Path.GetFileName(alphaDirectories[0]);
personDisplayDirectory = Path.Combine(matchDirectory, alphaDirectoryName);
if (!Directory.Exists(personDisplayDirectory) || !Directory.Exists(matchDirectory))
continue;
if (matchDirectory.Contains('='))
continue;
_ = System.Diagnostics.Process.Start("explorer", matchDirectory);
for (int i = 0; i < int.MaxValue; i++)
{
Thread.Sleep(500);
actionDirectories = Directory.GetDirectories(matchDirectory, "*", SearchOption.TopDirectoryOnly).Where(l => l != personDisplayDirectory && !l.EndsWith("Maybe")).ToArray();
if (actionDirectories.Any())
{
MoveTo(actionDirectories[0], ticksDirectory, directory, personKeyFormatted, yearDirectoryName, alphaDirectoryName, files, matchFaceFile);
break;
}
}
}
}
}
}
}
internal static List<(string, string[], string)> DeleteEmptyDirectoriesAndGetCollection(Configuration configuration, List<string> personKeyFormattedCollection, string[] ticksDirectories, string message) internal static List<(string, string[], string)> DeleteEmptyDirectoriesAndGetCollection(Configuration configuration, List<string> personKeyFormattedCollection, string[] ticksDirectories, string message)
{ {
List<(string, string[], string)> results = new(); List<(string, string[], string)> results = new();
@ -118,7 +202,12 @@ internal abstract class MapLogic
foreach (string personKeyDirectory in personKeyDirectories) foreach (string personKeyDirectory in personKeyDirectories)
{ {
personKeyFormatted = Path.GetFileName(personKeyDirectory); personKeyFormatted = Path.GetFileName(personKeyDirectory);
isReservedDirectoryName = personKeyFormatted.StartsWith(nameof(Shared.Models.Stateless.IMapLogic.Sorting)) || personKeyFormatted.StartsWith(nameof(Shared.Models.Stateless.IMapLogic.Mapping)) || personKeyFormatted.StartsWith(nameof(Shared.Models.Stateless.IMapLogic.ManualCopy)) || personKeyFormatted.StartsWith(nameof(Shared.Models.Stateless.IMapLogic.Individually)); if (personKeyFormatted.StartsWith(nameof(Shared.Models.Stateless.IMapLogic.Individually)))
{
Individually(configuration, ticksDirectory, personKeyDirectory);
break;
}
isReservedDirectoryName = personKeyFormatted.StartsWith(nameof(Shared.Models.Stateless.IMapLogic.Sorting)) || personKeyFormatted.StartsWith(nameof(Shared.Models.Stateless.IMapLogic.Mapping)) || personKeyFormatted.StartsWith(nameof(Shared.Models.Stateless.IMapLogic.ManualCopy));
yearDirectories = Directory.GetDirectories(personKeyDirectory, "*", SearchOption.TopDirectoryOnly); yearDirectories = Directory.GetDirectories(personKeyDirectory, "*", SearchOption.TopDirectoryOnly);
foreach (string yearDirectory in yearDirectories) foreach (string yearDirectory in yearDirectories)
{ {
@ -856,4 +945,88 @@ internal abstract class MapLogic
return results; return results;
} }
private static bool TryToFind(string a2PeopleSingletonDirectory, string file, string path)
{
bool result = false;
string? pathName = Path.GetFileName(path);
string? group = Path.GetDirectoryName(path);
string? groupName = Path.GetFileName(group);
if (pathName is not null && group is not null && groupName is not null)
{
WindowsShortcut windowsShortcut;
string checkDirectory = Path.Combine(a2PeopleSingletonDirectory, groupName, pathName);
if (Directory.Exists(checkDirectory))
{
try
{
windowsShortcut = new() { Path = checkDirectory };
windowsShortcut.Save(file);
windowsShortcut.Dispose();
result = true;
}
catch (Exception)
{ }
}
}
return result;
}
internal static void BeforeSaveFilteredOriginalImagesFromJLinks(string[] jLinks, string a2PeopleContentDirectory)
{
string[] files;
string checkDirectory;
WindowsShortcut windowsShortcut;
foreach (string directoryName in jLinks)
{
checkDirectory = Path.Combine(a2PeopleContentDirectory, directoryName);
if (!Directory.Exists(checkDirectory))
continue;
files = Directory.GetFiles(checkDirectory, "*.lnk", SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
windowsShortcut = WindowsShortcut.Load(file);
if (windowsShortcut.Path is null)
continue;
if (!Directory.Exists(windowsShortcut.Path))
{
if (!TryToFind(a2PeopleContentDirectory, file, windowsShortcut.Path))
continue;
}
}
}
}
internal static (string, bool, bool) Get(int? useFiltersCounter, bool saveIndividually, bool sortingContainersAny, string forceSingleImageHumanized, Mapping mapping)
{
string by;
bool isByMapping;
bool isBySorting;
if (mapping.By is null)
{
isByMapping = false;
isBySorting = !sortingContainersAny;
by = $"{nameof(Shared.Models.Stateless.IMapLogic.Mapping)}Null";
}
else
{
isByMapping = mapping.By == Shared.Models.Stateless.IMapLogic.Mapping;
isBySorting = mapping.By == Shared.Models.Stateless.IMapLogic.Sorting;
if (isBySorting && mapping.MappingFromPerson is null)
by = saveIndividually ? nameof(Shared.Models.Stateless.IMapLogic.Individually) : $"{nameof(Shared.Models.Stateless.IMapLogic.Sorting)} Without Person";
else if (isBySorting && useFiltersCounter.HasValue)
by = $"{nameof(Shared.Models.Stateless.IMapLogic.Sorting)} Modified Filters - {useFiltersCounter.Value}";
else
{
by = mapping.By.Value switch
{
Shared.Models.Stateless.IMapLogic.Mapping => nameof(Shared.Models.Stateless.IMapLogic.Mapping),
Shared.Models.Stateless.IMapLogic.Sorting => saveIndividually ? nameof(Shared.Models.Stateless.IMapLogic.Individually) : nameof(Shared.Models.Stateless.IMapLogic.Sorting),
Shared.Models.Stateless.IMapLogic.ForceSingleImage => forceSingleImageHumanized,
_ => throw new NotImplementedException()
};
}
}
return new(by, isByMapping, isBySorting);
}
} }

View File

@ -182,6 +182,7 @@ public class Mapping : Properties.IMapping
{ {
_By = Stateless.IMapLogic.Sorting; _By = Stateless.IMapLogic.Sorting;
_SortingContainer = sortingContainer; _SortingContainer = sortingContainer;
_SegmentC = sortingContainer.Sorting.DistancePermyriad.ToString();
} }
public void UpdateMappingFromPerson(int? approximateYears, string displayDirectoryName, PersonBirthday personBirthday, string segmentB) public void UpdateMappingFromPerson(int? approximateYears, string displayDirectoryName, PersonBirthday personBirthday, string segmentB)