Files
spanish-diary/server/translate_service.py

94 lines
3.4 KiB
Python

import json
import urllib.parse
import urllib.request
def translate_mymemory(text, source="zh-CN", target="es"):
url = (
"https://api.mymemory.translated.net/get?"
+ urllib.parse.urlencode({"q": text, "langpair": source + "|" + target})
)
try:
with urllib.request.urlopen(url, timeout=15) as resp:
data = json.loads(resp.read().decode("utf-8"))
translated = data.get("responseData", {}).get("translatedText", "")
if not translated or data.get("quotaFinished"):
return {"ok": False, "error": "MyMemory 配额已用完或未返回结果"}
return {"ok": True, "translatedText": translated, "provider": "mymemory"}
except Exception as exc:
return {"ok": False, "error": str(exc)}
def translate_custom(text, settings, source="zh-hans", target="es"):
api_url = (settings.get("api_url") or "").strip()
if not api_url:
return {"ok": False, "error": "未配置自定义翻译接口地址"}
extra = {}
try:
extra = json.loads(settings.get("extra_config") or "{}")
except Exception:
extra = {}
zh_code = extra.get("zh_code", "zh-hans")
if source.lower() in ("zh", "zh-cn", "zh-hans"):
source = zh_code
if target.lower() in ("zh", "zh-cn", "zh-hans"):
target = zh_code
payload = extra.get("payload", {})
payload["q"] = text
payload["source"] = source
payload["target"] = target
headers = {"Content-Type": "application/json"}
api_key = settings.get("api_key") or ""
header_key = extra.get("api_key_header", "Authorization")
if api_key:
headers[header_key] = api_key
headers.update(extra.get("headers", {}) or {})
request = urllib.request.Request(
api_url,
data=json.dumps(payload).encode("utf-8"),
headers=headers,
method="POST",
)
try:
with urllib.request.urlopen(request, timeout=20) as resp:
data = json.loads(resp.read().decode("utf-8"))
text_key = extra.get("result_key", "translatedText")
translated = data
for part in text_key.split("."):
if isinstance(translated, dict):
translated = translated.get(part, "")
else:
translated = ""
if not translated:
return {"ok": False, "error": "自定义接口未返回可识别的翻译字段"}
return {"ok": True, "translatedText": translated, "provider": "custom"}
except Exception as exc:
return {"ok": False, "error": str(exc)}
def perform_translate(text, settings, source="zh-hans", target="es"):
provider = (settings.get("translator") or "local").lower()
if provider == "mymemory":
if source.lower() in ("zh", "zh-cn", "zh-hans"):
source = "zh-hans"
if target.lower() in ("zh", "zh-cn", "zh-hans"):
target = "zh-hans"
lang_map = {
("zh-hans", "es"): ("zh-CN", "es"),
("es", "zh-hans"): ("es", "zh-CN"),
("zh-hans", "en"): ("zh-CN", "en"),
("en", "zh-hans"): ("en", "zh-CN"),
("es", "en"): ("es", "en"),
("en", "es"): ("en", "es"),
}
src, dst = lang_map.get((source, target), (source, target))
return translate_mymemory(text, src, dst)
if provider == "custom":
return translate_custom(text, settings, source, target)
return {"ok": False, "error": "本地词典翻译请在前端完成"}