photo-file-organizer/Src/PhotoFileOrganizer/FileOrganizerCommand.cs

113 lines
4.0 KiB
C#

using Directory = System.IO.Directory;
using MetadataExtractor.Formats.Exif;
using MetadataExtractor;
namespace PhotoFileOrganizer;
internal class FileOrganizerCommand
{
public FileOrganizerCommand(FileOrganizerOptions options)
{
if (string.IsNullOrEmpty(options.InputPath) || !Directory.Exists(options.InputPath)) throw new Exception($"null input path");
if (string.IsNullOrEmpty(options.OutputPath)) throw new Exception($"null output path");
this.InputPath = options.InputPath;
this.OutputPath = options.OutputPath;
}
public string InputPath { get; }
public string OutputPath { get; }
public void Execute()
{
try
{
OrganizeFilesByExif(InputPath, OutputPath);
OrganizeFilesByCreationDate(InputPath, OutputPath);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
private void OrganizeFilesByExif(string rootFolder, string saveRootFolder)
{
string[] allFiles = Directory.GetFiles(rootFolder, "*", SearchOption.AllDirectories);
foreach (var filePath in allFiles)
{
try
{
var directories = ImageMetadataReader.ReadMetadata(filePath);
var dateString = string.Empty;
//foreach (var directory in directories)
// foreach (var tag in directory.Tags)
// Console.WriteLine($"{directory.Name} - {tag.Name} = {tag.Description}");
GetExifTag(directories, ExifDirectoryBase.TagDateTime, ref dateString);
GetExifTag(directories, ExifDirectoryBase.TagDateTimeOriginal, ref dateString);
GetExifTag(directories, ExifDirectoryBase.TagDateTimeDigitized, ref dateString);
if (string.IsNullOrEmpty(dateString)) throw new Exception("can not read exif");
var dateTaken = DateTime.ParseExact(dateString, "yyyy:MM:dd HH:mm:ss", null);
var destinationFolder = Path.Combine(saveRootFolder, $"{dateTaken:yyyy}", $"{dateTaken:MM}");
MoveFileToFolder(filePath, destinationFolder);
}
catch (Exception ex)
{
// Exif 정보를 읽을 수 없는 경우 또는 다른 이유로 예외가 발생한 경우
Console.WriteLine($"Failed to read Exif information for file: {filePath}. Error: {ex.Message}");
}
}
}
private void OrganizeFilesByCreationDate(string rootFolder, string saveRootFolder)
{
var allFiles = Directory.GetFiles(rootFolder, "*", SearchOption.AllDirectories);
foreach (var filePath in allFiles)
{
var creationDate = File.GetCreationTime(filePath);
var destinationFolder = Path.Combine(saveRootFolder, $"{creationDate:yyyy}", $"{creationDate:MM}");
MoveFileToFolder(filePath, destinationFolder);
}
}
private void MoveFileToFolder(string filePath, string destinationFolder)
{
if (!Directory.Exists(destinationFolder))
{
Directory.CreateDirectory(destinationFolder);
}
var fileName = Path.GetFileName(filePath);
var destinationPath = Path.Combine(destinationFolder, fileName);
if (!File.Exists(destinationPath))
{
File.Move(filePath, destinationPath);
Console.WriteLine($"Moved file {fileName} to {destinationFolder}");
}
else
{
Console.WriteLine($"File {fileName} already exists in {destinationFolder}");
}
}
private void GetExifTag(IReadOnlyList<MetadataExtractor.Directory> directories, int tag, ref string result)
{
if (!string.IsNullOrEmpty(result)) return;
foreach (var directory in directories.OfType<ExifSubIfdDirectory>())
{
var date = directory.GetDescription(tag);
if (string.IsNullOrEmpty(date)) continue;
result = date;
break;
}
}
}