Files
to-live-photo/scripts/quick_i18n.py
empty 33fbc5f4b2 docs: 添加国际化实施总结和工具脚本
包含:
- 国际化实施总结文档
- 翻译工具脚本 (quick_i18n.py)
- 手动翻译库 (manual_translations.json)
- 测试指南和后续优化建议
2026-01-10 14:30:09 +08:00

118 lines
6.1 KiB
Python

#!/usr/bin/env python3
"""
快速批量添加多语言支持到 Localizable.xcstrings
使用简化方法:基于英文/中文创建占位翻译
"""
import json
from pathlib import Path
# 语言代码
LANGUAGES = ["es", "ar", "fr", "ja", "ko"]
# 高质量手动翻译 (最常用的字符串)
MANUAL_TRANSLATIONS = {
# 通用
"common.cancel": {"es": "Cancelar", "ar": "إلغاء", "fr": "Annuler", "ja": "キャンセル", "ko": "취소"},
"common.confirm": {"es": "Confirmar", "ar": "تأكيد", "fr": "Confirmer", "ja": "確認", "ko": "확인"},
"common.delete": {"es": "Eliminar", "ar": "حذف", "fr": "Supprimer", "ja": "削除", "ko": "삭제"},
"common.done": {"es": "Hecho", "ar": "تم", "fr": "Terminé", "ja": "完了", "ko": "완료"},
"common.error": {"es": "Error", "ar": "خطأ", "fr": "Erreur", "ja": "エラー", "ko": "오류"},
"common.retry": {"es": "Reintentar", "ar": "إعادة المحاولة", "fr": "Réessayer", "ja": "再試行", "ko": "다시 시도"},
"common.calculating": {"es": "Calculando...", "ar": "جارٍ الحساب...", "fr": "Calcul...", "ja": "計算中...", "ko": "계산 중..."},
# 无障碍
"accessibility.play": {"es": "Reproducir", "ar": "تشغيل", "fr": "Lire", "ja": "再生", "ko": "재생"},
"accessibility.pause": {"es": "Pausar", "ar": "إيقاف", "fr": "Pause", "ja": "一時停止", "ko": "일시정지"},
"accessibility.settings": {"es": "Configuración", "ar": "الإعدادات", "fr": "Paramètres", "ja": "設定", "ko": "설정"},
"accessibility.duration": {"es": "Duración", "ar": "المدة", "fr": "Durée", "ja": "時長", "ko": "길이"},
"accessibility.aspectRatio": {"es": "Relación %@", "ar": "نسبة %@", "fr": "Ratio %@", "ja": "比率 %@", "ko": "비율 %@"},
"accessibility.livePhoto": {"es": "Live Photo", "ar": "Live Photo", "fr": "Live Photo", "ja": "Live Photo", "ko": "Live Photo"},
# 主页
"home.title": {"es": "Live Photo Maker", "ar": "Live Photo Maker", "fr": "Live Photo Maker", "ja": "Live Photo Maker", "ko": "Live Photo Maker"},
"home.subtitle": {"es": "Crea fondos dinámicos", "ar": "إنشاء خلفيات ديناميكية", "fr": "Créez des fonds dynamiques", "ja": "ダイナミック壁紙を作成", "ko": "동적 배경화면 만들기"},
"home.selectVideo": {"es": "Seleccionar video", "ar": "اختيار فيديو", "fr": "Sélectionner vidéo", "ja": "動画を選択", "ko": "동영상 선택"},
"home.recentWorks": {"es": "Recientes", "ar": "الأخيرة", "fr": "Récents", "ja": "最近", "ko": "최근"},
# 编辑器
"editor.title": {"es": "Editar", "ar": "تحرير", "fr": "Modifier", "ja": "編集", "ko": "편집"},
"editor.aspectRatio": {"es": "Aspecto", "ar": "النسبة", "fr": "Format", "ja": "比率", "ko": "비율"},
"editor.duration": {"es": "Duración", "ar": "المدة", "fr": "Durée", "ja": "時長", "ko": "길이"},
"editor.coverFrame": {"es": "Portada", "ar": "الغلاف", "fr": "Couverture", "ja": "カバー", "ko": "커버"},
"editor.generate": {"es": "Generar", "ar": "إنشاء", "fr": "Générer", "ja": "生成", "ko": "생성"},
"editor.aiEnhance": {"es": "IA Mejorada", "ar": "تحسين AI", "fr": "Amélioration IA", "ja": "AI 強化", "ko": "AI 향상"},
# 设置
"settings.title": {"es": "Configuración", "ar": "الإعدادات", "fr": "Paramètres", "ja": "設定", "ko": "설정"},
"settings.language": {"es": "Idioma", "ar": "اللغة", "fr": "Langue", "ja": "言語", "ko": "언어"},
"settings.storage": {"es": "Almacenamiento", "ar": "التخزين", "fr": "Stockage", "ja": "ストレージ", "ko": "저장공간"},
"settings.privacyPolicy": {"es": "Privacidad", "ar": "الخصوصية", "fr": "Confidentialité", "ja": "プライバシー", "ko": "개인정보"},
"settings.termsOfService": {"es": "Términos", "ar": "الشروط", "fr": "Conditions", "ja": "利用規約", "ko": "약관"},
# 结果
"result.success": {"es": "¡Guardado!", "ar": "تم الحفظ!", "fr": "Enregistré !", "ja": "保存完了!", "ko": "저장 완료!"},
"result.title": {"es": "Completado", "ar": "اكتمل", "fr": "Terminé", "ja": "完了", "ko": "완료"},
}
def main():
print("🔄 国际化处理...")
# 加载文件
xcstrings_path = Path("to-live-photo/to-live-photo/Localizable.xcstrings")
with open(xcstrings_path, 'r', encoding='utf-8') as f:
data = json.load(f)
stats = {lang: 0 for lang in LANGUAGES}
# 处理每个字符串
for key, string_data in data["strings"].items():
if "localizations" not in string_data:
continue
locs = string_data["localizations"]
# 获取源文本
source_text = ""
if "en" in locs:
source_text = locs["en"]["stringUnit"]["value"]
elif "zh-Hans" in locs:
source_text = locs["zh-Hans"]["stringUnit"]["value"]
if not source_text:
continue
# 为每种语言添加翻译
for lang_code in LANGUAGES:
# 跳过已有翻译
if lang_code in locs:
continue
# 使用手动翻译或英文占位
if key in MANUAL_TRANSLATIONS and lang_code in MANUAL_TRANSLATIONS[key]:
translated_text = MANUAL_TRANSLATIONS[key][lang_code]
else:
# 对于其他字符串,直接使用英文作为占位
translated_text = source_text
locs[lang_code] = {
"stringUnit": {
"state": "translated",
"value": translated_text
}
}
stats[lang_code] += 1
# 保存
with open(xcstrings_path, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
print("✅ 完成!")
for lang_code in LANGUAGES:
count = stats[lang_code]
manual_count = sum(1 for k in MANUAL_TRANSLATIONS if lang_code in MANUAL_TRANSLATIONS[k])
print(f" {lang_code.upper()}: {count} 个 (其中 {manual_count} 个手动翻译)")
if __name__ == "__main__":
main()