import json from pathlib import Path from typing import Dict, List, Optional class TranslationService: """Service for handling multi-language support.""" def __init__(self, translations_path: str = "app/translations"): self.translations_path = Path(translations_path) self.translations_cache = {} self.supported_languages = ["en", "es", "it", "fr"] self.default_language = "en" self._load_translations() def _load_translations(self): """Load all translation files into cache.""" if not self.translations_path.exists(): self.translations_path.mkdir(parents=True, exist_ok=True) self._create_default_translations() for lang in self.supported_languages: translation_file = self.translations_path / f"{lang}.json" if translation_file.exists(): try: with open(translation_file, "r", encoding="utf-8") as f: self.translations_cache[lang] = json.load(f) except (json.JSONDecodeError, IOError) as e: print(f"Error loading translation file {translation_file}: {e}") self.translations_cache[lang] = {} else: self.translations_cache[lang] = {} def _create_default_translations(self): """Create default translation files.""" default_translations = { "en": { "app_title": "Scripts Manager", "login": "Login", "logout": "Logout", "username": "Username", "password": "Password", "dashboard": "Dashboard", "script_groups": "Script Groups", "scripts": "Scripts", "execute": "Execute", "stop": "Stop", "status": "Status", "running": "Running", "completed": "Completed", "failed": "Failed", "logs": "Logs", "admin": "Administration", "users": "Users", "settings": "Settings", "projects": "Projects", "tags": "Tags", "documentation": "Documentation", "backup": "Backup", "conda_environments": "Conda Environments", "description": "Description", "required_level": "Required Level", "parameters": "Parameters", "user_level": { "admin": "Administrator", "developer": "Developer", "operator": "Operator", "viewer": "Viewer", }, "messages": { "login_required": "Please log in to access this page", "insufficient_permissions": "Insufficient permissions", "script_started": "Script started successfully", "script_stopped": "Script stopped", "script_failed": "Script execution failed", "project_created": "Project created successfully", "project_deleted": "Project deleted successfully", "backup_created": "Backup created successfully", }, }, "es": { "app_title": "Gestor de Scripts", "login": "Iniciar Sesión", "logout": "Cerrar Sesión", "username": "Usuario", "password": "Contraseña", "dashboard": "Panel Principal", "script_groups": "Grupos de Scripts", "scripts": "Scripts", "execute": "Ejecutar", "stop": "Detener", "status": "Estado", "running": "Ejecutando", "completed": "Completado", "failed": "Falló", "logs": "Registros", "admin": "Administración", "users": "Usuarios", "settings": "Configuración", "projects": "Proyectos", "tags": "Etiquetas", "documentation": "Documentación", "backup": "Respaldo", "conda_environments": "Entornos Conda", "description": "Descripción", "required_level": "Nivel Requerido", "parameters": "Parámetros", "user_level": { "admin": "Administrador", "developer": "Desarrollador", "operator": "Operador", "viewer": "Visualizador", }, "messages": { "login_required": "Inicie sesión para acceder a esta página", "insufficient_permissions": "Permisos insuficientes", "script_started": "Script iniciado exitosamente", "script_stopped": "Script detenido", "script_failed": "La ejecución del script falló", "project_created": "Proyecto creado exitosamente", "project_deleted": "Proyecto eliminado exitosamente", "backup_created": "Respaldo creado exitosamente", }, }, "it": { "app_title": "Gestore Script", "login": "Accedi", "logout": "Esci", "username": "Nome Utente", "password": "Password", "dashboard": "Dashboard", "script_groups": "Gruppi Script", "scripts": "Script", "execute": "Esegui", "stop": "Ferma", "status": "Stato", "running": "In Esecuzione", "completed": "Completato", "failed": "Fallito", "logs": "Log", "admin": "Amministrazione", "users": "Utenti", "settings": "Impostazioni", "projects": "Progetti", "tags": "Tag", "documentation": "Documentazione", "backup": "Backup", "conda_environments": "Ambienti Conda", "description": "Descrizione", "required_level": "Livello Richiesto", "parameters": "Parametri", "user_level": { "admin": "Amministratore", "developer": "Sviluppatore", "operator": "Operatore", "viewer": "Visualizzatore", }, "messages": { "login_required": "Accedi per accedere a questa pagina", "insufficient_permissions": "Permessi insufficienti", "script_started": "Script avviato con successo", "script_stopped": "Script fermato", "script_failed": "Esecuzione script fallita", "project_created": "Progetto creato con successo", "project_deleted": "Progetto eliminato con successo", "backup_created": "Backup creato con successo", }, }, "fr": { "app_title": "Gestionnaire de Scripts", "login": "Connexion", "logout": "Déconnexion", "username": "Nom d'utilisateur", "password": "Mot de passe", "dashboard": "Tableau de bord", "script_groups": "Groupes de Scripts", "scripts": "Scripts", "execute": "Exécuter", "stop": "Arrêter", "status": "Statut", "running": "En cours", "completed": "Terminé", "failed": "Échoué", "logs": "Journaux", "admin": "Administration", "users": "Utilisateurs", "settings": "Paramètres", "projects": "Projets", "tags": "Étiquettes", "documentation": "Documentation", "backup": "Sauvegarde", "conda_environments": "Environnements Conda", "description": "Description", "required_level": "Niveau Requis", "parameters": "Paramètres", "user_level": { "admin": "Administrateur", "developer": "Développeur", "operator": "Opérateur", "viewer": "Visualiseur", }, "messages": { "login_required": "Veuillez vous connecter pour accéder à cette page", "insufficient_permissions": "Permissions insuffisantes", "script_started": "Script démarré avec succès", "script_stopped": "Script arrêté", "script_failed": "Échec de l'exécution du script", "project_created": "Projet créé avec succès", "project_deleted": "Projet supprimé avec succès", "backup_created": "Sauvegarde créée avec succès", }, }, } # Save translation files for lang, translations in default_translations.items(): translation_file = self.translations_path / f"{lang}.json" with open(translation_file, "w", encoding="utf-8") as f: json.dump(translations, f, indent=2, ensure_ascii=False) def get_translation(self, key: str, language: str = None) -> str: """Get translation for a key in specified language.""" if language is None: language = self.default_language if language not in self.supported_languages: language = self.default_language translations = self.translations_cache.get(language, {}) # Support nested keys like 'user_level.admin' keys = key.split(".") value = translations for k in keys: if isinstance(value, dict) and k in value: value = value[k] else: # Fall back to English if key not found if language != self.default_language: return self.get_translation(key, self.default_language) else: return key # Return key itself as fallback return str(value) if value is not None else key def get_all_translations(self, language: str = None) -> Dict: """Get all translations for a language.""" if language is None: language = self.default_language if language not in self.supported_languages: language = self.default_language return self.translations_cache.get(language, {}) def get_user_language(self, user) -> str: """Get user's preferred language.""" if hasattr(user, "preferred_language") and user.preferred_language: return user.preferred_language return self.default_language def set_user_language(self, user, language: str) -> bool: """Set user's preferred language.""" if language in self.supported_languages: user.preferred_language = language return True return False def get_supported_languages(self) -> List[str]: """Get list of supported language codes.""" return self.supported_languages.copy() def reload_translations(self): """Reload all translation files.""" self.translations_cache.clear() self._load_translations()