/// <summary> /// Runs the organizer by recursively searching every directory from the given <paramref name="inputDirectory" />. /// </summary> /// <param name="inputDirectory">Path to initial directory to search for media files.</param> /// <param name="database">Indicates whether a database is used.</param> public async Task RunOrganizerAsync(string inputDirectory) { // if input directory does not exist, throw exception and end run inputDirectory.EnsureDirectoryExists(); // preliminary setup var hashAlgorithm = _configuration.GetValue <Algorithm>("hash-algorithm"); var checksum = new Checksum(hashAlgorithm); var photoCounter = 0; if (!(_context is null)) { await _context.Database.EnsureCreatedAsync(); } _logger.LogInformation($"Begin organizing in { inputDirectory }"); await foreach (var photo in PhotoHandler.FindPhotosAsync(inputDirectory)) { using var fs = File.OpenRead(photo.FilePath); // Compute checksum photo.Checksum = checksum.ComputeChecksum(fs); // Reset filestream position fs.Position = 0; // Fetch metadata directories using MetadataExctractor and parse metadata to the Photo object var metadataDirectories = ImageMetadataReader.ReadMetadata(fs); ParseMetadata.Parse(photo, metadataDirectories); // Rename and sort photos _sortService.SortPhoto(photo); // Add photo to database context if it does not exist already if (!(_context is null) && !await _context.Photos.AnyAsync(p => p.Name == photo.Name)) { await _context.Photos.AddAsync(photo); } photoCounter++; } if (!(_context is null)) { // Save all additions to the database await _context.SaveChangesAsync(); } _logger.LogInformation($"End organizing. Organized { photoCounter } photos."); }