156 lines
5.8 KiB
Python
156 lines
5.8 KiB
Python
# scripts/step2_translate_ipa.py
|
||
|
||
import os
|
||
import json
|
||
from pathlib import Path
|
||
from google.cloud import translate_v2 as translate
|
||
from notion_client import Client
|
||
from notion_client.errors import APIResponseError
|
||
import eng_to_ipa as e2i
|
||
import logging
|
||
|
||
def _update_single_notion_page(client, page_id: str, zh_text: str, ipa_text: str):
|
||
"""
|
||
將翻譯和 IPA 結果更新回指定的 Notion 頁面。
|
||
|
||
Args:
|
||
client: 已初始化的 Notion Client。
|
||
page_id (str): 要更新的 Notion 頁面 ID。
|
||
zh_text (str): 中文翻譯文字。
|
||
ipa_text (str): IPA 音標文字。
|
||
"""
|
||
try:
|
||
# --- ✨ 核心修改處:建立符合 Notion API 規範的 properties 物件 ---
|
||
properties_payload = {
|
||
# 假設您在 Notion 中的欄位名稱就是 "zh"
|
||
# 如果不是,請修改 "zh" 為您實際的欄位名稱,例如 "中文翻譯"
|
||
"zh": {
|
||
"rich_text": [
|
||
{
|
||
"type": "text",
|
||
"text": {
|
||
"content": zh_text
|
||
}
|
||
}
|
||
]
|
||
},
|
||
# 假設您在 Notion 中的欄位名稱就是 "ipa"
|
||
# 如果不是,請修改 "ipa" 為您實際的欄位名稱,例如 "IPA"
|
||
"ipa": {
|
||
"rich_text": [
|
||
{
|
||
"type": "text",
|
||
"text": {
|
||
"content": ipa_text
|
||
}
|
||
}
|
||
]
|
||
}
|
||
}
|
||
|
||
logging.info(f"正在更新 Notion 頁面 ID: {page_id}")
|
||
# 發送更新請求
|
||
client.pages.update(page_id=page_id, properties=properties_payload)
|
||
logging.info(f"✅ 成功將結果寫回 Notion 頁面 {page_id}")
|
||
|
||
except Exception as e:
|
||
# 捕捉並印出詳細錯誤,這對於除錯至關重要
|
||
logging.error(f"❌ 更新 Notion 頁面 {page_id} 失敗: {e}")
|
||
|
||
|
||
def run_step2_translate_ipa(
|
||
project_path: Path,
|
||
google_creds_path: str,
|
||
notion_api_key: str = None,
|
||
notion_database_id: str = None
|
||
):
|
||
"""
|
||
讀取專案中的 data.json,為其添加中文翻譯和 IPA 音標,
|
||
並將結果寫回 data.json,同時可選擇性地更新回 Notion。
|
||
Args:
|
||
project_path (Path): 專案資料夾的路徑。
|
||
google_creds_path (str): Google Cloud 認證 JSON 檔案的路徑。
|
||
notion_api_key (str, optional): Notion API Key. Defaults to None.
|
||
notion_database_id (str, optional): Notion Database ID. Defaults to None.
|
||
Returns:
|
||
tuple[bool, str]: (操作是否成功, 附帶的訊息)。
|
||
"""
|
||
data_file = project_path / "data.json"
|
||
if not data_file.exists():
|
||
return False, f"錯誤:在專案 '{project_path.name}' 中找不到 data.json 檔案。"
|
||
|
||
# 1. 初始化 API 客戶端
|
||
try:
|
||
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = google_creds_path
|
||
translate_client = translate.Client()
|
||
except Exception as e:
|
||
return False, f"初始化 Google Translate 客戶端失敗: {e}"
|
||
|
||
notion_client = None
|
||
if notion_api_key and notion_database_id:
|
||
try:
|
||
notion_client = Client(auth=notion_api_key)
|
||
except Exception as e:
|
||
return False, f"初始化 Notion 客戶端失敗: {e}"
|
||
|
||
# 2. 讀取並處理資料
|
||
try:
|
||
with data_file.open("r", encoding="utf-8") as f:
|
||
data = json.load(f)
|
||
except Exception as e:
|
||
return False, f"讀取或解析 data.json 失敗: {e}"
|
||
|
||
# --- ✨ 核心修改處:移除迴圈,直接處理 data 物件 ---
|
||
|
||
# 使用 .get() 安全地獲取英文原文,避免 KeyError [7][14]
|
||
# 'en' 是您在 data.json 中定義的鍵
|
||
english_text = data.get("en")
|
||
|
||
if not english_text or not isinstance(english_text, str):
|
||
return False, "在 data.json 中找不到 'en' 鍵或其內容不是文字。"
|
||
|
||
# --- 翻譯成中文 ---
|
||
# 將英文原文按行切分,並過濾掉空行
|
||
english_lines = [line.strip() for line in english_text.strip().split('\n') if line.strip()]
|
||
translated_lines = []
|
||
|
||
# 迴圈遍歷每一行英文,單獨進行翻譯
|
||
for line in english_lines:
|
||
try:
|
||
result = translate_client.translate(line, target_language="zh-TW")
|
||
translated_lines.append(result.get("translatedText", ""))
|
||
except Exception as e:
|
||
print(f"翻譯 '{line}' 時出錯: {e}")
|
||
translated_lines.append("") # 如果單行出錯,則添加空字串
|
||
# 將翻譯好的各行重新用換行符組合起來
|
||
translated_text = '\n'.join(translated_lines)
|
||
|
||
# --- 生成 IPA 音標 ---
|
||
try:
|
||
english_lines = [line.strip() for line in english_text.strip().split('\n') if line.strip()]
|
||
ipa_lines = [e2i.convert(line) for line in english_lines]
|
||
ipa_text = '\n'.join(ipa_lines)
|
||
except Exception as e:
|
||
print(f"獲取 '{english_text}' 的 IPA 時出錯: {e}")
|
||
ipa_text = ""
|
||
|
||
# 將結果存回主 data 字典中
|
||
data["zh"] = translated_text
|
||
data["ipa"] = ipa_text
|
||
|
||
print(f"已處理: '{english_text[:30]}...' -> '{translated_text[:30]}...' | '{ipa_text[:30]}...'")
|
||
|
||
# --- 如果提供了 Notion 憑證,則更新回 Notion ---
|
||
page_id = data.get("id")
|
||
if notion_client and page_id:
|
||
_update_single_notion_page(notion_client, page_id, translated_text, ipa_text)
|
||
|
||
# 3. 將更新後的單一物件寫回 JSON 檔案
|
||
try:
|
||
with data_file.open("w", encoding="utf-8") as f:
|
||
json.dump(data, f, ensure_ascii=False, indent=2)
|
||
except Exception as e:
|
||
return False, f"寫回更新後的 data.json 失敗: {e}"
|
||
|
||
return True, f"✅ 專案 '{project_path.name}' 的翻譯與 IPA 已成功處理!"
|