/// <summary> /// Update ExifTool, Thumbnail, Database and if needed rotateClock /// </summary> /// <param name="fileIndexItem">output database object</param> /// <param name="comparedNamesList">name of fields updated by exifTool</param> /// <param name="rotateClock">rotation value (if needed)</param> private async Task UpdateWriteDiskDatabase(FileIndexItem fileIndexItem, List <string> comparedNamesList, int rotateClock = 0) { // do rotation on thumbs await RotationThumbnailExecute(rotateClock, fileIndexItem); if (fileIndexItem.IsDirectory != true && ExtensionRolesHelper.IsExtensionExifToolSupported(fileIndexItem.FileName)) { // feature to exif update var exifUpdateFilePaths = new List <string> { fileIndexItem.FilePath }; var exifTool = new ExifToolCmdHelper(_exifTool, _iStorage, _thumbnailStorage, _readMeta); // to avoid diskWatcher catch up _query.SetGetObjectByFilePathCache(fileIndexItem.FilePath, fileIndexItem, TimeSpan.FromSeconds(10)); // Do an Exif Sync for all files, including thumbnails var(exifResult, newFileHashes) = await exifTool.UpdateAsync(fileIndexItem, exifUpdateFilePaths, comparedNamesList, true, true); await ApplyOrGenerateUpdatedFileHash(newFileHashes, fileIndexItem); _logger.LogInformation(string.IsNullOrEmpty(exifResult) ? $"[UpdateWriteDiskDatabase] ExifTool result is Nothing or " + $"Null for: path:{fileIndexItem.FilePath} {DateTime.UtcNow.ToShortTimeString()}" : $"[UpdateWriteDiskDatabase] ExifTool result: {exifResult} path:{fileIndexItem.FilePath}"); } else { await new FileIndexItemJsonParser(_iStorage).WriteAsync(fileIndexItem); } // Do a database sync + cache sync // Clone to avoid reference when cache exist await _query.UpdateItemAsync(fileIndexItem.Clone()); // > async > force you to read the file again // do not include thumbs in MetaCache // only the full path url of the source image _readMeta.RemoveReadMetaCache(fileIndexItem.FilePath); }
/// <summary> /// Run Transformation on Import to the files in the database && Update fileHash in database /// </summary> /// <param name="queryUpdateDelegate"></param> /// <param name="fileIndexItem">information</param> /// <param name="colorClassTransformation">change colorClass</param> /// <param name="dateTimeParsedFromFileName">is date time parsed from fileName</param> /// <param name="indexMode">should update database</param> internal async Task <FileIndexItem> UpdateTransformations(QueryUpdateDelegate queryUpdateDelegate, FileIndexItem fileIndexItem, int colorClassTransformation, bool dateTimeParsedFromFileName, bool indexMode) { if (!ExtensionRolesHelper.IsExtensionExifToolSupported(fileIndexItem.FileName)) { return(fileIndexItem); } var comparedNamesList = new List <string>(); if (dateTimeParsedFromFileName) { _logger.LogInformation($"[Import] DateTimeParsedFromFileName ExifTool Sync {fileIndexItem.FilePath}"); comparedNamesList = DateTimeParsedComparedNamesList(); } if (colorClassTransformation >= 0) { _logger.LogInformation($"[Import] ColorClassComparedNamesList ExifTool Sync {fileIndexItem.FilePath}"); comparedNamesList = ColorClassComparedNamesList(comparedNamesList); } if (!comparedNamesList.Any()) { return(fileIndexItem); } await new ExifToolCmdHelper(_exifTool, _subPathStorage, _thumbnailStorage, new ReadMeta(_subPathStorage, _appSettings)).UpdateAsync(fileIndexItem, comparedNamesList); // Only update database when indexMode is true if (!indexMode || queryUpdateDelegate == null) { return(fileIndexItem); } // Hash is changed after transformation fileIndexItem.FileHash = (await new FileHash(_subPathStorage).GetHashCodeAsync(fileIndexItem.FilePath)).Key; await queryUpdateDelegate(fileIndexItem); return(fileIndexItem.Clone()); }
/// <summary> /// Checks for files that already done /// if latitude is not location 0,0, That's default /// If one of the meta items are missing, keep in list /// If extension in exifTool supported, so no gpx /// </summary> /// <param name="metaFilesInDirectory">List of files with metadata</param> /// <param name="overwriteLocationNames">true = overwrite the location names, that have a gps location </param> /// <returns>list that can be updated</returns> public List <FileIndexItem> RemoveNoUpdateItems(IEnumerable <FileIndexItem> metaFilesInDirectory, bool overwriteLocationNames) { // this will overwrite the location names, that have a gps location if (overwriteLocationNames) { return(metaFilesInDirectory.Where( metaFileItem => Math.Abs(metaFileItem.Latitude) > 0.001 && Math.Abs(metaFileItem.Longitude) > 0.001) .ToList()); } // the default situation return(metaFilesInDirectory.Where( metaFileItem => ((Math.Abs(metaFileItem.Latitude) > 0.001 && Math.Abs(metaFileItem.Longitude) > 0.001) && (string.IsNullOrEmpty(metaFileItem.LocationCity) || string.IsNullOrEmpty(metaFileItem.LocationState) || string.IsNullOrEmpty(metaFileItem.LocationCountry))) && ExtensionRolesHelper.IsExtensionExifToolSupported(metaFileItem.FileName) ).ToList()); }
/// <summary> /// Write to ExifTool by list /// </summary> /// <param name="metaFilesInDirectory">list of files with data</param> /// <param name="syncLocationNames">Write city, state and country to exifTool (false > no)</param> public async Task LoopFolderAsync(List <FileIndexItem> metaFilesInDirectory, bool syncLocationNames) { foreach (var metaFileItem in metaFilesInDirectory.Where(metaFileItem => ExtensionRolesHelper.IsExtensionExifToolSupported(metaFileItem.FileName))) { if (_appSettings.IsVerbose()) { _console.Write(" 👟 "); } var comparedNamesList = new List <string> { nameof(FileIndexItem.Latitude).ToLowerInvariant(), nameof(FileIndexItem.Longitude).ToLowerInvariant(), nameof(FileIndexItem.LocationAltitude).ToLowerInvariant() }; if (syncLocationNames) { comparedNamesList.AddRange(new List <string> { nameof(FileIndexItem.LocationCity).ToLowerInvariant(), nameof(FileIndexItem.LocationState).ToLowerInvariant(), nameof(FileIndexItem.LocationCountry).ToLowerInvariant(), }); } await new ExifToolCmdHelper(_exifTool, _iStorage, _thumbnailStorage, new ReadMeta(_iStorage)).UpdateAsync(metaFileItem, comparedNamesList); // Rocket man! _console.Write(_appSettings.IsVerbose() ? $" GeoLocationWrite: {metaFileItem.FilePath} " : "🚀"); } }
public void IsExtensionExifToolSupported_fileWithNoExtension() { var result = ExtensionRolesHelper.IsExtensionExifToolSupported("no_ext"); Assert.IsFalse(result); }
public void IsExtensionExifToolSupported_Null() { var result = ExtensionRolesHelper.IsExtensionExifToolSupported(null); Assert.IsFalse(result); }
public List <FileIndexItem> GetInfo(List <string> inputFilePaths, bool collections) { // the result list var fileIndexResultsList = new List <FileIndexItem>(); foreach (var subPath in inputFilePaths) { var detailView = _query.SingleItem(subPath, null, collections, false); if (detailView?.FileIndexItem == null) { StatusCodesHelper.ReturnExifStatusError(new FileIndexItem(subPath), FileIndexItem.ExifStatus.NotFoundNotInIndex, fileIndexResultsList); continue; } if (!_iStorage.ExistFile(detailView.FileIndexItem.FilePath)) { StatusCodesHelper.ReturnExifStatusError(detailView.FileIndexItem, FileIndexItem.ExifStatus.NotFoundSourceMissing, fileIndexResultsList); continue; } // Check if extension is supported for ExtensionExifToolSupportedList // Not all files are able to write with exifTool if (!ExtensionRolesHelper.IsExtensionExifToolSupported(detailView.FileIndexItem.FileName)) { StatusCodesHelper.ReturnExifStatusError( new FileIndexItemJsonParser(_iStorage).Read(detailView.FileIndexItem), FileIndexItem.ExifStatus.ExifWriteNotSupported, fileIndexResultsList); continue; } var statusResults = StatusCodesHelper.IsDeletedStatus(detailView); // only when default status to avoid unneeded checks if (statusResults == FileIndexItem.ExifStatus.Default) { statusResults = _statusCodeHelper.IsReadOnlyStatus(detailView); } // when everything is checked, it should be good if (statusResults == FileIndexItem.ExifStatus.Default) { statusResults = FileIndexItem.ExifStatus.Ok; } var collectionSubPathList = DetailView.GetCollectionSubPathList(detailView.FileIndexItem, collections, subPath); foreach (var collectionSubPath in collectionSubPathList) { var collectionItem = _readMeta.ReadExifAndXmpFromFile(collectionSubPath); collectionItem.Status = statusResults; collectionItem.CollectionPaths = collectionSubPathList; collectionItem.ImageFormat = ExtensionRolesHelper.MapFileTypesToExtension(collectionSubPath); collectionItem.Size = _iStorage.Info(collectionSubPath).Size; fileIndexResultsList.Add(collectionItem); } } return(fileIndexResultsList); }