|
|
|
@ -63,7 +63,7 @@ public partial class DlibDotNet
|
|
|
|
|
Models.Configuration configuration = Models.Binder.Configuration.Get(isEnvironment, configurationRoot, propertyConfiguration);
|
|
|
|
|
_Log.Information(propertyConfiguration.RootDirectory);
|
|
|
|
|
Property.Models.Configuration.Verify(propertyConfiguration, requireExist: false);
|
|
|
|
|
OpenPossibleDuplicates(configuration);
|
|
|
|
|
Verify(configuration);
|
|
|
|
|
VerifyExtra(args, propertyConfiguration, configuration);
|
|
|
|
|
_Configuration = configuration;
|
|
|
|
|
_Index = new(configuration);
|
|
|
|
@ -206,7 +206,7 @@ public partial class DlibDotNet
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OpenPossibleDuplicates(Models.Configuration configuration)
|
|
|
|
|
private void Verify(Models.Configuration configuration)
|
|
|
|
|
{
|
|
|
|
|
if (!configuration.OutputResolutions.Any() || string.IsNullOrEmpty(configuration.OutputResolutions[0]) || !configuration.ValidResolutions.Contains(configuration.OutputResolutions[0]))
|
|
|
|
|
throw new NullReferenceException($"{nameof(configuration.OutputResolutions)} must be _FileNameToCollection valid outputResolution!");
|
|
|
|
@ -274,7 +274,8 @@ public partial class DlibDotNet
|
|
|
|
|
configuration.MappingDefaultName,
|
|
|
|
|
configuration.PersonBirthdayFirstYear,
|
|
|
|
|
configuration.PersonBirthdayFormat,
|
|
|
|
|
configuration.PersonCharacters,
|
|
|
|
|
configuration.PersonCharacters.ToArray(),
|
|
|
|
|
configuration.PersonCharactersCopyCount,
|
|
|
|
|
configuration.RangeDaysDeltaTolerance,
|
|
|
|
|
configuration.RangeDistanceTolerance,
|
|
|
|
|
configuration.SaveSortingWithoutPerson,
|
|
|
|
@ -783,6 +784,52 @@ public partial class DlibDotNet
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RenameAbandoned(string argZero, Container[] containers)
|
|
|
|
|
{
|
|
|
|
|
List<string> renameCollection = new();
|
|
|
|
|
foreach (Container container in containers)
|
|
|
|
|
{
|
|
|
|
|
if (!container.Items.Any())
|
|
|
|
|
continue;
|
|
|
|
|
if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
|
|
|
|
|
continue;
|
|
|
|
|
foreach (Item item in container.Items)
|
|
|
|
|
{
|
|
|
|
|
if (item.Abandoned is not null && item.Abandoned.Value)
|
|
|
|
|
renameCollection.Add(item.SourceDirectoryFileHolder.FullName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (renameCollection.Any())
|
|
|
|
|
{
|
|
|
|
|
foreach (string rename in renameCollection)
|
|
|
|
|
File.Move(rename, $"{rename}.abd");
|
|
|
|
|
throw new Exception($"Renamed {renameCollection.Count}(s) files!");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RenameMoved(string argZero, Container[] containers)
|
|
|
|
|
{
|
|
|
|
|
List<string> renameCollection = new();
|
|
|
|
|
foreach (Container container in containers)
|
|
|
|
|
{
|
|
|
|
|
if (!container.Items.Any())
|
|
|
|
|
continue;
|
|
|
|
|
if (!_ArgZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
|
|
|
|
|
continue;
|
|
|
|
|
foreach (Item item in container.Items)
|
|
|
|
|
{
|
|
|
|
|
if (item.Moved is not null && item.Moved.Value)
|
|
|
|
|
renameCollection.Add(item.SourceDirectoryFileHolder.FullName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (renameCollection.Any())
|
|
|
|
|
{
|
|
|
|
|
foreach (string rename in renameCollection)
|
|
|
|
|
File.Move(rename, $"{rename}.mvd");
|
|
|
|
|
throw new Exception($"Renamed {renameCollection.Count}(s) files!");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<Shared.Models.Face> GetFilteredDistinctFaces(string argZero, Container[] containers)
|
|
|
|
|
{
|
|
|
|
|
List<Shared.Models.Face> results = new();
|
|
|
|
@ -845,13 +892,12 @@ public partial class DlibDotNet
|
|
|
|
|
return items;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void MapLogic(string argZero, long ticks, Container[] containers, string a2PeopleSingletonDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, string fPhotoPrismContentDirectory, MapLogicSupport mapLogicSupport, MapLogic mapLogic, string outputResolution, List<Shared.Models.Face> distinctFilteredFaces, Mapping[] mappingCollection, int totalNotMapped)
|
|
|
|
|
private void MapLogic(string argZero, long ticks, Container[] containers, string a2PeopleSingletonDirectory, string dResultsFullGroupDirectory, string d2ResultsFullGroupDirectory, string fPhotoPrismContentDirectory, MapLogicSupport mapLogicSupport, MapLogic mapLogic, string outputResolution, List<Shared.Models.Face> distinctFilteredFaces, Mapping[] mappingCollection, int totalNotMapped, Dictionary<long, int> personKeyToCount)
|
|
|
|
|
{
|
|
|
|
|
int? useFiltersCounter = null;
|
|
|
|
|
SortingContainer[] sortingContainers;
|
|
|
|
|
string dFacesContentDirectory = Path.Combine(dResultsFullGroupDirectory, "()");
|
|
|
|
|
string d2FacePartsContentDirectory = Path.Combine(d2ResultsFullGroupDirectory, "()");
|
|
|
|
|
Dictionary<long, int> personKeyToCount = mapLogic.GetPersonKeyToCount(mappingCollection);
|
|
|
|
|
string dFacesCollectionDirectory = Path.Combine(dResultsFullGroupDirectory, "[]", _Configuration.PropertyConfiguration.ResultAllInOne);
|
|
|
|
|
Dictionary<int, Dictionary<int, Mapping>> idToNormalizedRectangleToMapping = MapLogicSupport.GetIdToNormalizedRectangleToFace(mappingCollection);
|
|
|
|
|
if (Directory.Exists(fPhotoPrismContentDirectory))
|
|
|
|
@ -861,13 +907,11 @@ public partial class DlibDotNet
|
|
|
|
|
List<Item> filteredItems = GetItems(argZero, containers);
|
|
|
|
|
mapLogic.SaveShortcutsForOutputResolutions(filteredItems, mappingCollection, personKeyToCount);
|
|
|
|
|
}
|
|
|
|
|
if (_Configuration.PersonCharactersToCopyTo.Length == 1 && _Configuration.PersonCharacters.ToArray().Contains(_Configuration.PersonCharactersToCopyTo[0]))
|
|
|
|
|
mapLogic.CopyAtLeastOneMappedFiles(_Configuration.PersonCharactersToCopyTo[0], dFacesContentDirectory, a2PeopleSingletonDirectory, mappingCollection);
|
|
|
|
|
if (_Configuration.PersonCharactersCopyCount > 0 && !string.IsNullOrEmpty(_Configuration.PersonCharacters))
|
|
|
|
|
mapLogic.CopyAtLeastOneMappedFiles(dFacesContentDirectory, a2PeopleSingletonDirectory, mappingCollection);
|
|
|
|
|
mapLogic.CopyManualFiles(dFacesContentDirectory, idToNormalizedRectangleToMapping);
|
|
|
|
|
if (_Configuration.SaveMappedForOutputResolutions.Contains(outputResolution))
|
|
|
|
|
mapLogic.SaveMapped(dFacesContentDirectory, d2FacePartsContentDirectory, mappingCollection, idToNormalizedRectangleToMapping, personKeyToCount, totalNotMapped);
|
|
|
|
|
if (_Configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions.Contains(outputResolution))
|
|
|
|
|
mapLogic.SaveFilteredOriginalImagesFromJLinks(_Configuration.JLinks, _PersonContainers, a2PeopleSingletonDirectory, mappingCollection, personKeyToCount, totalNotMapped);
|
|
|
|
|
if (_Configuration.SaveFaceDistancesForOutputResolutions.Contains(outputResolution))
|
|
|
|
|
{
|
|
|
|
|
MapLogicSupport.SetFaceDistances(_AppSettings.MaxDegreeOfParallelism, ticks, distinctFilteredFaces);
|
|
|
|
@ -1014,6 +1058,7 @@ public partial class DlibDotNet
|
|
|
|
|
string key;
|
|
|
|
|
double? percent;
|
|
|
|
|
Rectangle? rectangle;
|
|
|
|
|
List<string> delete = new();
|
|
|
|
|
Rectangle intersectRectangle;
|
|
|
|
|
(string File, int NormalizedRectangle) item;
|
|
|
|
|
Dictionary<string, (string, int)> distinct = new();
|
|
|
|
@ -1038,21 +1083,28 @@ public partial class DlibDotNet
|
|
|
|
|
percent = intersectRectangle.Width * intersectRectangle.Height;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!_Configuration.DeletePossibleDuplicates)
|
|
|
|
|
duplicates.Add(new(locationContainer.PersonKey, locationContainer.Id, locationContainer.File, percent));
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (File.Exists(item.File))
|
|
|
|
|
File.Delete(item.File);
|
|
|
|
|
if (File.Exists(locationContainer.File))
|
|
|
|
|
File.Delete(locationContainer.File);
|
|
|
|
|
}
|
|
|
|
|
delete.Add(item.File);
|
|
|
|
|
delete.Add(locationContainer.File);
|
|
|
|
|
duplicates.Add(new(locationContainer.PersonKey, locationContainer.Id, locationContainer.File, percent));
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
distinct.Add(key, new(locationContainer.File, locationContainer.NormalizedRectangle));
|
|
|
|
|
}
|
|
|
|
|
if (duplicates.Any() && _IsEnvironment.Development)
|
|
|
|
|
OpenPossibleDuplicates(duplicates);
|
|
|
|
|
if (!_Configuration.DeletePossibleDuplicates)
|
|
|
|
|
{
|
|
|
|
|
if (duplicates.Any() && _IsEnvironment.Development)
|
|
|
|
|
OpenPossibleDuplicates(duplicates);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (delete.Count > 5)
|
|
|
|
|
throw new Exception("Something maybe wrong!");
|
|
|
|
|
foreach (string file in delete)
|
|
|
|
|
{
|
|
|
|
|
if (File.Exists(file))
|
|
|
|
|
File.Delete(file);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<LocationContainer<MetadataExtractor.Directory>> GetCollection(long ticks, string? a2PeopleContentDirectory, string eDistanceContentDirectory)
|
|
|
|
@ -1107,9 +1159,7 @@ public partial class DlibDotNet
|
|
|
|
|
int f;
|
|
|
|
|
int j;
|
|
|
|
|
int t;
|
|
|
|
|
int totalNotMapped;
|
|
|
|
|
Container[] containers;
|
|
|
|
|
Mapping[] mappingCollection;
|
|
|
|
|
string eDistanceContentDirectory;
|
|
|
|
|
string? a2PeopleContentDirectory;
|
|
|
|
|
string aResultsFullGroupDirectory;
|
|
|
|
@ -1119,7 +1169,6 @@ public partial class DlibDotNet
|
|
|
|
|
string d2ResultsFullGroupDirectory;
|
|
|
|
|
string fPhotoPrismContentDirectory;
|
|
|
|
|
string fPhotoPrismSingletonDirectory;
|
|
|
|
|
List<Shared.Models.Face> distinctFilteredFaces;
|
|
|
|
|
string a2PeopleSingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(A2_People), "{}");
|
|
|
|
|
int totalSeconds = (int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds);
|
|
|
|
|
string message = $") Building Container(s) - {totalSeconds} total second(s)";
|
|
|
|
@ -1130,6 +1179,8 @@ public partial class DlibDotNet
|
|
|
|
|
progressBar.Tick();
|
|
|
|
|
(j, f, t, containers) = Property.Models.Stateless.Container.GetContainers(_Configuration.PropertyConfiguration, propertyLogic);
|
|
|
|
|
}
|
|
|
|
|
RenameMoved(argZero, containers);
|
|
|
|
|
RenameAbandoned(argZero, containers);
|
|
|
|
|
Container? container = AreAllSameEndsWith(argZero, containers);
|
|
|
|
|
if (!_ArgZeroIsConfigurationRootDirectory || container is null)
|
|
|
|
|
{
|
|
|
|
@ -1168,25 +1219,26 @@ public partial class DlibDotNet
|
|
|
|
|
FullDoWork(argZero, propertyRoot, ticks, propertyLogic, t, containers, a2PeopleContentDirectory, eDistanceContentDirectory);
|
|
|
|
|
_Distance.Clear();
|
|
|
|
|
mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, ticks, _PersonContainers, a2PeopleSingletonDirectory, eDistanceContentDirectory, mapLogicSupport);
|
|
|
|
|
SetMapping(_FileNameToCollection, argZero, containers);
|
|
|
|
|
List<Shared.Models.Face> distinctFilteredFaces = GetFilteredDistinctFaces(argZero, containers);
|
|
|
|
|
Mapping[] mappingCollection = MapLogicSupport.GetSelectedMappingCollection(distinctFilteredFaces);
|
|
|
|
|
Dictionary<long, int> personKeyToCount = mapLogic.GetPersonKeyToCount(mappingCollection);
|
|
|
|
|
int totalNotMapped = mapLogic.UpdateMappingFromPerson(mappingCollection);
|
|
|
|
|
if (a2PeopleContentDirectory is not null && false)
|
|
|
|
|
mapLogic.CreateTree(ticks, a2PeopleContentDirectory);
|
|
|
|
|
foreach (string outputResolution in _Configuration.OutputResolutions)
|
|
|
|
|
{
|
|
|
|
|
if (_PropertyRootExistedBefore || container is not null)
|
|
|
|
|
break;
|
|
|
|
|
(aResultsFullGroupDirectory, bResultsFullGroupDirectory, cResultsFullGroupDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory) = GetResultsFullGroupDirectories(outputResolution);
|
|
|
|
|
if (_Configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions.Contains(outputResolution))
|
|
|
|
|
MapLogicSupport.BeforeSaveFilteredOriginalImagesFromJLinks(_Configuration.JLinks, a2PeopleSingletonDirectory);
|
|
|
|
|
SetMapping(_FileNameToCollection, argZero, containers);
|
|
|
|
|
distinctFilteredFaces = GetFilteredDistinctFaces(argZero, containers);
|
|
|
|
|
mappingCollection = MapLogicSupport.GetSelectedMappingCollection(distinctFilteredFaces);
|
|
|
|
|
totalNotMapped = mapLogic.UpdateMappingFromPerson(mappingCollection);
|
|
|
|
|
if (a2PeopleContentDirectory is not null)
|
|
|
|
|
mapLogic.CreateTree(ticks, a2PeopleContentDirectory);
|
|
|
|
|
if (!string.IsNullOrEmpty(a2PeopleContentDirectory) && _Configuration.SaveFilteredOriginalImagesFromJLinksForOutputResolutions.Contains(outputResolution))
|
|
|
|
|
mapLogic.SaveFilteredOriginalImagesFromJLinks(_Configuration.JLinks, _PersonContainers, a2PeopleContentDirectory, mappingCollection, personKeyToCount, totalNotMapped);
|
|
|
|
|
if (_ArgZeroIsConfigurationRootDirectory
|
|
|
|
|
&& _Configuration.SaveResizedSubfiles
|
|
|
|
|
&& outputResolution == _Configuration.OutputResolutions[0]
|
|
|
|
|
&& _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)
|
|
|
|
|
&& _Exceptions.Count == 0)
|
|
|
|
|
MapLogic(argZero, ticks, containers, a2PeopleSingletonDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, fPhotoPrismContentDirectory, mapLogicSupport, mapLogic, outputResolution, distinctFilteredFaces, mappingCollection, totalNotMapped);
|
|
|
|
|
MapLogic(argZero, ticks, containers, a2PeopleSingletonDirectory, dResultsFullGroupDirectory, d2ResultsFullGroupDirectory, fPhotoPrismContentDirectory, mapLogicSupport, mapLogic, outputResolution, distinctFilteredFaces, mappingCollection, totalNotMapped, personKeyToCount);
|
|
|
|
|
if (_Configuration.SaveRandomForOutputResolutions.Contains(outputResolution))
|
|
|
|
|
_Random.Random(_Configuration.PropertyConfiguration, mapLogic, outputResolution, mappingCollection);
|
|
|
|
|
if (_IsEnvironment.Development)
|
|
|
|
|