|
|
|
@ -254,31 +254,6 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
|
|
|
|
|
throw new Exception("Configuration has SaveSortingWithoutPerson and FocusDirectory!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ReadOnlyCollection<int> GetNotNineCollection(ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection)
|
|
|
|
|
{
|
|
|
|
|
List<int> results = [];
|
|
|
|
|
FileInfo fileInfo;
|
|
|
|
|
FileHolder fileHolder;
|
|
|
|
|
FilePath checkFilePath;
|
|
|
|
|
foreach (ReadOnlyCollection<FilePath> filePaths in filePathsCollection)
|
|
|
|
|
{
|
|
|
|
|
foreach (FilePath filePath in filePaths)
|
|
|
|
|
{
|
|
|
|
|
if (!filePath.FullName.Contains(" !9"))
|
|
|
|
|
continue;
|
|
|
|
|
fileInfo = new(filePath.FullName);
|
|
|
|
|
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(fileInfo);
|
|
|
|
|
if (!fileInfo.Attributes.HasFlag(FileAttributes.Hidden))
|
|
|
|
|
File.SetAttributes(fileHolder.FullName, FileAttributes.Hidden);
|
|
|
|
|
checkFilePath = FilePath.Get(_Configuration.PropertyConfiguration, fileHolder, index: null);
|
|
|
|
|
if (checkFilePath.Id is null)
|
|
|
|
|
continue;
|
|
|
|
|
results.Add(checkFilePath.Id.Value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return new(results);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void DeleteContinueFiles(ReadOnlyCollection<PersonContainer> personContainers)
|
|
|
|
|
{
|
|
|
|
|
foreach (PersonContainer personContainer in personContainers)
|
|
|
|
@ -337,9 +312,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
|
|
|
|
|
const string directorySearchFilter = "*";
|
|
|
|
|
string? filesCollectionRootDirectory = null;
|
|
|
|
|
bool configurationOutputResolutionsHas = false;
|
|
|
|
|
ReadOnlyCollection<Container> readOnlyContainers;
|
|
|
|
|
ReadOnlyCollection<int>? notNineCollection = null;
|
|
|
|
|
ReadOnlyDictionary<long, List<int>> personKeyToIds;
|
|
|
|
|
ReadOnlyDictionary<int, Identifier>? splatNineIdentifiers = null;
|
|
|
|
|
ReadOnlyCollection<ReadOnlyCollection<FilePath>>? filePathsCollection = null;
|
|
|
|
|
bool runToDoCollectionFirst = GetRunToDoCollectionFirst(_Configuration, ticks);
|
|
|
|
|
(aResultsFullGroupDirectory, bResultsFullGroupDirectory) = GetResultsFullGroupDirectories();
|
|
|
|
@ -361,8 +335,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
|
|
|
|
|
if (!runToDoCollectionFirst)
|
|
|
|
|
break;
|
|
|
|
|
(filesCollectionRootDirectory, filePathsCollection, filesCollectionCountIsOne) = GetFilesCollectionThenCopyOrMove(ticks, fileSearchFilter, directorySearchFilter, options, outputResolution);
|
|
|
|
|
SaveDistinctIds(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, filePathsCollection);
|
|
|
|
|
notNineCollection = GetNotNineCollection(filePathsCollection);
|
|
|
|
|
splatNineIdentifiers = GetSplatNineIdentifiersAndHideSplatNine(_Configuration.PropertyConfiguration, bResultsFullGroupDirectory, filePathsCollection);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
fPhotoPrismContentDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_Configuration.PropertyConfiguration, nameof(F_PhotoPrism), _Configuration.PropertyConfiguration.ResultContent);
|
|
|
|
@ -396,7 +369,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
|
|
|
|
|
continue;
|
|
|
|
|
(cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution);
|
|
|
|
|
filesCollectionRootDirectory = Path.Combine(cResultsFullGroupDirectory, _Configuration.PropertyConfiguration.ResultContent);
|
|
|
|
|
filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, filesCollectionRootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage: true);
|
|
|
|
|
filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, directorySearchFilter, fileSearchFilter, filesCollectionRootDirectory, useCeilingAverage: true);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -408,7 +381,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
|
|
|
|
|
int count = filePathsCollection.Select(l => l.Count).Sum();
|
|
|
|
|
message = $") Building Container(s) - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)";
|
|
|
|
|
_ProgressBar = new(count, message, options);
|
|
|
|
|
readOnlyContainers = Shared.Models.Stateless.Methods.IContainer.GetContainers(this, _Configuration.PropertyConfiguration, aPropertySingletonDirectory, filesCollectionRootDirectory, filePathsCollection);
|
|
|
|
|
ReadOnlyCollection<Container> readOnlyContainers = Shared.Models.Stateless.Methods.IContainer.GetContainers(this, _Configuration.PropertyConfiguration, aPropertySingletonDirectory, filesCollectionRootDirectory, splatNineIdentifiers, filePathsCollection);
|
|
|
|
|
_ProgressBar.Dispose();
|
|
|
|
|
mapLogic ??= new(_AppSettings.MaxDegreeOfParallelism, _Configuration.PropertyConfiguration, _MapConfiguration, _Distance, personContainers, ticks, a2PeopleContentDirectory, a2PeopleSingletonDirectory, eDistanceContentDirectory);
|
|
|
|
|
DeleteContinueFiles(personContainers);
|
|
|
|
@ -455,8 +428,8 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
|
|
|
|
|
&& _Configuration.LoadOrCreateThenSaveDistanceResultsForOutputResolutions.Contains(outputResolution)
|
|
|
|
|
&& _Exceptions.Count == 0)
|
|
|
|
|
MapLogic(ticks, readOnlyContainers, fPhotoPrismContentDirectory, mapLogic, outputResolution, new(personKeyToIds), distinctValidImageFaces, distinctValidImageMappingCollection);
|
|
|
|
|
if (runToDoCollectionFirst && _Configuration.SaveRandomForOutputResolutions.Contains(outputResolution) && personKeyToIds.Count > 0 && distinctValidImageMappingCollection.Count > 0)
|
|
|
|
|
_Random.Random(_Configuration.PropertyConfiguration, _Configuration.ImmichAssetsFile, _Configuration.RadomUseBirthdayMinimum, _Configuration.ValidKeyWordsToIgnoreInRandom, personKeyToIds, notNineCollection, distinctValidImageMappingCollection);
|
|
|
|
|
if (runToDoCollectionFirst && _Configuration.SaveRandomForOutputResolutions.Contains(outputResolution) && personKeyToIds.Count > 0 && splatNineIdentifiers is not null && distinctValidImageMappingCollection.Count > 0)
|
|
|
|
|
_Random.Random(_Configuration.PropertyConfiguration, _Configuration.ImmichAssetsFile, _Configuration.ImmichOwnerId, _Configuration.ImmichRoot, _Configuration.RadomUseBirthdayMinimum, _Configuration.ValidKeyWordsToIgnoreInRandom, personKeyToIds, splatNineIdentifiers, distinctValidImageMappingCollection);
|
|
|
|
|
if (_IsEnvironment.Development)
|
|
|
|
|
continue;
|
|
|
|
|
if (!_IsEnvironment.Development)
|
|
|
|
@ -569,7 +542,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
|
|
|
|
|
isValidImageFormatExtension = _Configuration.PropertyConfiguration.ValidImageFormatExtensions.Contains(extensionLowered);
|
|
|
|
|
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(sourceDirectoryFile);
|
|
|
|
|
filePath = FilePath.Get(_Configuration.PropertyConfiguration, fileHolder, index: null);
|
|
|
|
|
_ = new Item(filePath, fileHolder, relativePath, isValidImageFormatExtension);
|
|
|
|
|
_ = Item.Get(filePath, fileHolder, relativePath, isValidImageFormatExtension);
|
|
|
|
|
// container.Items.Add(item);
|
|
|
|
|
}
|
|
|
|
|
_Logger?.LogInformation(". . .");
|
|
|
|
@ -663,10 +636,11 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static ReadOnlyDictionary<int, List<FilePath>> GetKeyValuePairs(ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection)
|
|
|
|
|
private static ReadOnlyDictionary<int, ReadOnlyCollection<FilePath>> GetKeyValuePairs(ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection)
|
|
|
|
|
{
|
|
|
|
|
Dictionary<int, List<FilePath>> results = [];
|
|
|
|
|
Dictionary<int, ReadOnlyCollection<FilePath>> results = [];
|
|
|
|
|
List<FilePath>? collection;
|
|
|
|
|
Dictionary<int, List<FilePath>> keyValuePairs = [];
|
|
|
|
|
foreach (ReadOnlyCollection<FilePath> filePaths in filePathsCollection)
|
|
|
|
|
{
|
|
|
|
|
if (filePaths.Count == 0)
|
|
|
|
@ -675,45 +649,69 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
|
|
|
|
|
{
|
|
|
|
|
if (filePath.Id is null)
|
|
|
|
|
continue;
|
|
|
|
|
if (!results.TryGetValue(filePath.Id.Value, out collection))
|
|
|
|
|
if (!keyValuePairs.TryGetValue(filePath.Id.Value, out collection))
|
|
|
|
|
{
|
|
|
|
|
results.Add(filePath.Id.Value, []);
|
|
|
|
|
if (!results.TryGetValue(filePath.Id.Value, out collection))
|
|
|
|
|
keyValuePairs.Add(filePath.Id.Value, []);
|
|
|
|
|
if (!keyValuePairs.TryGetValue(filePath.Id.Value, out collection))
|
|
|
|
|
throw new Exception();
|
|
|
|
|
}
|
|
|
|
|
collection.Add(filePath);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
foreach (KeyValuePair<int, List<FilePath>> keyValuePair in keyValuePairs)
|
|
|
|
|
results.Add(keyValuePair.Key, new(keyValuePair.Value));
|
|
|
|
|
return new(results);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void SaveDistinctIds(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection)
|
|
|
|
|
private static ReadOnlyDictionary<int, Identifier> GetSplatNineIdentifiersAndHideSplatNine(Property.Models.Configuration propertyConfiguration, string bResultsFullGroupDirectory, ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection)
|
|
|
|
|
{
|
|
|
|
|
ReadOnlyDictionary<int, List<FilePath>> keyValuePairs = GetKeyValuePairs(filePathsCollection);
|
|
|
|
|
Dictionary<int, Identifier> results = [];
|
|
|
|
|
ReadOnlyDictionary<int, ReadOnlyCollection<FilePath>> keyValuePairs = GetKeyValuePairs(filePathsCollection);
|
|
|
|
|
if (keyValuePairs.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
string json;
|
|
|
|
|
string paddedId;
|
|
|
|
|
FileInfo fileInfo;
|
|
|
|
|
FilePath filePath;
|
|
|
|
|
FileHolder fileHolder;
|
|
|
|
|
Identifier identifier;
|
|
|
|
|
string[] directoryNames;
|
|
|
|
|
List<int> distinct = [];
|
|
|
|
|
List<Identifier> identifiers = [];
|
|
|
|
|
string rootDirectory = propertyConfiguration.RootDirectory.Replace('\\', '/');
|
|
|
|
|
string bMetadataCollectionDirectory = Path.Combine(bResultsFullGroupDirectory, propertyConfiguration.ResultCollection);
|
|
|
|
|
if (!Directory.Exists(bMetadataCollectionDirectory))
|
|
|
|
|
_ = Directory.CreateDirectory(bMetadataCollectionDirectory);
|
|
|
|
|
foreach (KeyValuePair<int, List<FilePath>> keyValuePair in keyValuePairs)
|
|
|
|
|
foreach (KeyValuePair<int, ReadOnlyCollection<FilePath>> keyValuePair in keyValuePairs)
|
|
|
|
|
{
|
|
|
|
|
filePath = keyValuePair.Value[0];
|
|
|
|
|
if (filePath.Id is null)
|
|
|
|
|
continue;
|
|
|
|
|
directoryNames = keyValuePair.Value.Select(l => l.DirectoryFullPath.Replace('\\', '/')).ToArray();
|
|
|
|
|
paddedId = IId.GetPaddedId(propertyConfiguration, filePath.Id.Value, filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal, index: null);
|
|
|
|
|
identifier = new(directoryNames, filePath.HasDateTimeOriginal, filePath.Id.Value, filePath.Length, paddedId, filePath.LastWriteTicks);
|
|
|
|
|
identifiers.Add(identifier);
|
|
|
|
|
for (int i = 0; i < keyValuePair.Value.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
filePath = keyValuePair.Value[0];
|
|
|
|
|
if (filePath.Id is null)
|
|
|
|
|
continue;
|
|
|
|
|
directoryNames = keyValuePair.Value.Select(l => l.DirectoryFullPath.Replace('\\', '/')).ToArray();
|
|
|
|
|
paddedId = IId.GetPaddedId(propertyConfiguration, filePath.Id.Value, filePath.HasIgnoreKeyword, filePath.HasDateTimeOriginal, index: null);
|
|
|
|
|
identifier = new(directoryNames, filePath.ExtensionLowered, filePath.HasDateTimeOriginal, filePath.Id.Value, filePath.Length, paddedId, filePath.LastWriteTicks);
|
|
|
|
|
if (i == 0)
|
|
|
|
|
identifiers.Add(identifier);
|
|
|
|
|
if (!filePath.FullName.Contains(" !9"))
|
|
|
|
|
continue;
|
|
|
|
|
fileInfo = new(filePath.FullName);
|
|
|
|
|
fileHolder = Shared.Models.Stateless.Methods.IFileHolder.Get(fileInfo);
|
|
|
|
|
if (!fileInfo.Attributes.HasFlag(FileAttributes.Hidden))
|
|
|
|
|
File.SetAttributes(fileHolder.FullName, FileAttributes.Hidden);
|
|
|
|
|
if (distinct.Contains(keyValuePair.Key))
|
|
|
|
|
continue;
|
|
|
|
|
distinct.Add(keyValuePair.Key);
|
|
|
|
|
results.Add(keyValuePair.Key, identifier);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
string json = JsonSerializer.Serialize((from l in identifiers orderby l.DirectoryNames.Length descending, l.Id select l).ToArray(), IdentifierCollectionSourceGenerationContext.Default.IdentifierArray);
|
|
|
|
|
json = JsonSerializer.Serialize(results.Values.ToArray(), IdentifierCollectionSourceGenerationContext.Default.IdentifierArray);
|
|
|
|
|
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(bMetadataCollectionDirectory, "!9.json"), json, updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
|
|
|
|
|
json = JsonSerializer.Serialize((from l in identifiers orderby l.DirectoryNames.Length descending, l.Id select l).ToArray(), IdentifierCollectionSourceGenerationContext.Default.IdentifierArray);
|
|
|
|
|
_ = Shared.Models.Stateless.Methods.IPath.WriteAllText(Path.Combine(bMetadataCollectionDirectory, ".json"), json.Replace(rootDirectory, string.Empty), updateDateWhenMatches: false, compareBeforeWrite: true, updateToWhenMatches: null);
|
|
|
|
|
}
|
|
|
|
|
return new(results);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ReadOnlyCollection<Mapping> GetMappings(Property.Models.Configuration propertyConfiguration, string eDistanceContentDirectory, ReadOnlyCollection<Container> readOnlyContainers, MapLogic mapLogic, bool distinctItems)
|
|
|
|
@ -1053,7 +1051,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
|
|
|
|
|
isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
|
|
|
|
|
mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson);
|
|
|
|
|
}
|
|
|
|
|
mapping = new(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection);
|
|
|
|
|
mapping = Mapping.Get(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection);
|
|
|
|
|
notMapped += mapLogic.UpdateMappingFromPerson(wholePercentagesToPersonContainers, mapping);
|
|
|
|
|
face.SetMapping(mapping);
|
|
|
|
|
}
|
|
|
|
@ -1113,7 +1111,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
|
|
|
|
|
bool? canReMap = Map.Models.Stateless.Methods.IMapLogic.CanReMap(jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
|
|
|
|
|
bool? isFocusPerson = mapLogic.IsFocusPerson(_Configuration.SkipPersonWithMoreThen, jLinkResolvedPersonKeys, wholePercentagesToPersonContainers, mappingFromLocation);
|
|
|
|
|
MappingFromFilterPost mappingFromFilterPost = new(canReMap, inSkipCollection, isFocusPerson);
|
|
|
|
|
result = new(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection: null);
|
|
|
|
|
result = Mapping.Get(item.FilePath, mappingFromFilterPost, mappingFromFilterPre, mappingFromItem, mappingFromLocation, mappingFromPhotoPrismCollection: null);
|
|
|
|
|
int notMapped = mapLogic.UpdateMappingFromPerson(wholePercentagesToPersonContainers, result);
|
|
|
|
|
return (result, notMapped);
|
|
|
|
|
}
|
|
|
|
@ -1494,7 +1492,7 @@ public partial class DlibDotNet : IDlibDotNet, IDisposable
|
|
|
|
|
string filesCollectionRootDirectory = _Configuration.PropertyConfiguration.RootDirectory;
|
|
|
|
|
(string cResultsFullGroupDirectory, _, _, _) = GetResultsFullGroupDirectories(outputResolution);
|
|
|
|
|
IReadOnlyDictionary<string, ReadOnlyCollection<string>> fileGroups = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_Configuration.PropertyConfiguration, cResultsFullGroupDirectory, [_Configuration.PropertyConfiguration.ResultContent, _Configuration.PropertyConfiguration.ResultContentCollection]);
|
|
|
|
|
ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, filesCollectionRootDirectory, directorySearchFilter, fileSearchFilter, useCeilingAverage: false);
|
|
|
|
|
ReadOnlyCollection<ReadOnlyCollection<FilePath>> filePathsCollection = IDirectory.GetFilePathCollections(_Configuration.PropertyConfiguration, directorySearchFilter, fileSearchFilter, filesCollectionRootDirectory, useCeilingAverage: false);
|
|
|
|
|
int count = filePathsCollection.Select(l => l.Count).Sum();
|
|
|
|
|
bool filesCollectionCountIsOne = IsFilesCollectionCountIsOne(filePathsCollection);
|
|
|
|
|
string message = $") Selecting for ## pattern directory - {(int)Math.Floor(new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds)} total second(s)";
|
|
|
|
|