Files
to-live-photo/scripts/add_all_missing_i18n.py
empty f505448a1c fix: 全面修复Views目录国际化遗漏
修复内容:
- EditorView: 30+个硬编码字符串替换为本地化键值
  - 导航标题、封面帧提示、视频时长、关键帧时刻
  - AI超分辨率完整说明(下载提示、分辨率提升、处理时间、本地处理)
  - 兼容模式详细参数(分辨率、帧率、编码、色彩)
  - 视频诊断建议(HDR、高分辨率、高帧率)
- ProcessingView: 17个阶段描述本地化
  - 导航标题、取消按钮
  - 9个处理阶段的标题和描述
- ResultView: 6个按钮和描述本地化
  - 导航标题、保存描述、验证徽章、操作按钮
- OnboardingView: 4个引导页完整国际化
  - 每页标题和描述、导航按钮
- 新增66个localization keys,支持8种语言
  (zh-Hans, zh-Hant, en, es, ar, fr, ja, ko)

构建验证:BUILD SUCCEEDED

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-10 17:13:35 +08:00

794 lines
33 KiB
Python
Raw 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 python3
"""添加所有遗漏的国际化字符串 - 全面覆盖Views目录"""
import json
# 所有需要添加的本地化字符串超过100个
ALL_MISSING_STRINGS = {
# EditorView - 导航和基础
"editor.title": {
"zh-Hans": "编辑",
"zh-Hant": "編輯",
"en": "Edit",
"es": "Editar",
"ar": "تحرير",
"fr": "Modifier",
"ja": "編集",
"ko": "편집"
},
# EditorView - 封面帧
"editor.coverFrameHint1": {
"zh-Hans": "此图片将作为 Live Photo 的静态封面",
"zh-Hant": "此圖片將作為 Live Photo 的靜態封面",
"en": "This image will be the static cover of Live Photo",
"es": "Esta imagen será la portada estática de Live Photo",
"ar": "ستكون هذه الصورة الغلاف الثابت لـ Live Photo",
"fr": "Cette image sera la couverture statique de Live Photo",
"ja": "この画像がLive Photoの静止画カバーになります",
"ko": "이 이미지가 Live Photo의 정적 커버가 됩니다"
},
"editor.coverFrameHint2": {
"zh-Hans": "拖动下方滑杆选择封面时刻",
"zh-Hant": "拖動下方滑桿選擇封面時刻",
"en": "Drag the slider below to select cover moment",
"es": "Arrastra el control deslizante para seleccionar el momento de portada",
"ar": "اسحب شريط التمرير أدناه لاختيار لحظة الغلاف",
"fr": "Faites glisser le curseur ci-dessous pour sélectionner le moment de couverture",
"ja": "下のスライダーをドラッグしてカバーの瞬間を選択",
"ko": "아래 슬라이더를 드래그하여 커버 순간 선택"
},
# EditorView - 时长控制
"editor.videoDuration": {
"zh-Hans": "视频时长",
"zh-Hant": "影片時長",
"en": "Video Duration",
"es": "Duración del Video",
"ar": "مدة الفيديو",
"fr": "Durée de la Vidéo",
"ja": "ビデオの長さ",
"ko": "비디오 길이"
},
"editor.durationSeconds": {
"zh-Hans": "%.1f",
"zh-Hant": "%.1f",
"en": "%.1f sec",
"es": "%.1f seg",
"ar": "%.1f ث",
"fr": "%.1f s",
"ja": "%.1f",
"ko": "%.1f"
},
"editor.durationHint": {
"zh-Hans": "Live Photo 壁纸推荐时长1 ~ 1.5 秒",
"zh-Hant": "Live Photo 桌布建議時長1 ~ 1.5 秒",
"en": "Live Photo wallpaper recommended duration: 1-1.5 seconds",
"es": "Duración recomendada para fondo Live Photo: 1-1.5 segundos",
"ar": "المدة الموصى بها لخلفية Live Photo: 1-1.5 ثانية",
"fr": "Durée recommandée pour fond d'écran Live Photo: 1-1.5 secondes",
"ja": "Live Photo壁紙推奨時間1〜1.5秒",
"ko": "Live Photo 배경화면 권장 길이: 1-1.5초"
},
# EditorView - 封面时刻
"editor.keyFrameTime": {
"zh-Hans": "封面时刻",
"zh-Hant": "封面時刻",
"en": "Cover Moment",
"es": "Momento de Portada",
"ar": "لحظة الغلاف",
"fr": "Moment de Couverture",
"ja": "カバーの瞬間",
"ko": "커버 순간"
},
"editor.keyFrameSeconds": {
"zh-Hans": "%.2f",
"zh-Hant": "%.2f",
"en": "%.2f sec",
"es": "%.2f seg",
"ar": "%.2f ث",
"fr": "%.2f s",
"ja": "%.2f",
"ko": "%.2f"
},
"editor.keyFrameHint": {
"zh-Hans": "选择视频中的某一帧作为 Live Photo 的封面",
"zh-Hant": "選擇影片中的某一幀作為 Live Photo 的封面",
"en": "Select a frame from the video as the Live Photo cover",
"es": "Selecciona un fotograma del video como portada de Live Photo",
"ar": "اختر إطارًا من الفيديو كغلاف لـ Live Photo",
"fr": "Sélectionnez une image de la vidéo comme couverture Live Photo",
"ja": "ビデオからフレームを選択してLive Photoのカバーにする",
"ko": "비디오에서 프레임을 선택하여 Live Photo 커버로 사용"
},
# EditorView - AI超分辨率
"editor.aiEnhance": {
"zh-Hans": "AI 超分辨率",
"zh-Hant": "AI 超解析度",
"en": "AI Super Resolution",
"es": "Súper Resolución IA",
"ar": "الدقة الفائقة بالذكاء الاصطناعي",
"fr": "Super Résolution IA",
"ja": "AI超解像度",
"ko": "AI 초해상도"
},
"editor.aiEnhanceDescription": {
"zh-Hans": "使用 AI 提升封面画质",
"zh-Hant": "使用 AI 提升封面畫質",
"en": "Use AI to enhance cover quality",
"es": "Usa IA para mejorar la calidad de la portada",
"ar": "استخدم الذكاء الاصطناعي لتحسين جودة الغلاف",
"fr": "Utilisez l'IA pour améliorer la qualité de la couverture",
"ja": "AIを使ってカバーの画質を向上",
"ko": "AI를 사용하여 커버 품질 향상"
},
"editor.aiModelDownloading": {
"zh-Hans": "正在下载 AI 模型...",
"zh-Hant": "正在下載 AI 模型...",
"en": "Downloading AI model...",
"es": "Descargando modelo de IA...",
"ar": "جارٍ تنزيل نموذج الذكاء الاصطناعي...",
"fr": "Téléchargement du modèle IA...",
"ja": "AIモデルをダウンロード中...",
"ko": "AI 모델 다운로드 중..."
},
"editor.aiModelDownloadHint": {
"zh-Hans": "首次使用需下载 AI 模型(约 64MB",
"zh-Hant": "首次使用需下載 AI 模型(約 64MB",
"en": "First-time use requires downloading AI model (~64MB)",
"es": "El primer uso requiere descargar el modelo de IA (~64MB)",
"ar": "الاستخدام الأول يتطلب تنزيل نموذج الذكاء الاصطناعي (~64 ميجابايت)",
"fr": "La première utilisation nécessite le téléchargement du modèle IA (~64Mo)",
"ja": "初回使用時にAIモデルのダウンロードが必要約64MB",
"ko": "첫 사용 시 AI 모델 다운로드 필요 (~64MB)"
},
"editor.aiResolutionBoost": {
"zh-Hans": "分辨率提升约 2 倍",
"zh-Hant": "解析度提升約 2 倍",
"en": "Resolution increased by ~2x",
"es": "Resolución aumentada ~2x",
"ar": "زيادة الدقة بحوالي 2×",
"fr": "Résolution augmentée d'environ 2×",
"ja": "解像度が約2倍向上",
"ko": "해상도 약 2배 증가"
},
"editor.aiProcessingTime": {
"zh-Hans": "处理时间:约 2-3 秒",
"zh-Hant": "處理時間:約 2-3 秒",
"en": "Processing time: ~2-3 seconds",
"es": "Tiempo de procesamiento: ~2-3 segundos",
"ar": "وقت المعالجة: حوالي 2-3 ثواني",
"fr": "Temps de traitement: ~2-3 secondes",
"ja": "処理時間約2〜3秒",
"ko": "처리 시간: 약 2-3초"
},
"editor.aiLocalProcessing": {
"zh-Hans": "本地 AI 处理,无需网络",
"zh-Hant": "本地 AI 處理,無需網路",
"en": "Local AI processing, no network required",
"es": "Procesamiento IA local, no requiere red",
"ar": "معالجة محلية بالذكاء الاصطناعي، لا تحتاج إلى شبكة",
"fr": "Traitement IA local, pas de réseau nécessaire",
"ja": "ローカルAI処理、ネットワーク不要",
"ko": "로컬 AI 처리, 네트워크 불필요"
},
"editor.aiNotSupported": {
"zh-Hans": "当前设备不支持 AI 增强",
"zh-Hant": "目前裝置不支援 AI 增強",
"en": "Current device doesn't support AI enhancement",
"es": "El dispositivo actual no admite mejora de IA",
"ar": "الجهاز الحالي لا يدعم تحسين الذكاء الاصطناعي",
"fr": "L'appareil actuel ne prend pas en charge l'amélioration IA",
"ja": "現在のデバイスはAI強化に対応していません",
"ko": "현재 기기는 AI 향상을 지원하지 않습니다"
},
# EditorView - 兼容模式
"editor.compatibilityMode": {
"zh-Hans": "兼容模式",
"zh-Hant": "相容模式",
"en": "Compatibility Mode",
"es": "Modo de Compatibilidad",
"ar": "وضع التوافق",
"fr": "Mode de Compatibilité",
"ja": "互換性モード",
"ko": "호환성 모드"
},
"editor.compatibilityDescription": {
"zh-Hans": "适用于较旧设备或生成失败时",
"zh-Hant": "適用於較舊裝置或產生失敗時",
"en": "For older devices or when generation fails",
"es": "Para dispositivos antiguos o cuando falla la generación",
"ar": "للأجهزة القديمة أو عند فشل الإنشاء",
"fr": "Pour les appareils plus anciens ou en cas d'échec de génération",
"ja": "古いデバイスまたは生成失敗時に使用",
"ko": "구형 기기 또는 생성 실패 시 사용"
},
"editor.resolution720p": {
"zh-Hans": "分辨率720p",
"zh-Hant": "解析度720p",
"en": "Resolution: 720p",
"es": "Resolución: 720p",
"ar": "الدقة: 720p",
"fr": "Résolution: 720p",
"ja": "解像度720p",
"ko": "해상도: 720p"
},
"editor.framerate30fps": {
"zh-Hans": "帧率30fps",
"zh-Hant": "畫面更新率30fps",
"en": "Frame rate: 30fps",
"es": "Fotogramas: 30fps",
"ar": "معدل الإطارات: 30fps",
"fr": "Fréquence d'images: 30fps",
"ja": "フレームレート30fps",
"ko": "프레임 속도: 30fps"
},
"editor.codecH264": {
"zh-Hans": "编码H.264",
"zh-Hant": "編碼H.264",
"en": "Codec: H.264",
"es": "Códec: H.264",
"ar": "الترميز: H.264",
"fr": "Codec: H.264",
"ja": "コーデックH.264",
"ko": "코덱: H.264"
},
"editor.colorSDR": {
"zh-Hans": "色彩SDR",
"zh-Hant": "色彩SDR",
"en": "Color: SDR",
"es": "Color: SDR",
"ar": "اللون: SDR",
"fr": "Couleur: SDR",
"ja": "SDR",
"ko": "색상: SDR"
},
# EditorView - 诊断
"editor.videoDiagnosis": {
"zh-Hans": "视频检测",
"zh-Hant": "影片檢測",
"en": "Video Detection",
"es": "Detección de Video",
"ar": "كشف الفيديو",
"fr": "Détection de Vidéo",
"ja": "ビデオ検出",
"ko": "비디오 감지"
},
"editor.diagnosisHDR": {
"zh-Hans": "HDR 视频",
"zh-Hant": "HDR 影片",
"en": "HDR Video",
"es": "Video HDR",
"ar": "فيديو HDR",
"fr": "Vidéo HDR",
"ja": "HDR ビデオ",
"ko": "HDR 비디오"
},
"editor.diagnosisHDRDesc": {
"zh-Hans": "将自动转换为 SDR 以确保兼容性",
"zh-Hant": "將自動轉換為 SDR 以確保相容性",
"en": "Will be automatically converted to SDR for compatibility",
"es": "Se convertirá automáticamente a SDR para compatibilidad",
"ar": "سيتم التحويل تلقائيًا إلى SDR للتوافق",
"fr": "Sera automatiquement converti en SDR pour la compatibilité",
"ja": "互換性のため自動的にSDRに変換されます",
"ko": "호환성을 위해 자동으로 SDR로 변환됩니다"
},
"editor.diagnosisHighRes": {
"zh-Hans": "高分辨率视频",
"zh-Hant": "高解析度影片",
"en": "High Resolution Video",
"es": "Video de Alta Resolución",
"ar": "فيديو عالي الدقة",
"fr": "Vidéo Haute Résolution",
"ja": "高解像度ビデオ",
"ko": "고해상도 비디오"
},
"editor.diagnosisHighResDesc": {
"zh-Hans": "建议开启兼容模式以加快处理速度",
"zh-Hant": "建議開啟相容模式以加快處理速度",
"en": "Recommend enabling compatibility mode for faster processing",
"es": "Se recomienda habilitar el modo de compatibilidad para procesamiento más rápido",
"ar": "يوصى بتفعيل وضع التوافق لمعالجة أسرع",
"fr": "Recommandé d'activer le mode de compatibilité pour un traitement plus rapide",
"ja": "処理速度を上げるため互換性モードの有効化を推奨",
"ko": "더 빠른 처리를 위해 호환성 모드 활성화 권장"
},
"editor.diagnosisHighResAction": {
"zh-Hans": "开启兼容模式",
"zh-Hant": "開啟相容模式",
"en": "Enable Compatibility Mode",
"es": "Habilitar Modo de Compatibilidad",
"ar": "تفعيل وضع التوافق",
"fr": "Activer le Mode de Compatibilité",
"ja": "互換性モードを有効にする",
"ko": "호환성 모드 활성화"
},
"editor.diagnosisHighFrameRate": {
"zh-Hans": "高帧率视频",
"zh-Hant": "高畫面更新率影片",
"en": "High Frame Rate Video",
"es": "Video de Alta Tasa de Fotogramas",
"ar": "فيديو عالي معدل الإطارات",
"fr": "Vidéo à Fréquence d'Images Élevée",
"ja": "高フレームレートビデオ",
"ko": "고프레임 비디오"
},
"editor.diagnosisHighFrameRateDesc": {
"zh-Hans": "将自动转换为 60fps",
"zh-Hant": "將自動轉換為 60fps",
"en": "Will be automatically converted to 60fps",
"es": "Se convertirá automáticamente a 60fps",
"ar": "سيتم التحويل تلقائيًا إلى 60fps",
"fr": "Sera automatiquement converti en 60fps",
"ja": "自動的に60fpsに変換されます",
"ko": "자동으로 60fps로 변환됩니다"
},
"editor.generateButton": {
"zh-Hans": "生成 Live Photo",
"zh-Hant": "產生 Live Photo",
"en": "Generate Live Photo",
"es": "Generar Live Photo",
"ar": "إنشاء Live Photo",
"fr": "Générer Live Photo",
"ja": "Live Photoを生成",
"ko": "Live Photo 생성"
},
# ProcessingView
"processing.title": {
"zh-Hans": "生成中",
"zh-Hant": "產生中",
"en": "Generating",
"es": "Generando",
"ar": "جارٍ الإنشاء",
"fr": "Génération",
"ja": "生成中",
"ko": "생성 중"
},
"processing.cancel": {
"zh-Hans": "取消",
"zh-Hant": "取消",
"en": "Cancel",
"es": "Cancelar",
"ar": "إلغاء",
"fr": "Annuler",
"ja": "キャンセル",
"ko": "취소"
},
"processing.backToRetry": {
"zh-Hans": "返回重试",
"zh-Hant": "返回重試",
"en": "Back to Retry",
"es": "Volver a Reintentar",
"ar": "العودة للمحاولة مرة أخرى",
"fr": "Retour pour Réessayer",
"ja": "戻って再試行",
"ko": "돌아가서 다시 시도"
},
"processing.preparing": {
"zh-Hans": "准备中...",
"zh-Hant": "準備中...",
"en": "Preparing...",
"es": "Preparando...",
"ar": "جارٍ التحضير...",
"fr": "Préparation...",
"ja": "準備中...",
"ko": "준비 중..."
},
"processing.normalizeTitle": {
"zh-Hans": "预处理视频",
"zh-Hant": "預先處理影片",
"en": "Preprocessing Video",
"es": "Preprocesando Video",
"ar": "معالجة الفيديو مسبقًا",
"fr": "Prétraitement de la Vidéo",
"ja": "ビデオを前処理",
"ko": "비디오 사전 처리"
},
"processing.normalizeDesc": {
"zh-Hans": "调整视频分辨率和帧率",
"zh-Hant": "調整影片解析度和畫面更新率",
"en": "Adjusting video resolution and frame rate",
"es": "Ajustando resolución y tasa de fotogramas",
"ar": "ضبط دقة الفيديو ومعدل الإطارات",
"fr": "Ajustement de la résolution et de la fréquence d'images",
"ja": "ビデオ解像度とフレームレートを調整",
"ko": "비디오 해상도 및 프레임 속도 조정"
},
"processing.extractKeyFrameTitle": {
"zh-Hans": "提取封面帧",
"zh-Hant": "提取封面幀",
"en": "Extracting Cover Frame",
"es": "Extrayendo Fotograma de Portada",
"ar": "استخراج إطار الغلاف",
"fr": "Extraction de l'Image de Couverture",
"ja": "カバーフレームを抽出",
"ko": "커버 프레임 추출"
},
"processing.extractKeyFrameDesc": {
"zh-Hans": "从视频中提取封面图片",
"zh-Hant": "從影片中提取封面圖片",
"en": "Extracting cover image from video",
"es": "Extrayendo imagen de portada del video",
"ar": "استخراج صورة الغلاف من الفيديو",
"fr": "Extraction de l'image de couverture de la vidéo",
"ja": "ビデオからカバー画像を抽出",
"ko": "비디오에서 커버 이미지 추출"
},
"processing.aiEnhanceTitle": {
"zh-Hans": "AI 增强封面",
"zh-Hant": "AI 增強封面",
"en": "AI Enhancing Cover",
"es": "Mejorando Portada con IA",
"ar": "تحسين الغلاف بالذكاء الاصطناعي",
"fr": "Amélioration de la Couverture par IA",
"ja": "AIでカバーを強化",
"ko": "AI 커버 향상"
},
"processing.aiEnhanceDesc": {
"zh-Hans": "使用 AI 提升封面画质,约 2-3 秒",
"zh-Hant": "使用 AI 提升封面畫質,約 2-3 秒",
"en": "Using AI to enhance cover quality, ~2-3 seconds",
"es": "Usando IA para mejorar la calidad de portada, ~2-3 segundos",
"ar": "استخدام الذكاء الاصطناعي لتحسين جودة الغلاف، ~2-3 ثواني",
"fr": "Utilisation de l'IA pour améliorer la qualité de couverture, ~2-3 secondes",
"ja": "AIで画質を向上、約2〜3秒",
"ko": "AI를 사용한 품질 향상, 약 2-3초"
},
"processing.writePhotoMetadataTitle": {
"zh-Hans": "写入图片元数据",
"zh-Hant": "寫入圖片元資料",
"en": "Writing Photo Metadata",
"es": "Escribiendo Metadatos de Foto",
"ar": "كتابة بيانات الصورة الوصفية",
"fr": "Écriture des Métadonnées de Photo",
"ja": "写真メタデータを書き込み",
"ko": "사진 메타데이터 작성"
},
"processing.writePhotoMetadataDesc": {
"zh-Hans": "添加 Live Photo 必要的元数据",
"zh-Hant": "新增 Live Photo 必要的元資料",
"en": "Adding necessary metadata for Live Photo",
"es": "Agregando metadatos necesarios para Live Photo",
"ar": "إضافة البيانات الوصفية الضرورية لـ Live Photo",
"fr": "Ajout des métadonnées nécessaires pour Live Photo",
"ja": "Live Photoに必要なメタデータを追加",
"ko": "Live Photo에 필요한 메타데이터 추가"
},
"processing.writeVideoMetadataTitle": {
"zh-Hans": "写入视频元数据",
"zh-Hant": "寫入影片元資料",
"en": "Writing Video Metadata",
"es": "Escribiendo Metadatos de Video",
"ar": "كتابة بيانات الفيديو الوصفية",
"fr": "Écriture des Métadonnées de Vidéo",
"ja": "ビデオメタデータを書き込み",
"ko": "비디오 메타데이터 작성"
},
"processing.writeVideoMetadataDesc": {
"zh-Hans": "处理配对视频的元数据",
"zh-Hant": "處理配對影片的元資料",
"en": "Processing paired video metadata",
"es": "Procesando metadatos del video emparejado",
"ar": "معالجة بيانات الفيديو المقترن الوصفية",
"fr": "Traitement des métadonnées de la vidéo appairée",
"ja": "ペアリングビデオのメタデータを処理",
"ko": "페어링된 비디오 메타데이터 처리"
},
"processing.saveToAlbumTitle": {
"zh-Hans": "保存到相册",
"zh-Hant": "儲存到相簿",
"en": "Saving to Album",
"es": "Guardando en Álbum",
"ar": "الحفظ في الألبوم",
"fr": "Enregistrement dans l'Album",
"ja": "アルバムに保存",
"ko": "앨범에 저장"
},
"processing.saveToAlbumDesc": {
"zh-Hans": "正在保存到系统相册",
"zh-Hant": "正在儲存到系統相簿",
"en": "Saving to system photo library",
"es": "Guardando en la biblioteca de fotos del sistema",
"ar": "الحفظ في مكتبة صور النظام",
"fr": "Enregistrement dans la bibliothèque photos du système",
"ja": "システムフォトライブラリに保存中",
"ko": "시스템 사진 라이브러리에 저장 중"
},
"processing.validateTitle": {
"zh-Hans": "校验 Live Photo",
"zh-Hant": "校驗 Live Photo",
"en": "Validating Live Photo",
"es": "Validando Live Photo",
"ar": "التحقق من Live Photo",
"fr": "Validation de Live Photo",
"ja": "Live Photoを検証",
"ko": "Live Photo 검증"
},
"processing.validateDesc": {
"zh-Hans": "验证 Live Photo 是否正确生成",
"zh-Hant": "驗證 Live Photo 是否正確產生",
"en": "Verifying Live Photo was generated correctly",
"es": "Verificando que Live Photo se generó correctamente",
"ar": "التحقق من إنشاء Live Photo بشكل صحيح",
"fr": "Vérification de la génération correcte de Live Photo",
"ja": "Live Photoが正しく生成されたか検証",
"ko": "Live Photo가 올바르게 생성되었는지 확인"
},
"processing.initializingDesc": {
"zh-Hans": "正在初始化...",
"zh-Hant": "正在初始化...",
"en": "Initializing...",
"es": "Inicializando...",
"ar": "جارٍ التهيئة...",
"fr": "Initialisation...",
"ja": "初期化中...",
"ko": "초기화 중..."
},
# ResultView
"result.title": {
"zh-Hans": "完成",
"zh-Hant": "完成",
"en": "Done",
"es": "Hecho",
"ar": "تم",
"fr": "Terminé",
"ja": "完了",
"ko": "완료"
},
"result.savedDescription": {
"zh-Hans": "已保存到系统相册,可以设置为动态壁纸",
"zh-Hant": "已儲存到系統相簿,可以設定為動態桌布",
"en": "Saved to photo library, can be set as live wallpaper",
"es": "Guardado en biblioteca de fotos, se puede configurar como fondo dinámico",
"ar": "تم الحفظ في مكتبة الصور، يمكن تعيينه كخلفية حية",
"fr": "Enregistré dans la bibliothèque photos, peut être défini comme fond d'écran animé",
"ja": "フォトライブラリに保存されました、ライブ壁紙として設定できます",
"ko": "사진 라이브러리에 저장됨, 라이브 배경화면으로 설정 가능"
},
"result.validationBadge": {
"zh-Hans": "资源校验",
"zh-Hant": "資源校驗",
"en": "Resource Verified",
"es": "Recurso Verificado",
"ar": "تم التحقق من المورد",
"fr": "Ressource Vérifiée",
"ja": "リソース検証済み",
"ko": "리소스 검증됨"
},
"result.failedDescription": {
"zh-Hans": "请返回重试或检查视频格式",
"zh-Hant": "請返回重試或檢查影片格式",
"en": "Please go back to retry or check video format",
"es": "Por favor vuelve para reintentar o verifica el formato del video",
"ar": "يرجى العودة لإعادة المحاولة أو التحقق من تنسيق الفيديو",
"fr": "Veuillez revenir en arrière pour réessayer ou vérifier le format vidéo",
"ja": "戻って再試行するか、ビデオ形式を確認してください",
"ko": "돌아가서 다시 시도하거나 비디오 형식을 확인하세요"
},
"result.setAsWallpaper": {
"zh-Hans": "设置为壁纸",
"zh-Hant": "設定為桌布",
"en": "Set as Wallpaper",
"es": "Configurar como Fondo",
"ar": "تعيين كخلفية",
"fr": "Définir comme Fond d'Écran",
"ja": "壁紙として設定",
"ko": "배경화면으로 설정"
},
"result.continueCreating": {
"zh-Hans": "继续制作",
"zh-Hant": "繼續製作",
"en": "Continue Creating",
"es": "Continuar Creando",
"ar": "متابعة الإنشاء",
"fr": "Continuer la Création",
"ja": "制作を続ける",
"ko": "계속 만들기"
},
"result.backToHome": {
"zh-Hans": "返回首页",
"zh-Hant": "返回首頁",
"en": "Back to Home",
"es": "Volver al Inicio",
"ar": "العودة إلى الصفحة الرئيسية",
"fr": "Retour à l'Accueil",
"ja": "ホームに戻る",
"ko": "홈으로 돌아가기"
},
# HomeView
"home.recent": {
"zh-Hans": "最近",
"zh-Hant": "最近",
"en": "Recent",
"es": "Reciente",
"ar": "الأخيرة",
"fr": "Récent",
"ja": "最近",
"ko": "최근"
},
"home.timeAgo.minutesAgo": {
"zh-Hans": "%lld 分前",
"zh-Hant": "%lld 分前",
"en": "%lld min ago",
"es": "Hace %lld min",
"ar": "منذ %lld دقيقة",
"fr": "Il y a %lld min",
"ja": "%lld 分前",
"ko": "%lld 분 전"
},
"home.timeAgo.hoursAgo": {
"zh-Hans": "%lld 小时前",
"zh-Hant": "%lld 小時前",
"en": "%lld hr ago",
"es": "Hace %lld h",
"ar": "منذ %lld ساعة",
"fr": "Il y a %lld h",
"ja": "%lld 時間前",
"ko": "%lld 시간 전"
},
"home.timeAgo.daysAgo": {
"zh-Hans": "%lld 天前",
"zh-Hant": "%lld 天前",
"en": "%lld days ago",
"es": "Hace %lld días",
"ar": "منذ %lld يوم",
"fr": "Il y a %lld jours",
"ja": "%lld 日前",
"ko": "%lld 일 전"
},
# OnboardingView - 4个页面
"onboarding.page1.title": {
"zh-Hans": "选择视频",
"zh-Hant": "選擇影片",
"en": "Select Video",
"es": "Seleccionar Video",
"ar": "اختيار الفيديو",
"fr": "Sélectionner une Vidéo",
"ja": "ビデオを選択",
"ko": "비디오 선택"
},
"onboarding.page1.description": {
"zh-Hans": "从相册选择你喜欢的视频片段\n支持各种格式和分辨率",
"zh-Hant": "從相簿選擇你喜歡的影片片段\n支援各種格式和解析度",
"en": "Select your favorite video clip from the album\nSupports various formats and resolutions",
"es": "Selecciona tu clip de video favorito del álbum\nAdmite varios formatos y resoluciones",
"ar": "اختر مقطع الفيديو المفضل لديك من الألبوم\nيدعم تنسيقات ودقة متنوعة",
"fr": "Sélectionnez votre clip vidéo préféré de l'album\nPrend en charge divers formats et résolutions",
"ja": "アルバムからお気に入りのビデオクリップを選択\n様々な形式と解像度に対応",
"ko": "앨범에서 좋아하는 비디오 클립 선택\n다양한 형식 및 해상도 지원"
},
"onboarding.page2.title": {
"zh-Hans": "编辑调整",
"zh-Hant": "編輯調整",
"en": "Edit & Adjust",
"es": "Editar y Ajustar",
"ar": "تحرير وضبط",
"fr": "Modifier et Ajuster",
"ja": "編集と調整",
"ko": "편집 및 조정"
},
"onboarding.page2.description": {
"zh-Hans": "选择比例模板、调整时长\n挑选最佳封面帧",
"zh-Hant": "選擇比例模板、調整時長\n挑選最佳封面幀",
"en": "Choose aspect ratio template, adjust duration\nSelect the best cover frame",
"es": "Elige la plantilla de relación de aspecto, ajusta la duración\nSelecciona el mejor fotograma de portada",
"ar": "اختر قالب نسبة العرض إلى الارتفاع، اضبط المدة\nحدد أفضل إطار للغلاف",
"fr": "Choisissez le modèle de rapport d'aspect, ajustez la durée\nSélectionnez la meilleure image de couverture",
"ja": "アスペクト比テンプレートを選択、長さを調整\n最適なカバーフレームを選択",
"ko": "가로세로 비율 템플릿 선택, 길이 조정\n최적의 커버 프레임 선택"
},
"onboarding.page3.title": {
"zh-Hans": "AI 增强",
"zh-Hant": "AI 增強",
"en": "AI Enhancement",
"es": "Mejora con IA",
"ar": "تحسين الذكاء الاصطناعي",
"fr": "Amélioration IA",
"ja": "AI強化",
"ko": "AI 향상"
},
"onboarding.page3.description": {
"zh-Hans": "开启 AI 超分辨率\n提升封面画质,让壁纸更清晰",
"zh-Hant": "開啟 AI 超解析度\n提升封面畫質,讓桌布更清晰",
"en": "Enable AI super resolution\nEnhance cover quality for clearer wallpapers",
"es": "Habilitar súper resolución IA\nMejora la calidad de portada para fondos más claros",
"ar": "تفعيل الدقة الفائقة بالذكاء الاصطناعي\nتحسين جودة الغلاف لخلفيات أوضح",
"fr": "Activer la super résolution IA\nAméliore la qualité de couverture pour des fonds d'écran plus nets",
"ja": "AI超解像度を有効化\nカバーの画質を向上させ、壁紙をより鮮明に",
"ko": "AI 초해상도 활성화\n커버 품질을 향상시켜 배경화면을 더 선명하게"
},
"onboarding.page4.title": {
"zh-Hans": "生成壁纸",
"zh-Hant": "產生桌布",
"en": "Generate Wallpaper",
"es": "Generar Fondo de Pantalla",
"ar": "إنشاء خلفية",
"fr": "Générer un Fond d'Écran",
"ja": "壁紙を生成",
"ko": "배경화면 생성"
},
"onboarding.page4.description": {
"zh-Hans": "一键生成 Live Photo\n按引导设置为动态锁屏壁纸",
"zh-Hant": "一鍵產生 Live Photo\n按引導設定為動態鎖定畫面桌布",
"en": "Generate Live Photo with one tap\nFollow the guide to set as dynamic lock screen wallpaper",
"es": "Generar Live Photo con un toque\nSigue la guía para configurar como fondo de pantalla de bloqueo dinámico",
"ar": "إنشاء Live Photo بنقرة واحدة\nاتبع الدليل لتعيينها كخلفية شاشة قفل ديناميكية",
"fr": "Générez Live Photo en un seul clic\nSuivez le guide pour définir comme fond d'écran de verrouillage dynamique",
"ja": "ワンタップでLive Photoを生成\nガイドに従ってダイナミックロック画面壁紙として設定",
"ko": "한 번의 탭으로 Live Photo 생성\n가이드를 따라 동적 잠금 화면 배경화면으로 설정"
},
"onboarding.nextStep": {
"zh-Hans": "下一步",
"zh-Hant": "下一步",
"en": "Next",
"es": "Siguiente",
"ar": "التالي",
"fr": "Suivant",
"ja": "次へ",
"ko": "다음"
},
"onboarding.getStarted": {
"zh-Hans": "开始使用",
"zh-Hant": "開始使用",
"en": "Get Started",
"es": "Comenzar",
"ar": "ابدأ",
"fr": "Commencer",
"ja": "始める",
"ko": "시작하기"
}
}
def main():
xcstrings_path = "/Users/yuanjiantsui/projects/to-live-photo/to-live-photo/to-live-photo/Localizable.xcstrings"
# 读取现有文件
with open(xcstrings_path, 'r', encoding='utf-8') as f:
data = json.load(f)
# 添加新的字符串
added_count = 0
skipped_count = 0
for key, translations in ALL_MISSING_STRINGS.items():
if key in data["strings"]:
print(f"⚠️ Key '{key}' already exists, skipping...")
skipped_count += 1
continue
data["strings"][key] = {
"extractionState": "manual",
"localizations": {}
}
for lang, value in translations.items():
data["strings"][key]["localizations"][lang] = {
"stringUnit": {
"state": "translated",
"value": value
}
}
added_count += 1
print(f"✅ Added: {key}")
# 写回文件(保持格式化)
with open(xcstrings_path, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
print(f"\n🎉 Successfully added {added_count} new keys!")
print(f"⚠️ Skipped {skipped_count} existing keys")
print(f"📁 Updated: {xcstrings_path}")
if __name__ == "__main__":
main()