process_zip_files/lib/index.js

222 lines
8.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const child_process_1 = require("child_process");
const adm_zip_1 = __importDefault(require("adm-zip"));
const DISALLOWED_EXTENSIONS = new Set([
".exe",
".o",
".class",
".bin",
".dll",
".vcxproj",
".filters",
".user",
".sln",
]);
const DISALLOWED_KEYWORDS = new Set(["a.out", "main", "temp"]);
const DISALLOWED_DIRECTORIES = new Set([
".vs",
".idea",
"__pycache__",
"node_modules",
".git",
"x64",
"x86",
"__MACOSX",
".vscode",
]);
let deletedItems = [];
// 清理文件名
const sanitizeFileName = (fileName) => {
// 对文件名进行标准化处理,解决编码问题
const decodedName = fileName.toString("utf8");
return decodedName;
};
// 检查是否是压缩文件
const isCompressedFile = (filePath) => {
return (filePath.endsWith(".zip") ||
filePath.endsWith(".7z") ||
filePath.endsWith(".rar"));
};
// 测试是否安装了7z和unrar
const preTest = () => {
try {
(0, child_process_1.execSync)("7z --help");
}
catch (e) {
console.error("[ERROR] 7z 未安装,请先安装 7z。");
process.exit(1);
}
try {
(0, child_process_1.execSync)("unrar");
}
catch (e) {
console.error("[ERROR] unrar 未安装,请先安装 unrar。");
process.exit(1);
}
};
// 检查文件是否可能是Linux可执行文件无后缀的二进制
const isLinuxExecutable = (filePath) => {
if (fs_1.default.statSync(filePath).isFile() && path_1.default.extname(filePath) === "") {
const stats = fs_1.default.statSync(filePath);
return (stats.mode & 0o111) !== 0;
}
return false;
};
// 使用7z解压文件
const extractUsing7z = (filePath, extractTo) => {
console.log(`[INFO] 使用 7z 解压文件: ${filePath} 到目录: ${extractTo}`);
if (!fs_1.default.existsSync(extractTo)) {
fs_1.default.mkdirSync(extractTo, { recursive: true });
}
try {
(0, child_process_1.execSync)(`7z x "${filePath}" -o"${extractTo}"`);
console.log(`[INFO] 解压完成: ${filePath}`);
}
catch (e) {
console.error(`[ERROR] 解压失败: ${e}`);
}
};
// 使用unrar解压文件
const extractRar = (filePath, extractTo) => {
console.log(`[INFO] 使用 unrar 解压文件: ${filePath} 到目录: ${extractTo}`);
if (!fs_1.default.existsSync(extractTo)) {
fs_1.default.mkdirSync(extractTo, { recursive: true });
}
try {
(0, child_process_1.execSync)(`unrar x -o+ "${filePath}" "${extractTo}"`);
console.log(`[INFO] 解压完成: ${filePath}`);
}
catch (e) {
console.error(`[ERROR] 解压失败: ${e}`);
}
};
/**
* 解压缩文件
* @param inputDirectory 输入目录
* @param outputDirectory 输出目录
* @deprecated 存在编码问题,暂时不使用
*/
const extractZip = (filePath, extractTo) => {
console.log(`[INFO] 解压缩文件: ${filePath} 到目录: ${extractTo}`);
if (!fs_1.default.existsSync(extractTo)) {
fs_1.default.mkdirSync(extractTo, { recursive: true });
}
const zip = new adm_zip_1.default(filePath);
// 遍历所有的文件条目,清理文件名中的非法字符
zip.getEntries().forEach((entry) => {
if (entry.entryName) {
try {
// 清理文件名中的非法字符
const sanitizedName = sanitizeFileName(entry.rawEntryName);
entry.entryName = sanitizedName; // 更新文件名
}
catch (e) {
console.error(`[ERROR] 解压时处理文件名失败: ${entry.entryName}`);
}
}
});
// 解压文件
zip.extractAllTo(extractTo, true);
};
// 递归处理目录并过滤文件
const processDirectory = (inputDirectory, outputDirectory) => {
console.log(`[INFO] 开始处理目录: ${inputDirectory}`);
fs_1.default.readdirSync(inputDirectory).forEach((item) => {
const itemPath = path_1.default.join(inputDirectory, item);
const stat = fs_1.default.statSync(itemPath);
if (stat.isDirectory()) {
// 排除不需要的目录
if (DISALLOWED_DIRECTORIES.has(item)) {
deletedItems.push(`目录: ${itemPath}`);
fs_1.default.rmdirSync(itemPath, { recursive: true });
console.log(`[DELETE] 删除目录: ${itemPath}`);
}
else {
// 创建对应的输出目录
const outputDirPath = path_1.default.join(outputDirectory, item);
if (!fs_1.default.existsSync(outputDirPath)) {
fs_1.default.mkdirSync(outputDirPath, { recursive: true });
}
processDirectory(itemPath, outputDirPath); // 递归处理子目录
}
}
else if (stat.isFile()) {
const ext = path_1.default.extname(item).toLowerCase();
// 如果是压缩文件,解压后递归处理
if (isCompressedFile(itemPath)) {
const relativePath = path_1.default.relative(inputDirectory, path_1.default.dirname(itemPath));
const outputDirPath = path_1.default.join(outputDirectory, relativePath, path_1.default.basename(itemPath, path_1.default.extname(itemPath)) +
"_extracted");
if (!fs_1.default.existsSync(outputDirPath)) {
fs_1.default.mkdirSync(outputDirPath, { recursive: true });
}
if (itemPath.endsWith(".zip")) {
// extractZip(itemPath, outputDirPath); // 存在编码问题,暂时不使用
extractUsing7z(itemPath, outputDirPath);
}
else if (itemPath.endsWith(".7z")) {
extractUsing7z(itemPath, outputDirPath);
}
else if (itemPath.endsWith(".rar")) {
extractRar(itemPath, outputDirPath);
}
// 递归处理解压后的内容
processDirectory(outputDirPath, outputDirPath);
// 重新压缩处理后的内容
const outputZip = path_1.default.join(outputDirectory, relativePath, path_1.default.basename(itemPath));
const zip = new adm_zip_1.default();
zip.addLocalFolder(outputDirPath);
zip.writeZip(outputZip);
// 删除临时目录
console.log(`[DELETE] 删除临时目录: ${outputDirPath}`);
fs_1.default.rmSync(outputDirPath, { recursive: true, force: true });
}
else if (DISALLOWED_EXTENSIONS.has(ext) ||
DISALLOWED_KEYWORDS.has(item) ||
isLinuxExecutable(itemPath)) {
console.log(`[DELETE] 删除文件: ${itemPath}`);
deletedItems.push(`文件: ${itemPath}`);
fs_1.default.rmSync(itemPath); // 删除不需要的文件
}
else {
// 将文件复制到对应的输出目录
const outputFilePath = path_1.default.join(outputDirectory, item);
fs_1.default.copyFileSync(itemPath, outputFilePath);
console.log(`[KEEP] 保留文件: ${itemPath} 并复制到 ${outputFilePath}`);
}
}
});
};
// 写入统计文件
const writeLog = (outputDirectory) => {
const logFile = path_1.default.join(outputDirectory, "result_log.txt");
fs_1.default.writeFileSync(logFile, "以下是被删除的目录和文件列表:\n");
fs_1.default.appendFileSync(logFile, deletedItems.join("\n"));
console.log(`[INFO] 统计文件已生成: ${logFile}`);
};
// 主函数
const main = () => {
preTest(); // 测试是否安装了7z和unrar
const inputDirectory = path_1.default.join(process.cwd(), "in"); // 输入文件夹
const outputDirectory = path_1.default.join(process.cwd(), "out"); // 输出文件夹
if (!fs_1.default.existsSync(inputDirectory)) {
console.error(`[ERROR] 输入目录 'in' 不存在,请检查。`);
return;
}
if (fs_1.default.existsSync(outputDirectory)) {
fs_1.default.rmSync(outputDirectory, { recursive: true }); // 清空输出目录
}
fs_1.default.mkdirSync(outputDirectory, { recursive: true });
console.log("[INFO] 开始处理压缩文件...");
processDirectory(inputDirectory, outputDirectory);
writeLog(outputDirectory);
console.log('[INFO] 处理完成!结果保存在 "out" 目录中。');
};
main();
//# sourceMappingURL=index.js.map