From 350bed217c5574ed829999a6a9996770dee36227 Mon Sep 17 00:00:00 2001 From: Hoofei Date: Sun, 6 Apr 2025 12:37:52 +0800 Subject: [PATCH] Delete the extract script --- extract.js | 270 ------------------------------------------ merge-translations.js | 252 --------------------------------------- 2 files changed, 522 deletions(-) delete mode 100644 extract.js delete mode 100644 merge-translations.js diff --git a/extract.js b/extract.js deleted file mode 100644 index 61d5d2d7f..000000000 --- a/extract.js +++ /dev/null @@ -1,270 +0,0 @@ -console.log('Creating translation extractor script...'); - -const fs = require('fs'); -const path = require('path'); - -// 存储找到的所有翻译键 -const translationKeys = { - common: new Set(), - settings: new Set() -}; - -// 匹配更多格式的翻译函数调用 -// 支持 t('common.xxx')、t("common.xxx")、t(`common.xxx`) -const translationPatterns = [ - /t\(\s*['"]([a-zA-Z0-9._-]+)['"]?\s*[,)]/g, // t('key') 或 t("key") - /t\(\s*`([a-zA-Z0-9._-]+)`\s*[,)]/g, // t(`key`) - /useTranslation\(\s*["']([a-zA-Z0-9._-]+)["']\s*\)/g, // useTranslation('namespace') - /serverSideTranslations\([^)]*["']([a-zA-Z0-9._-]+)["']/g // serverSideTranslations(..., ['namespace']) -]; - -const namespaceRegex = /^(common|settings)\./; - -// 递归扫描目录下的所有 JS 和 TS 文件 -function scanDirectory(directory) { - try { - const entries = fs.readdirSync(directory, { withFileTypes: true }); - - for (const entry of entries) { - const fullPath = path.join(directory, entry.name); - - if (entry.isDirectory() && !fullPath.includes('node_modules') && !fullPath.includes('.next')) { - scanDirectory(fullPath); - } else if (entry.isFile() && /\.(js|jsx|ts|tsx)$/.test(entry.name)) { - try { - const content = fs.readFileSync(fullPath, 'utf8'); - - // 检查文件中是否使用了翻译 - let usesTranslation = false; - if (content.includes('useTranslation') || content.includes('t(') || content.includes('serverSideTranslations')) { - usesTranslation = true; - } - - if (usesTranslation) { - // 使用所有模式匹配翻译键 - for (const pattern of translationPatterns) { - let match; - while ((match = pattern.exec(content)) !== null) { - const key = match[1]; - - // 检查是否有命名空间 - const namespaceMatch = key.match(namespaceRegex); - if (namespaceMatch) { - const namespace = namespaceMatch[1]; - if (namespace === 'common' || namespace === 'settings') { - translationKeys[namespace].add(key); - } - } - - // 如果文件中导入了特定命名空间,所有的 t(key) 都属于该命名空间 - if (content.includes(`useTranslation('common')`) || content.includes(`useTranslation("common")`)) { - if (!key.includes('.')) { - translationKeys.common.add(`common.${key}`); - } - } - - if (content.includes(`useTranslation('settings')`) || content.includes(`useTranslation("settings")`)) { - if (!key.includes('.')) { - translationKeys.settings.add(`settings.${key}`); - } - } - } - } - - // 控制台输出被处理的文件及其找到的翻译键 - if (usesTranslation) { - console.log(`检查文件: ${fullPath}`); - } - } - } catch (error) { - console.error(`Error reading file ${fullPath}:`, error); - } - } - } - } catch (error) { - console.error(`Error scanning directory ${directory}:`, error); - } -} - -// 手动添加一些常见的翻译键(基于直接观察和常见用法) -function addCommonTranslationKeys() { - const commonKeys = [ - 'dashboard.title', 'dashboard.overview', 'dashboard.projects', 'dashboard.servers', - 'dashboard.docker', 'dashboard.monitoring', 'dashboard.settings', 'dashboard.logout', - 'dashboard.profile', 'dashboard.terminal', 'dashboard.containers', 'dashboard.images', - 'dashboard.volumes', 'dashboard.networks', - - 'button.create', 'button.edit', 'button.delete', 'button.cancel', - 'button.save', 'button.confirm', 'button.back', 'button.next', 'button.finish', - - 'status.running', 'status.stopped', 'status.error', 'status.pending', - 'status.success', 'status.failed', - - 'form.required', 'form.invalid', 'form.submit', 'form.reset', - - 'notification.success', 'notification.error', 'notification.warning', 'notification.info', - - 'time.now', 'time.minutes', 'time.hours', 'time.days', - - 'filter.all', 'filter.active', 'filter.inactive', - - 'sort.asc', 'sort.desc', - - 'search.placeholder', 'search.noResults', - - 'pagination.prev', 'pagination.next', 'pagination.of', - - 'error.notFound', 'error.serverError', 'error.unauthorized', 'error.forbidden', - - 'loading', 'empty', 'more', 'less', - - 'project.create', 'project.edit', 'project.delete', 'project.name', 'project.description', - - 'service.create', 'service.edit', 'service.delete', 'service.name', 'service.type', - - 'domain.add', 'domain.remove', - - 'environment.variables', 'environment.add', 'environment.edit', - 'environment.name', 'environment.value' - ]; - - commonKeys.forEach(key => { - translationKeys.common.add(`common.${key}`); - }); -} - -// 读取现有翻译文件 -function readTranslationFile(filePath) { - try { - if (fs.existsSync(filePath)) { - const content = fs.readFileSync(filePath, 'utf8'); - return JSON.parse(content); - } - } catch (error) { - console.error(`Error reading translation file ${filePath}:`, error); - } - return {}; -} - -// 主函数 -function extractTranslations() { - const appsDir = path.join(__dirname, 'apps', 'dokploy'); - - // 扫描代码库 - scanDirectory(appsDir); - - // 手动添加常见的翻译键 - addCommonTranslationKeys(); - - // 读取现有翻译文件 - const zhHansCommonPath = path.join(appsDir, 'public', 'locales', 'zh-Hans', 'common.json'); - const zhHansSettingsPath = path.join(appsDir, 'public', 'locales', 'zh-Hans', 'settings.json'); - - const existingCommon = readTranslationFile(zhHansCommonPath); - const existingSettings = readTranslationFile(zhHansSettingsPath); - - // 准备新的翻译文件 - const newCommon = {}; - const newSettings = {}; - - // 处理 common 命名空间 - for (const key of translationKeys.common) { - const shortKey = key.replace('common.', ''); - newCommon[key] = existingCommon[key] || `[需要翻译] ${shortKey}`; - } - - // 处理 settings 命名空间 - for (const key of translationKeys.settings) { - const shortKey = key.replace('settings.', ''); - newSettings[key] = existingSettings[key] || `[需要翻译] ${shortKey}`; - } - - // 输出结果 - console.log('=== 提取的 common 翻译键 ==='); - console.log(Array.from(translationKeys.common).sort().join('\n')); - console.log(`\n共找到 ${translationKeys.common.size} 个 common 翻译键`); - - console.log('\n=== 提取的 settings 翻译键 ==='); - console.log(Array.from(translationKeys.settings).sort().join('\n')); - console.log(`\n共找到 ${translationKeys.settings.size} 个 settings 翻译键`); - - // 创建包含缺失翻译的新文件 - const missingCommonTranslations = {}; - const missingSettingsTranslations = {}; - - for (const key of translationKeys.common) { - if (!existingCommon[key]) { - const shortKey = key.replace('common.', ''); - missingCommonTranslations[key] = `[需要翻译] ${shortKey}`; - } - } - - for (const key of translationKeys.settings) { - if (!existingSettings[key]) { - const shortKey = key.replace('settings.', ''); - missingSettingsTranslations[key] = `[需要翻译] ${shortKey}`; - } - } - - // 输出缺失的翻译 - console.log('\n=== 缺失的 common 翻译 ==='); - console.log(JSON.stringify(missingCommonTranslations, null, 2)); - console.log(`\n共缺失 ${Object.keys(missingCommonTranslations).length} 个 common 翻译`); - - console.log('\n=== 缺失的 settings 翻译 ==='); - console.log(JSON.stringify(missingSettingsTranslations, null, 2)); - console.log(`\n共缺失 ${Object.keys(missingSettingsTranslations).length} 个 settings 翻译`); - - // 输出可以直接复制到文件中的完整翻译对象 - console.log('\n=== 完整的 common.json 内容 ==='); - const fullCommon = { ...existingCommon }; - translationKeys.common.forEach(key => { - if (!fullCommon[key]) { - const shortKey = key.replace('common.', ''); - fullCommon[key] = `[翻译] ${shortKey}`; - } - }); - console.log(JSON.stringify(fullCommon, null, 2)); - - console.log('\n=== 完整的 settings.json 内容 ==='); - const fullSettings = { ...existingSettings }; - translationKeys.settings.forEach(key => { - if (!fullSettings[key]) { - const shortKey = key.replace('settings.', ''); - fullSettings[key] = `[翻译] ${shortKey}`; - } - }); - console.log(JSON.stringify(fullSettings, null, 2)); - - // 优化生成的翻译文件格式:移除命名空间前缀 - const optimizedCommon = {}; - Object.keys(fullCommon).forEach(key => { - const shortKey = key.replace('common.', ''); - optimizedCommon[shortKey] = fullCommon[key]; - }); - - const optimizedSettings = {}; - Object.keys(fullSettings).forEach(key => { - const shortKey = key.replace('settings.', ''); - optimizedSettings[shortKey] = fullSettings[key]; - }); - - // 写入文件 - fs.writeFileSync('missing-common-translations.json', JSON.stringify(missingCommonTranslations, null, 2), 'utf8'); - fs.writeFileSync('missing-settings-translations.json', JSON.stringify(missingSettingsTranslations, null, 2), 'utf8'); - fs.writeFileSync('full-common-translations.json', JSON.stringify(fullCommon, null, 2), 'utf8'); - fs.writeFileSync('full-settings-translations.json', JSON.stringify(fullSettings, null, 2), 'utf8'); - fs.writeFileSync('optimized-common-translations.json', JSON.stringify(optimizedCommon, null, 2), 'utf8'); - fs.writeFileSync('optimized-settings-translations.json', JSON.stringify(optimizedSettings, null, 2), 'utf8'); - - console.log('\n翻译提取完成!'); - console.log('文件已保存:'); - console.log('- missing-common-translations.json: 缺失的 common 翻译'); - console.log('- missing-settings-translations.json: 缺失的 settings 翻译'); - console.log('- full-common-translations.json: 完整的 common 翻译(包含命名空间)'); - console.log('- full-settings-translations.json: 完整的 settings 翻译(包含命名空间)'); - console.log('- optimized-common-translations.json: 优化格式的 common 翻译(不含命名空间)'); - console.log('- optimized-settings-translations.json: 优化格式的 settings 翻译(不含命名空间)'); -} - -extractTranslations(); diff --git a/merge-translations.js b/merge-translations.js deleted file mode 100644 index 441ebed49..000000000 --- a/merge-translations.js +++ /dev/null @@ -1,252 +0,0 @@ -// 读取已创建的翻译文件 -const fs = require('fs'); -const path = require('path'); - -try { - const basePath = process.cwd(); - const commonPart1Path = path.join(basePath, 'common-zh-Hans.json'); - const commonPart2Path = path.join(basePath, 'common-zh-Hans-buttons.json'); - const fullCommonPath = path.join(basePath, 'optimized-common-translations.json'); - const fullSettingsPath = path.join(basePath, 'optimized-settings-translations.json'); - - const commonPart1 = JSON.parse(fs.readFileSync(commonPart1Path, 'utf8')); - const commonPart2 = JSON.parse(fs.readFileSync(commonPart2Path, 'utf8')); - const fullCommon = JSON.parse(fs.readFileSync(fullCommonPath, 'utf8')); - const fullSettings = JSON.parse(fs.readFileSync(fullSettingsPath, 'utf8')); - - // 创建一个全新的翻译对象 - const mergedCommon = {}; - const mergedSettings = {}; - - // 添加通用组件翻译 - mergedCommon["dashboard.title"] = "仪表盘"; - mergedCommon["dashboard.overview"] = "概览"; - mergedCommon["dashboard.projects"] = "项目"; - mergedCommon["dashboard.servers"] = "服务器"; - mergedCommon["dashboard.docker"] = "Docker"; - mergedCommon["dashboard.monitoring"] = "监控"; - mergedCommon["dashboard.settings"] = "设置"; - mergedCommon["dashboard.logout"] = "退出登录"; - mergedCommon["dashboard.profile"] = "个人资料"; - mergedCommon["dashboard.terminal"] = "终端"; - mergedCommon["dashboard.containers"] = "容器"; - mergedCommon["dashboard.images"] = "镜像"; - mergedCommon["dashboard.volumes"] = "卷"; - mergedCommon["dashboard.networks"] = "网络"; - - // 按钮翻译 - mergedCommon["button.create"] = "创建"; - mergedCommon["button.edit"] = "编辑"; - mergedCommon["button.delete"] = "删除"; - mergedCommon["button.cancel"] = "取消"; - mergedCommon["button.save"] = "保存"; - mergedCommon["button.confirm"] = "确认"; - mergedCommon["button.back"] = "返回"; - mergedCommon["button.next"] = "下一步"; - mergedCommon["button.finish"] = "完成"; - - // 状态翻译 - mergedCommon["status.running"] = "运行中"; - mergedCommon["status.stopped"] = "已停止"; - mergedCommon["status.error"] = "错误"; - mergedCommon["status.pending"] = "等待中"; - mergedCommon["status.success"] = "成功"; - mergedCommon["status.failed"] = "失败"; - - // 表单翻译 - mergedCommon["form.required"] = "必填"; - mergedCommon["form.invalid"] = "无效"; - mergedCommon["form.submit"] = "提交"; - mergedCommon["form.reset"] = "重置"; - - // 通知翻译 - mergedCommon["notification.success"] = "操作成功"; - mergedCommon["notification.error"] = "操作失败"; - mergedCommon["notification.warning"] = "警告"; - mergedCommon["notification.info"] = "信息"; - - // 时间翻译 - mergedCommon["time.now"] = "刚刚"; - mergedCommon["time.minutes"] = "分钟前"; - mergedCommon["time.hours"] = "小时前"; - mergedCommon["time.days"] = "天前"; - - // 过滤翻译 - mergedCommon["filter.all"] = "全部"; - mergedCommon["filter.active"] = "活跃"; - mergedCommon["filter.inactive"] = "不活跃"; - - // 排序翻译 - mergedCommon["sort.asc"] = "升序"; - mergedCommon["sort.desc"] = "降序"; - - // 搜索翻译 - mergedCommon["search.placeholder"] = "搜索..."; - mergedCommon["search.noResults"] = "无结果"; - - // 分页翻译 - mergedCommon["pagination.prev"] = "上一页"; - mergedCommon["pagination.next"] = "下一页"; - mergedCommon["pagination.of"] = "共 {0} 页"; - - // 错误翻译 - mergedCommon["error.notFound"] = "未找到"; - mergedCommon["error.serverError"] = "服务器错误"; - mergedCommon["error.unauthorized"] = "未授权"; - mergedCommon["error.forbidden"] = "禁止访问"; - - // 通用状态翻译 - mergedCommon["loading"] = "加载中..."; - mergedCommon["empty"] = "暂无数据"; - mergedCommon["more"] = "更多"; - mergedCommon["less"] = "收起"; - - // 项目翻译 - mergedCommon["project.create"] = "创建项目"; - mergedCommon["project.edit"] = "编辑项目"; - mergedCommon["project.delete"] = "删除项目"; - mergedCommon["project.name"] = "项目名称"; - mergedCommon["project.description"] = "项目描述"; - - // 服务翻译 - mergedCommon["service.create"] = "创建服务"; - mergedCommon["service.edit"] = "编辑服务"; - mergedCommon["service.delete"] = "删除服务"; - mergedCommon["service.name"] = "服务名称"; - mergedCommon["service.type"] = "服务类型"; - - // 域名翻译 - mergedCommon["domain.add"] = "添加域名"; - mergedCommon["domain.remove"] = "移除域名"; - - // 环境变量翻译 - mergedCommon["environment.variables"] = "环境变量"; - mergedCommon["environment.add"] = "添加环境变量"; - mergedCommon["environment.edit"] = "编辑环境变量"; - mergedCommon["environment.name"] = "变量名"; - mergedCommon["environment.value"] = "变量值"; - - // 设置页面的通用翻译 - mergedSettings["common.save"] = "保存"; - mergedSettings["common.enterTerminal"] = "终端"; - - // 服务器域名设置 - mergedSettings["server.domain.title"] = "服务器域名"; - mergedSettings["server.domain.description"] = "为您的服务器应用添加域名。"; - mergedSettings["server.domain.form.domain"] = "域名"; - mergedSettings["server.domain.form.letsEncryptEmail"] = "Let's Encrypt 邮箱"; - mergedSettings["server.domain.form.certificate.label"] = "证书提供商"; - mergedSettings["server.domain.form.certificate.placeholder"] = "选择证书"; - mergedSettings["server.domain.form.certificateOptions.none"] = "无"; - mergedSettings["server.domain.form.certificateOptions.letsencrypt"] = "Let's Encrypt"; - - // Web服务器设置 - mergedSettings["server.webServer.title"] = "Web 服务器"; - mergedSettings["server.webServer.description"] = "重载或清理 Web 服务器。"; - mergedSettings["server.webServer.actions"] = "操作"; - mergedSettings["server.webServer.reload"] = "重新加载"; - mergedSettings["server.webServer.watchLogs"] = "查看日志"; - mergedSettings["server.webServer.updateServerIp"] = "更新服务器 IP"; - mergedSettings["server.webServer.server.label"] = "服务器"; - - // Traefik设置 - mergedSettings["server.webServer.traefik.label"] = "Traefik"; - mergedSettings["server.webServer.traefik.modifyEnv"] = "修改环境变量"; - mergedSettings["server.webServer.traefik.managePorts"] = "额外端口映射"; - mergedSettings["server.webServer.traefik.managePortsDescription"] = "为 Traefik 添加或删除额外端口"; - mergedSettings["server.webServer.traefik.targetPort"] = "目标端口"; - mergedSettings["server.webServer.traefik.publishedPort"] = "发布端口"; - mergedSettings["server.webServer.traefik.addPort"] = "添加端口"; - mergedSettings["server.webServer.traefik.portsUpdated"] = "端口更新成功"; - mergedSettings["server.webServer.traefik.portsUpdateError"] = "端口更新失败"; - mergedSettings["server.webServer.traefik.publishMode"] = "发布模式"; - - // 存储空间设置 - mergedSettings["server.webServer.storage.label"] = "存储空间"; - mergedSettings["server.webServer.storage.cleanUnusedImages"] = "清理未使用的镜像"; - mergedSettings["server.webServer.storage.cleanUnusedVolumes"] = "清理未使用的卷"; - mergedSettings["server.webServer.storage.cleanStoppedContainers"] = "清理已停止的容器"; - mergedSettings["server.webServer.storage.cleanDockerBuilder"] = "清理 Docker Builder 和系统"; - mergedSettings["server.webServer.storage.cleanMonitoring"] = "清理监控数据"; - mergedSettings["server.webServer.storage.cleanAll"] = "清理所有内容"; - - // 个人资料设置 - mergedSettings["profile.title"] = "账户"; - mergedSettings["profile.description"] = "在此更改您的个人资料详情。"; - mergedSettings["profile.email"] = "邮箱"; - mergedSettings["profile.password"] = "密码"; - mergedSettings["profile.avatar"] = "头像"; - - // 外观设置 - mergedSettings["appearance.title"] = "外观"; - mergedSettings["appearance.description"] = "自定义您的仪表盘主题。"; - mergedSettings["appearance.theme"] = "主题"; - mergedSettings["appearance.themeDescription"] = "为您的仪表盘选择主题"; - mergedSettings["appearance.themes.light"] = "明亮"; - mergedSettings["appearance.themes.dark"] = "暗黑"; - mergedSettings["appearance.themes.system"] = "跟随系统"; - mergedSettings["appearance.language"] = "语言"; - mergedSettings["appearance.languageDescription"] = "为您的仪表盘选择语言"; - - // 终端设置 - mergedSettings["terminal.connectionSettings"] = "连接设置"; - mergedSettings["terminal.ipAddress"] = "IP 地址"; - mergedSettings["terminal.port"] = "端口"; - mergedSettings["terminal.username"] = "用户名"; - - // 其他设置 - mergedSettings["settings"] = "设置"; - mergedSettings["general"] = "通用设置"; - mergedSettings["security"] = "安全"; - mergedSettings["users"] = "用户管理"; - mergedSettings["roles"] = "角色管理"; - mergedSettings["permissions"] = "权限"; - mergedSettings["api"] = "API设置"; - mergedSettings["certificates"] = "证书管理"; - mergedSettings["ssh"] = "SSH密钥"; - mergedSettings["backups"] = "备份"; - mergedSettings["logs"] = "日志"; - mergedSettings["updates"] = "更新"; - mergedSettings["network"] = "网络"; - - // 输出合并后的文件内容 - console.log('Common translations total:', Object.keys(mergedCommon).length); - console.log('Settings translations total:', Object.keys(mergedSettings).length); - - // 保存为最终的翻译文件 - fs.writeFileSync(path.join(basePath, 'final-zh-Hans-common.json'), JSON.stringify(mergedCommon, null, 2)); - fs.writeFileSync(path.join(basePath, 'final-zh-Hans-settings.json'), JSON.stringify(mergedSettings, null, 2)); - - // 输出翻译完成的统计 - const commonKeys = Object.keys(mergedCommon); - const settingsKeys = Object.keys(mergedSettings); - console.log('最终翻译文件已保存:'); - console.log(`- 通用翻译 (${commonKeys.length} 个词条)`); - console.log(`- 设置翻译 (${settingsKeys.length} 个词条)`); - - // 创建最终放入项目中的文件(按项目结构) - const projectCommonPath = path.join(basePath, 'apps', 'dokploy', 'public', 'locales', 'zh-Hans'); - - // 确保目录存在 - if (!fs.existsSync(projectCommonPath)) { - fs.mkdirSync(projectCommonPath, { recursive: true }); - console.log(`创建目录: ${projectCommonPath}`); - } - - // 写入到项目中的目标位置 - const projectCommonFilePath = path.join(projectCommonPath, 'common.json'); - const projectSettingsFilePath = path.join(projectCommonPath, 'settings.json'); - - console.log(`尝试写入到:\n- ${projectCommonFilePath}\n- ${projectSettingsFilePath}`); - - try { - fs.writeFileSync(projectCommonFilePath, JSON.stringify(mergedCommon, null, 2)); - fs.writeFileSync(projectSettingsFilePath, JSON.stringify(mergedSettings, null, 2)); - console.log('已成功写入到项目文件夹中!'); - } catch (error) { - console.error('写入到项目文件夹失败:', error.message); - console.log('请手动将文件复制到目标位置。'); - } -} catch (error) { - console.error('错误:', error); -}