Files
zhuiguang-ai/scripts/bot-avatar-generate.mjs

86 lines
3.4 KiB
JavaScript
Raw Permalink 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.
#!/usr/bin/env node
// scripts/bot-avatar-generate.mjs
// 数字人头像批量预生成 + 落盘 + 回写 User.avatarUrl
//
// 用法:
// node scripts/bot-avatar-generate.mjs # 生成所有 bot 头像
// node scripts/bot-avatar-generate.mjs --bot=laochen # 只生成单个 bot
// node scripts/bot-avatar-generate.mjs --force # 强制重新生成(已存在也覆盖)
// node scripts/bot-avatar-generate.mjs --use-lunaris-only # 只用 Lunaris,不生成 SVG(当前 Lunaris 全是 default,不推荐)
// node scripts/bot-avatar-generate.mjs --no-update-db # 只落盘,不写 User.avatarUrl
// node scripts/bot-avatar-generate.mjs --dry-run # 试运行,不落盘不写库
import { disconnect, generateForAll } from "./lib/bot-avatar-generator.mjs";
function parseArgs() {
const args = process.argv.slice(2);
const out = { force: false, useLunarisOnly: false, updateDb: true, dryRun: false, bot: null, delay: 200 };
for (const a of args) {
if (a === "--force") out.force = true;
else if (a === "--use-lunaris-only") out.useLunarisOnly = true;
else if (a === "--no-update-db") out.updateDb = false;
else if (a === "--dry-run") out.dryRun = true;
else if (a.startsWith("--bot=")) out.bot = a.slice(6);
else if (a.startsWith("--delay=")) out.delay = parseInt(a.slice(8), 10);
else if (a === "--help" || a === "-h") {
console.log("用法: node scripts/bot-avatar-generate.mjs [选项]");
console.log(" --bot=<key> 只生成指定 bot");
console.log(" --force 覆盖已存在的头像");
console.log(" --use-lunaris-only 禁用 SVG 兜底(当前不推荐)");
console.log(" --no-update-db 只落盘不写 User.avatarUrl");
console.log(" --dry-run 试运行,不落盘不写库");
console.log(" --delay=<ms> bot 间隔延迟(默认 200ms)");
process.exit(0);
}
}
return out;
}
function ts() {
return new Date().toISOString().replace("T", " ").slice(0, 19);
}
async function main() {
const args = parseArgs();
console.log(`${ts()} 数字人头像批量预生成开始`);
console.log(
` bot=${args.bot || "all"} force=${args.force} lunarisOnly=${args.useLunarisOnly} updateDb=${args.updateDb} dryRun=${args.dryRun} delay=${args.delay}ms`
);
if (!process.env.DATABASE_URL) {
throw new Error("DATABASE_URL 未配置");
}
const startTime = Date.now();
const { summary, results } = await generateForAll({
force: args.force,
botKey: args.bot,
useLunarisOnly: args.useLunarisOnly,
delayMs: args.dryRun ? 0 : args.delay,
});
const duration = Date.now() - startTime;
console.log("");
console.log(`${ts()} 完成: total=${summary.total} ok=${summary.ok} failed=${summary.failed} (${duration}ms)`);
console.log(`${ts()} 落盘位置: public/bot-avatars/{key}.svg + public/bot-avatars/lunaris/{key}.jpg`);
console.log(`${ts()} 清单: public/bot-avatars/manifest.json`);
if (summary.failed > 0) {
console.log("");
console.log("失败列表:");
for (const r of results) {
if (r.error) console.log(` - ${r.key}: ${r.error}`);
}
}
await disconnect();
process.exit(summary.failed > 0 ? 1 : 0);
}
main().catch(async (err) => {
console.error(`${ts()} ❌ 致命错误: ${err.message}`);
console.error(err.stack);
await disconnect().catch(() => {});
process.exit(1);
});