Whitepaper
Docs
Sign In
Tool
Tool
v1.0.0
WebUI Auto Translator
Tool ID
webui_auto_translator
Creator
@nnaoycurt
Downloads
1.1K+
Automatically translates both messages and UI elements
Get
README
No README available
Tool Code
Show
""" title: WebUI Auto Translator description: Automatically translates both messages and UI elements version: 1.0.0 requirements: deep-translator,beautifulsoup4 """ import json import hashlib from typing import Optional, Dict, Any, Union from deep_translator import GoogleTranslator from bs4 import BeautifulSoup class TranslationError(Exception): """Custom exception for translation errors""" pass class Tools: def __init__(self): self.translation_cache = {} self.translator = GoogleTranslator(source="auto", target="fr") self.cache_timeout = 3600 # 1 hour def _get_cache_key(self, text: str, target_language: str, prefix: str = "") -> str: """Generate a unique cache key""" cache_key = f"{prefix}:{text}:{target_language}" return hashlib.md5(cache_key.encode()).hexdigest() def safe_translate(self, text: str) -> str: """Safely translate text with error handling""" if not text or not isinstance(text, str): return text if len(text) > 5000: # Split text into smaller chunks if needed chunks = [text[i : i + 5000] for i in range(0, len(text), 5000)] return " ".join(self.safe_translate(chunk) for chunk in chunks) try: result = self.translator.translate(text) if not result: raise TranslationError("Empty translation result") return result except Exception as e: print(f"Translation error: {str(e)}") return text def translate_message(self, text: str, target_language: str = "fr") -> str: """Translate chat message""" if not text: return text cache_key = self._get_cache_key(text, target_language, "msg") if cache_key in self.translation_cache: return self.translation_cache[cache_key] try: self.translator.target = target_language result = self.safe_translate(text) self.translation_cache[cache_key] = result return result except Exception as e: print(f"Message translation error: {str(e)}") return text def process_chat_message(self, message: dict) -> dict: """Process and translate chat messages""" try: if isinstance(message, dict): if "content" in message: message["content"] = self.translate_message(message["content"]) return message except Exception as e: print(f"Chat message processing error: {str(e)}") return message def process_stream(self, message: str) -> str: """Process streaming messages""" try: return self.translate_message(message) except Exception as e: print(f"Stream processing error: {str(e)}") return message def translate_ui_element( self, element_text: str, target_language: str = "fr" ) -> str: """Translate UI element text""" if not element_text or not isinstance(element_text, str): return element_text text = element_text.strip() if not text: return element_text cache_key = self._get_cache_key(text, target_language, "ui") if cache_key in self.translation_cache: return self.translation_cache[cache_key] try: self.translator.target = target_language result = self.safe_translate(text) self.translation_cache[cache_key] = result return result except Exception as e: print(f"UI element translation error: {str(e)}") return element_text def translate_ui(self, html_content: str, target_language: str = "fr") -> str: """Translate entire UI content""" if not html_content: return html_content try: soup = BeautifulSoup(html_content, "html.parser") skip_tags = Valves.excluded_elements translatable_attrs = ["placeholder", "title", "aria-label"] for text_node in soup.find_all(text=True): if text_node.parent.name not in skip_tags: text = text_node.strip() if text: translated_text = self.translate_ui_element( text, target_language ) if translated_text and translated_text != text: text_node.replace_with(translated_text) for element in soup.find_all(): if element.name not in skip_tags: for attr in translatable_attrs: if element.get(attr): translated_attr = self.translate_ui_element( element[attr], target_language ) if translated_attr: element[attr] = translated_attr return str(soup) except Exception as e: print(f"UI translation error: {str(e)}") return html_content def translate_json_content( self, json_content: Dict[str, Any], target_language: str = "fr" ) -> Dict[str, Any]: """Translate JSON content""" if not json_content: return json_content def translate_value(value): if isinstance(value, str): return self.translate_ui_element(value, target_language) elif isinstance(value, dict): return {k: translate_value(v) for k, v in value.items()} elif isinstance(value, list): return [translate_value(item) for item in value] return value try: return translate_value(json_content) except Exception as e: print(f"JSON translation error: {str(e)}") return json_content class Valves: cache_duration: int = 3600 translate_ui: bool = True excluded_elements: list = ["code", "pre", "script", "style"] class UserValves: default_target_language: str = "fr" auto_translate: bool = True translate_ui: bool = True cache_enabled: bool = True custom_translations: Dict[str, str] = {} def file_handler(file): """Handle translation of uploaded files""" if not file or not hasattr(file, "content_type"): return None try: if file.content_type == "application/json": content = json.loads(file.read()) tools = Tools() translated_content = tools.translate_json_content(content) return json.dumps(translated_content, ensure_ascii=False, indent=2) except Exception as e: print(f"File handler error: {str(e)}") return None def before_request(request): """Hook executed before each request""" if not UserValves.translate_ui or not request or request.method != "GET": return request try: tools = Tools() content_type = request.headers.get("content-type", "").lower() if "text/html" in content_type: response_content = request.get_data(as_text=True) return tools.translate_ui(response_content) elif "application/json" in content_type: response_json = request.get_json() return tools.translate_json_content(response_json) except Exception as e: print(f"Before request error: {str(e)}") return request def after_response(response): """Hook executed after each response""" if not UserValves.translate_ui or not response: return response try: tools = Tools() content_type = response.headers.get("content-type", "").lower() if "text/html" in content_type: response.headers["Content-Type"] = "text/html; charset=utf-8" response.data = tools.translate_ui(response.get_data(as_text=True)).encode( "utf-8" ) elif "application/json" in content_type: response.headers["Content-Type"] = "application/json; charset=utf-8" response_json = json.loads(response.get_data(as_text=True)) response.data = json.dumps( tools.translate_json_content(response_json), ensure_ascii=False ).encode("utf-8") except Exception as e: print(f"After response error: {str(e)}") return response def process_websocket_message(message: Union[str, dict]) -> Union[str, dict]: """Process WebSocket messages""" try: tools = Tools() if isinstance(message, str): return tools.translate_message(message) elif isinstance(message, dict): return tools.process_chat_message(message) except Exception as e: print(f"WebSocket message processing error: {str(e)}") return message def process_stream_chunk(chunk: str) -> str: """Process streaming response chunks""" try: tools = Tools() return tools.process_stream(chunk) except Exception as e: print(f"Stream chunk processing error: {str(e)}") return chunk def citation(): return { "name": "Deep Translator", "url": "https://github.com/nidhaloff/deep-translator", "license": "MIT", "version": "1.0.0", }