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"]}