113 lines
4.0 KiB
C#
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;
|
|
}
|
|
}
|
|
} |