112 lines
3.0 KiB
Python
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"]}
|