添加新的表情包
This commit is contained in:
@@ -4,9 +4,15 @@ import { fileURLToPath } from "node:url";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const repoRoot = path.join(__dirname, "..");
|
||||
const sourceDir = path.join(repoRoot, "原图");
|
||||
const publicMeme = path.join(repoRoot, "public", "meme");
|
||||
const outFile = path.join(repoRoot, "public", "memes.json");
|
||||
const rawDir = path.join(repoRoot, "原图");
|
||||
const processedDir = path.join(repoRoot, "原图-已处理");
|
||||
const publicDir = path.join(repoRoot, "public");
|
||||
const distDir = path.join(repoRoot, "dist");
|
||||
const publicMeme = path.join(publicDir, "meme");
|
||||
const distMeme = path.join(distDir, "meme");
|
||||
const argv = process.argv.slice(2);
|
||||
/** 强制从 原图-已处理/原图 扫描清单(忽略 public/meme 里已有素材) */
|
||||
const manifestFromSource = argv.includes("--manifest-from-source");
|
||||
|
||||
const NUMBERED_ASSET_RE = /^(\d+)\.(webp|gif)$/i;
|
||||
|
||||
@@ -36,20 +42,51 @@ function copyTreeIterative(srcDir, destDir) {
|
||||
return files;
|
||||
}
|
||||
|
||||
function syncSourceToPublic() {
|
||||
console.log("build: mirroring 原图/ -> public/meme/ ...");
|
||||
if (!fs.existsSync(sourceDir)) {
|
||||
console.warn("原图/ not found — 请先运行 convert_to_webp.py,或保留 public/meme");
|
||||
return false;
|
||||
/**
|
||||
* 清空并重建 dist/:复制 public/(需已写好 public/memes.json),再确保 dist/memes.json 一致。
|
||||
*/
|
||||
function rebuildDist(manifestJson) {
|
||||
if (!fs.existsSync(publicDir)) {
|
||||
console.warn("public/ not found — only writing dist/memes.json");
|
||||
fs.mkdirSync(distDir, { recursive: true });
|
||||
fs.writeFileSync(path.join(distDir, "memes.json"), manifestJson, "utf8");
|
||||
return;
|
||||
}
|
||||
fs.mkdirSync(path.dirname(publicMeme), { recursive: true });
|
||||
if (fs.existsSync(publicMeme)) {
|
||||
fs.rmSync(publicMeme, { recursive: true, force: true });
|
||||
if (fs.existsSync(distDir)) {
|
||||
fs.rmSync(distDir, { recursive: true, force: true });
|
||||
}
|
||||
fs.mkdirSync(publicMeme, { recursive: true });
|
||||
const n = copyTreeIterative(sourceDir, publicMeme);
|
||||
console.log(`synced 原图/ -> public/meme/ (${n} files copied)`);
|
||||
return true;
|
||||
fs.mkdirSync(distDir, { recursive: true });
|
||||
const n = copyTreeIterative(publicDir, distDir);
|
||||
fs.writeFileSync(path.join(distDir, "memes.json"), manifestJson, "utf8");
|
||||
console.log(`build: public/ -> dist/ (${n} files), dist/memes.json written`);
|
||||
}
|
||||
|
||||
function pickManifestRoot() {
|
||||
if (fs.existsSync(processedDir)) return processedDir;
|
||||
return rawDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* 部署时以 public/meme 为准(你手动拷入的成品);本地未拷素材时仍可从 原图-已处理 生成清单。
|
||||
*/
|
||||
function resolveScanRoot() {
|
||||
if (manifestFromSource) {
|
||||
const primary = pickManifestRoot();
|
||||
if (fs.existsSync(primary)) return { root: primary, label: primary === processedDir ? "原图-已处理/" : "原图/" };
|
||||
if (fs.existsSync(publicMeme)) return { root: publicMeme, label: "public/meme/ (--manifest-from-source 但源目录缺失,回退)" };
|
||||
if (fs.existsSync(distMeme)) return { root: distMeme, label: "dist/meme/ (回退)" };
|
||||
return { root: null, label: "" };
|
||||
}
|
||||
if (countPublicMemeNumberedFiles() > 0) {
|
||||
return { root: publicMeme, label: "public/meme/" };
|
||||
}
|
||||
const primary = pickManifestRoot();
|
||||
if (fs.existsSync(primary)) {
|
||||
return { root: primary, label: primary === processedDir ? "原图-已处理/" : "原图/" };
|
||||
}
|
||||
if (fs.existsSync(publicMeme)) return { root: publicMeme, label: "public/meme/" };
|
||||
if (fs.existsSync(distMeme)) return { root: distMeme, label: "dist/meme/" };
|
||||
return { root: null, label: "" };
|
||||
}
|
||||
|
||||
/** @param {string} dirPath */
|
||||
@@ -65,10 +102,25 @@ function listNumberedAssets(dirPath) {
|
||||
});
|
||||
}
|
||||
|
||||
function main() {
|
||||
syncSourceToPublic();
|
||||
/** 统计 public/meme 下已存在的编号素材数量(与图库实际可加载文件一致) */
|
||||
function countPublicMemeNumberedFiles() {
|
||||
if (!fs.existsSync(publicMeme)) return 0;
|
||||
let n = 0;
|
||||
for (const ent of fs.readdirSync(publicMeme, { withFileTypes: true })) {
|
||||
if (!ent.isDirectory()) continue;
|
||||
const dirPath = path.join(publicMeme, ent.name);
|
||||
for (const f of fs.readdirSync(dirPath)) {
|
||||
if (NUMBERED_ASSET_RE.test(f)) n += 1;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
const scanRoot = fs.existsSync(publicMeme) ? publicMeme : sourceDir;
|
||||
function main() {
|
||||
const { root: scanRoot, label: scanLabel } = resolveScanRoot();
|
||||
console.log(
|
||||
`build: memes.json 扫描自 ${scanLabel || "(无)"}(不修改 public/meme/;素材请自行拷入)`
|
||||
);
|
||||
|
||||
/** @type {{ generatedAt: string; categories: Array<{ id: string; name: string; items: Array<{ file: string; path: string }> }> }} */
|
||||
const payload = {
|
||||
@@ -76,7 +128,7 @@ function main() {
|
||||
categories: [],
|
||||
};
|
||||
|
||||
if (fs.existsSync(scanRoot)) {
|
||||
if (scanRoot && fs.existsSync(scanRoot)) {
|
||||
const dirs = fs.readdirSync(scanRoot, { withFileTypes: true });
|
||||
for (const ent of dirs) {
|
||||
if (!ent.isDirectory()) continue;
|
||||
@@ -96,10 +148,26 @@ function main() {
|
||||
}
|
||||
|
||||
payload.categories.sort((a, b) => a.id.localeCompare(b.id, "zh-Hans-CN"));
|
||||
fs.mkdirSync(path.dirname(outFile), { recursive: true });
|
||||
fs.writeFileSync(outFile, `${JSON.stringify(payload, null, 2)}\n`, "utf8");
|
||||
const n = payload.categories.reduce((acc, c) => acc + c.items.length, 0);
|
||||
const onDisk = countPublicMemeNumberedFiles();
|
||||
const scannedPublicMeme = scanRoot === publicMeme;
|
||||
if (!scannedPublicMeme && onDisk > 0 && onDisk < n) {
|
||||
console.warn(
|
||||
`警告: 清单来自「${scanLabel.replace(/\/$/, "")}」共 ${n} 个编号素材,但 public/meme/ 里只有 ${onDisk} 个;部署请把「原图-已处理」整夹拷进 public/meme/ 后再 build,或删空 public/meme 仅用源目录清单。`
|
||||
);
|
||||
} else if (n > 0 && onDisk === 0 && fs.existsSync(publicMeme)) {
|
||||
console.warn(
|
||||
"警告: public/meme/ 存在但未发现编号 .webp/.gif,图库可能没有图片。"
|
||||
);
|
||||
}
|
||||
|
||||
const json = `${JSON.stringify(payload, null, 2)}\n`;
|
||||
fs.mkdirSync(publicDir, { recursive: true });
|
||||
fs.writeFileSync(path.join(publicDir, "memes.json"), json, "utf8");
|
||||
rebuildDist(json);
|
||||
|
||||
console.log(`manifest: ${payload.categories.length} categories, ${n} assets (webp/gif)`);
|
||||
console.log(`wrote public/memes.json + dist/memes.json;public/meme/ 中现有 ${onDisk} 个可加载素材`);
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user