리펙토링 - 전체 프로젝트 코드 (Codex)

This commit is contained in:
2026-05-17 22:18:01 +09:00
parent 5337ea221b
commit 0f72f4a0f0
16 changed files with 508 additions and 356 deletions
+59
View File
@@ -0,0 +1,59 @@
const fs = require('fs');
const path = require('path');
const IMAGE_EXTENSIONS = new Set(['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.tif', '.webp', '.heic', '.heif']);
function listImages(folderPath) {
return fs.readdirSync(folderPath)
.filter(fileName => IMAGE_EXTENSIONS.has(path.extname(fileName).toLowerCase()))
.map(fileName => {
const fullPath = path.join(folderPath, fileName);
const stat = fs.statSync(fullPath);
return { name: fileName, path: fullPath, mtime: stat.mtimeMs };
})
.sort((a, b) => a.name.localeCompare(b.name, 'ko'));
}
function readImageAsDataUrl(filePath) {
const data = fs.readFileSync(filePath);
const mime = getImageMime(path.extname(filePath));
return `data:image/${mime};base64,${data.toString('base64')}`;
}
function getImageMime(extName) {
const ext = extName.toLowerCase().replace('.', '');
if (ext === 'jpg' || ext === 'jpeg') return 'jpeg';
if (ext === 'png') return 'png';
if (ext === 'gif') return 'gif';
if (ext === 'webp') return 'webp';
if (ext === 'tiff' || ext === 'tif') return 'tiff';
if (ext === 'bmp') return 'bmp';
if (ext === 'heic' || ext === 'heif') return 'heic';
return 'jpeg';
}
function fileExists(filePath) {
try {
fs.accessSync(filePath);
return true;
} catch {
return false;
}
}
function moveFileWithCopyFallback(src, dest) {
try {
fs.renameSync(src, dest);
} catch (e) {
if (e.code !== 'EXDEV') throw e;
fs.copyFileSync(src, dest);
fs.unlinkSync(src);
}
}
module.exports = {
fileExists,
listImages,
moveFileWithCopyFallback,
readImageAsDataUrl,
};
+16 -55
View File
@@ -2,21 +2,17 @@ const { ipcMain, app } = require('electron');
const path = require('path');
const fs = require('fs');
const crypto = require('crypto');
const EXTS = new Set(['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.tif', '.webp', '.heic', '.heif']);
const {
fileExists,
listImages,
moveFileWithCopyFallback,
readImageAsDataUrl,
} = require('./file-utils');
function register() {
ipcMain.handle('list-images', async (_event, folderPath) => {
try {
const files = fs.readdirSync(folderPath)
.filter(f => EXTS.has(path.extname(f).toLowerCase()))
.map(f => {
const fullPath = path.join(folderPath, f);
const stat = fs.statSync(fullPath);
return { name: f, path: fullPath, mtime: stat.mtimeMs };
})
.sort((a, b) => a.name.localeCompare(b.name, 'ko'));
return files;
return listImages(folderPath);
} catch (e) {
return [];
}
@@ -24,27 +20,14 @@ function register() {
ipcMain.handle('read-image', async (_event, filePath) => {
try {
const data = fs.readFileSync(filePath);
const ext = path.extname(filePath).toLowerCase().replace('.', '');
const mime = (ext === 'jpg' || ext === 'jpeg') ? 'jpeg'
: ext === 'png' ? 'png'
: ext === 'gif' ? 'gif'
: ext === 'webp' ? 'webp'
: (ext === 'tiff' || ext === 'tif') ? 'tiff'
: ext === 'bmp' ? 'bmp'
: (ext === 'heic' || ext === 'heif') ? 'heic'
: 'jpeg';
return `data:image/${mime};base64,${data.toString('base64')}`;
return readImageAsDataUrl(filePath);
} catch (e) {
return null;
}
});
ipcMain.handle('check-files-exist', (_event, folderPath, names) => {
return names.filter(name => {
try { fs.accessSync(path.join(folderPath, name)); return true; }
catch { return false; }
});
return names.filter(name => fileExists(path.join(folderPath, name)));
});
ipcMain.handle('move-files', async (_event, { targetFolder, files }) => {
@@ -54,20 +37,10 @@ function register() {
const destName = file.newName || file.name;
const dest = path.join(targetFolder, destName);
try {
fs.renameSync(file.path, dest);
moveFileWithCopyFallback(file.path, dest);
moved.push({ src: file.path, dest, name: destName });
} catch (e) {
if (e.code === 'EXDEV') {
try {
fs.copyFileSync(file.path, dest);
fs.unlinkSync(file.path);
moved.push({ src: file.path, dest, name: destName });
} catch (e2) {
errors.push(`${file.name}: ${e2.message}`);
}
} else {
errors.push(`${file.name}: ${e.message}`);
}
errors.push(`${file.name}: ${e.message}`);
}
}
return { moved, errors };
@@ -84,16 +57,10 @@ function register() {
const name = path.basename(fp);
const dest = path.join(batchDir, name);
try {
fs.renameSync(fp, dest);
moveFileWithCopyFallback(fp, dest);
staged.push({ name, originalPath: fp, stagingPath: dest });
} catch (e) {
if (e.code === 'EXDEV') {
try {
fs.copyFileSync(fp, dest);
fs.unlinkSync(fp);
staged.push({ name, originalPath: fp, stagingPath: dest });
} catch (e2) { errors.push(`${name}: ${e2.message}`); }
} else { errors.push(`${name}: ${e.message}`); }
errors.push(`${name}: ${e.message}`);
}
}
if (!staged.length) try { fs.rmdirSync(batchDir); } catch {}
@@ -111,16 +78,10 @@ function register() {
}
try {
fs.mkdirSync(path.dirname(originalPath), { recursive: true });
fs.renameSync(stagingPath, originalPath);
moveFileWithCopyFallback(stagingPath, originalPath);
restored.push(originalPath);
} catch (e) {
if (e.code === 'EXDEV') {
try {
fs.copyFileSync(stagingPath, originalPath);
fs.unlinkSync(stagingPath);
restored.push(originalPath);
} catch (e2) { errors.push(`${name}: ${e2.message}`); }
} else { errors.push(`${name}: ${e.message}`); }
errors.push(`${name}: ${e.message}`);
}
}
return { restored, errors };
@@ -161,4 +122,4 @@ function register() {
});
}
module.exports = { register };
module.exports = { register };