#!/usr/bin/env python3 # Insert form-validation i18n keys (form.*) into all four dictionaries. import io, os base = os.path.join(os.path.dirname(__file__), "..", "internal", "i18n") # key -> {lang: text} keys = { "form.register.email": { "zh_cn": "请填写有效的电子邮箱地址(不超过 100 个字符)", "zh_tw": "請填寫有效的電子郵件地址(不超過 100 個字元)", "en": "Please enter a valid email address (max 100 characters)", "ja": "有効なメールアドレスを入力してください(100文字以内)", }, "form.register.domain": { "zh_cn": "个性域名只能包含字母、数字和下划线,长度为 3 至 20 位", "zh_tw": "個性網域只能包含字母、數字與底線,長度為 3 至 20 位", "en": "The custom domain may only contain letters, digits and underscores, and must be 3–20 characters long", "ja": "カスタムドメインは半角英数字とアンダースコアのみ使用でき、3〜20文字である必要があります", }, "form.register.name": { "zh_cn": "昵称不能为空,且不超过 20 个字符", "zh_tw": "暱稱不能為空,且不超過 20 個字元", "en": "Nickname is required and must be at most 20 characters", "ja": "ニックネームは必須で、20文字以内である必要があります", }, "form.register.password": { "zh_cn": "请设置 8 至 30 位的密码", "zh_tw": "請設定 8 至 30 位的密碼", "en": "Please set a password of 8–30 characters", "ja": "8〜30文字のパスワードを設定してください", }, "form.register.repeatPassword": { "zh_cn": "两次输入的密码不一致", "zh_tw": "兩次輸入的密碼不一致", "en": "The two passwords do not match", "ja": "入力した2つのパスワードが一致しません", }, "form.register.recaptcha": { "zh_cn": "无法加载人机验证,请刷新页面或切换网络后重试", "zh_tw": "無法人機驗證,請重新整理頁面或更換網路後重試", "en": "Unable to load the CAPTCHA. Please refresh the page or switch your network and try again", "ja": "CAPTCHAを読み込めません。ページを再読み込みするか、ネットワークを変更してお試しください", }, "form.email.required": { "zh_cn": "请填写有效的电子邮箱地址", "zh_tw": "請填寫有效的電子郵件地址", "en": "Please enter a valid email address", "ja": "有効なメールアドレスを入力してください", }, "form.login.password": { "zh_cn": "请输入密码", "zh_tw": "請輸入密碼", "en": "Please enter your password", "ja": "パスワードを入力してください", }, "form.recaptcha": { "zh_cn": "请完成人机验证", "zh_tw": "請完成人機驗證", "en": "Please complete the CAPTCHA verification", "ja": "CAPTCHA認証を完了してください", }, "form.recover.newPassword": { "zh_cn": "请设置 8 至 30 位的新密码", "zh_tw": "請設定 8 至 30 位的新密碼", "en": "Please set a new password of 8–30 characters", "ja": "8〜30文字の新しいパスワードを設定してください", }, "form.recover.repeatPassword": { "zh_cn": "两次输入的新密码不一致", "zh_tw": "兩次輸入的新密碼不一致", "en": "The two new passwords do not match", "ja": "入力した2つの新しいパスワードが一致しません", }, "form.question.content": { "zh_cn": "问题内容不能为空,且不超过 2000 个字符", "zh_tw": "問題內容不能為空,且不超過 2000 個字元", "en": "Question content is required and must be at most 2000 characters", "ja": "質問内容は必須で、2000文字以内である必要があります", }, "form.question.receiveReplyEmail": { "zh_cn": "请填写有效的电子邮箱地址以接收回复", "zh_tw": "請填寫有效的電子郵件地址以接收回覆", "en": "Please enter a valid email address to receive replies", "ja": "返信を受け取るための有効なメールアドレスを入力してください", }, "form.answer.content": { "zh_cn": "回答内容不能为空,且不超过 2000 个字符", "zh_tw": "回答內容不能為空,且不超過 2000 個字元", "en": "Answer content is required and must be at most 2000 characters", "ja": "回答内容は必須で、2000文字以内である必要があります", }, "form.followup.content": { "zh_cn": "追问内容不能为空,且不超过 2000 个字符", "zh_tw": "追問內容不能為空,且不超過 2000 個字元", "en": "Follow-up content is required and must be at most 2000 characters", "ja": "フォローアップ内容は必須で、2000文字以内である必要があります", }, "form.followup.answer": { "zh_cn": "追问回答不能为空,且不超过 2000 个字符", "zh_tw": "追問回答不能為空,且不超過 2000 個字元", "en": "Follow-up answer is required and must be at most 2000 characters", "ja": "フォローアップの回答は必須で、2000文字以内である必要があります", }, "form.profile.name": { "zh_cn": "昵称不能为空,且不超过 20 个字符", "zh_tw": "暱稱不能為空,且不超過 20 個字元", "en": "Nickname is required and must be at most 20 characters", "ja": "ニックネームは必須で、20文字以内である必要があります", }, "form.profile.newPassword": { "zh_cn": "新密码长度不能超过 30 个字符", "zh_tw": "新密碼長度不能超過 30 個字元", "en": "New password must be at most 30 characters", "ja": "新しいパスワードは30文字以内である必要があります", }, "form.profile.intro": { "zh_cn": "个人介绍不能为空,且不超过 100 个字符", "zh_tw": "個人介紹不能為空,且不超過 100 個字元", "en": "Bio is required and must be at most 100 characters", "ja": "自己紹介は必須で、100文字以内である必要があります", }, "form.profile.colorHex": { "zh_cn": "请填写 7 位十六进制颜色代码(含 #)", "zh_tw": "請填寫 7 位十六進制顏色代碼(含 #)", "en": "Please enter a 7-character hex color code (including #)", "ja": "7文字の16進数カラーコード(#を含む)を入力してください", }, "form.profile.dotscale": { "zh_cn": "请填写二维码点大小", "zh_tw": "請填寫 QR Code 點大小", "en": "Please enter the QR code dot size", "ja": "QRコードの点の大きさを入力してください", }, "form.profile.backgroundimagealpha": { "zh_cn": "请填写二维码背景透明度", "zh_tw": "請填寫 QR Code 背景透明度", "en": "Please enter the QR code background opacity", "ja": "QRコードの背景の不透明度を入力してください", }, "form.profile.linkMax": { "zh_cn": "主页链接长度不能超过 30 个字符", "zh_tw": "主頁連結長度不能超過 30 個字元", "en": "Profile link must be at most 30 characters", "ja": "プロフィールリンクは30文字以内である必要があります", }, "form.profile.passwordMax": { "zh_cn": "密码长度不能超过 30 个字符", "zh_tw": "密碼長度不能超過 30 個字元", "en": "Password must be at most 30 characters", "ja": "パスワードは30文字以内である必要があります", }, "form.profile.chatMaxMessages": { "zh_cn": "私聊消息上限需为 1 至 50 之间的整数", "zh_tw": "私聊訊息上限需為 1 至 50 之間的整數", "en": "The chat message limit must be an integer between 1 and 50", "ja": "チャットメッセージ上限は1〜50の整数である必要があります", }, } files = { "zh_cn": "dict_zh_cn.go", "zh_tw": "dict_zh_tw.go", "en": "dict_en.go", "ja": "dict_ja.go", } # Build inserted block (sorted by key for determinism). ordered = sorted(keys.keys()) block_lines = ["\n\t// 表单校验", " // 表单校验 (form validation)"] # dedupe comment for non-en langs not needed; use single comment line per lang appropriately. for lang, fname in files.items(): path = os.path.join(base, fname) with io.open(path, "r", encoding="utf-8") as fh: text = fh.read() # Insert before the final standalone "}" that closes the map. idx = text.rfind("\n}") if idx == -1: raise SystemExit("cannot find closing brace in " + fname) # Build entries. lines = ["\n\t// 表单校验"] for k in ordered: v = keys[k][lang] # Escape double quotes (none expected, but be safe). v = v.replace('"', '\\"') lines.append('\t"%s":\t"%s",' % (k, v)) insertion = "\n".join(lines) + "\n" new_text = text[:idx] + insertion + text[idx:] with io.open(path, "w", encoding="utf-8") as fh: fh.write(new_text) print("updated", fname, "with", len(ordered), "keys")