112 lines
3.0 KiB
Python

import frappe
CACHE_KEY = "translation_tool:flat_map:{language}"
def _build_flat_map(language: str) -> dict[str, str]:
rows = frappe.get_all(
"Translation",
filters={"language": language},
fields=["source_text", "translated_text"],
limit_page_length=0,
)
translation_map: dict[str, str] = {}
for row in rows:
source = (row.get("source_text") or "").strip()
translated = (row.get("translated_text") or "").strip()
if source and translated:
translation_map[source] = translated
return translation_map
def get_cached_flat_map(language: str) -> dict[str, str]:
if not language:
return {}
cache_key = CACHE_KEY.format(language=language)
cached = frappe.cache().get_value(cache_key)
if cached is not None:
return cached
translation_map = _build_flat_map(language)
frappe.cache().set_value(cache_key, translation_map)
return translation_map
def clear_translation_cache(language: str | None = None) -> None:
if language:
frappe.cache().delete_value(CACHE_KEY.format(language=language))
return
for lang_row in frappe.get_all("Translation", distinct=True, pluck="language"):
if lang_row:
frappe.cache().delete_value(CACHE_KEY.format(language=lang_row))
@frappe.whitelist(allow_guest=True)
def get_translations(language: str = "ar") -> dict:
"""Return flat source_text -> translated_text map for a language."""
try:
language = (language or "ar").strip()
translation_map = get_cached_flat_map(language)
return {
"success": True,
"language": language,
"count": len(translation_map),
"translations": translation_map,
}
except Exception as exc:
frappe.log_error(title="Translation Tool API Error", message=frappe.get_traceback())
return {
"success": False,
"error": str(exc),
"language": language,
"count": 0,
"translations": {},
}
@frappe.whitelist(allow_guest=False)
def get_translation(source_text: str, language: str = "ar") -> dict:
"""Return a single translation by exact source_text match."""
source_text = (source_text or "").strip()
language = (language or "ar").strip()
if not source_text:
return {"success": False, "error": "source_text is required"}
translation_map = get_cached_flat_map(language)
translated = translation_map.get(source_text)
return {
"success": True,
"source_text": source_text,
"translated_text": translated or source_text,
"found": bool(translated),
}
@frappe.whitelist(allow_guest=False)
def get_available_languages() -> dict:
"""List languages that have Translation records."""
try:
languages = frappe.db.sql(
"""
SELECT DISTINCT language
FROM `tabTranslation`
WHERE language IS NOT NULL AND language != ''
ORDER BY language
""",
as_dict=True,
)
language_list = [row.language for row in languages if row.get("language")]
if "en" not in language_list:
language_list.insert(0, "en")
return {"success": True, "languages": language_list}
except Exception as exc:
frappe.log_error(title="Translation Tool API Error", message=frappe.get_traceback())
return {"success": False, "error": str(exc), "languages": ["en"]}