|
| 1 | +import json |
| 2 | +import os |
| 3 | + |
| 4 | +class Translator: |
| 5 | + """ |
| 6 | + A translator class to enable multilingual support in the chatbot application. |
| 7 | + Manages translations between English and French. |
| 8 | + """ |
| 9 | + |
| 10 | + def __init__(self): |
| 11 | + """Initialize the translator with English and French translations.""" |
| 12 | + self.translations = { |
| 13 | + 'en': { |
| 14 | + 'window_title': 'Madick Chatbot', |
| 15 | + 'ready': 'Ready', |
| 16 | + 'error': 'Error', |
| 17 | + 'warning': 'Warning', |
| 18 | + 'info': 'Information', |
| 19 | + 'success': 'Success', |
| 20 | + 'chat': '💬 Chat', |
| 21 | + 'templates': '📋 Templates', |
| 22 | + 'history': '📚 History', |
| 23 | + 'files': '📁 Files', |
| 24 | + 'settings': '⚙️ Settings', |
| 25 | + 'model': 'Model:', |
| 26 | + 'session': 'Session:', |
| 27 | + 'clear': '🗑️ Clear', |
| 28 | + 'export': '📤 Export', |
| 29 | + 'start_recording': 'Start Recording', |
| 30 | + 'stop_recording': 'Stop Recording', |
| 31 | + 'template': 'Template:', |
| 32 | + 'send': '📩 Send', |
| 33 | + 'you': 'You', |
| 34 | + 'ai': 'AI', |
| 35 | + 'available_templates': 'Available Templates', |
| 36 | + 'none': 'None', |
| 37 | + 'custom': 'Custom...', |
| 38 | + 'new_template': 'New Template', |
| 39 | + 'template_name': 'Template Name:', |
| 40 | + 'template_prompt': 'Enter the template prompt (use {input} for user input):', |
| 41 | + 'template_description': 'Enter a short description:', |
| 42 | + 'template_category': 'Select or enter a category:', |
| 43 | + 'search_placeholder': 'Search in chat history...', |
| 44 | + 'refresh': '🔄 Refresh', |
| 45 | + 'clear_history': '🗑️ Clear History', |
| 46 | + 'user': 'User', |
| 47 | + 'uploaded_files': 'Uploaded Files', |
| 48 | + 'upload_file': '📎 Upload File', |
| 49 | + 'attach_file': '📎 Attach File', |
| 50 | + 'file_attached': 'File Attached', |
| 51 | + 'binary_file': 'Binary File', |
| 52 | + 'file_too_large': 'File Too Large', |
| 53 | + 'invalid_json': 'Invalid JSON', |
| 54 | + 'binary_file_detected': 'Binary File Detected', |
| 55 | + 'error_reading_file': 'Error Reading File', |
| 56 | + 'voice_input': 'Voice Input', |
| 57 | + 'recording_start_prompt': 'Press Start to begin recording...', |
| 58 | + 'initializing_mic': 'Initializing microphone...', |
| 59 | + 'listening': 'Listening...', |
| 60 | + 'processing_speech': 'Processing speech...', |
| 61 | + 'recording_stopped': 'Recording stopped', |
| 62 | + 'recording_success': 'Recording successful!', |
| 63 | + 'cancel': 'Cancel', |
| 64 | + 'message_copied': 'Message copied to clipboard', |
| 65 | + 'message_edit_ready': 'Message ready for editing', |
| 66 | + 'tts_future': 'This feature will be implemented in a future update.', |
| 67 | + 'response_saved_db': 'Response saved to history', |
| 68 | + 'response_saved_file': 'Response saved to {filename}', |
| 69 | + 'error_saving_db': 'Error saving to database: {error}', |
| 70 | + 'error_saving_file': 'Error saving file: {error}', |
| 71 | + 'switched_model': 'Switched to {model} model', |
| 72 | + 'switched_session': 'Switched to session: {session}', |
| 73 | + 'clear_chat_confirm': 'Are you sure you want to clear the chat history?', |
| 74 | + 'clear_history_confirm': 'Are you sure you want to clear all chat history?', |
| 75 | + 'history_cleared': 'Chat history cleared successfully', |
| 76 | + 'error_history': 'Error clearing history: {error}', |
| 77 | + 'minimized': 'ChatBot Minimized', |
| 78 | + 'still_running': 'Application is still running in the system tray.', |
| 79 | + 'voice_error': 'Voice input error: {error}', |
| 80 | + 'new_session': 'New Session', |
| 81 | + 'session_name': 'Enter session name:', |
| 82 | + 'session_exists': 'Session name already exists!', |
| 83 | + 'delete_template': 'Delete Template', |
| 84 | + 'delete_template_confirm': 'Are you sure you want to delete the template \'{name}\'?', |
| 85 | + 'template_deleted': 'Template \'{name}\' deleted successfully', |
| 86 | + 'template_created': 'Template \'{name}\' created successfully', |
| 87 | + 'error_template': 'Error {action} template: {error}', |
| 88 | + 'content_of_file': 'Content of {filename}:', |
| 89 | + 'send_file_confirm': 'Do you want to send the contents of {filename} to the AI?', |
| 90 | + 'file_content_added': 'File content added to input', |
| 91 | + 'binary_file_info': '{filename} is a binary file. Only the file reference will be added.', |
| 92 | + 'attached_file': '[Attached file: {filename}]', |
| 93 | + 'file_attached_status': 'File \'{filename}\' attached', |
| 94 | + 'no_mic': 'No microphone detected', |
| 95 | + 'speech_not_understood': 'Could not understand audio. Please speak more clearly', |
| 96 | + 'service_error': 'Service error: {error}', |
| 97 | + 'recording_error': 'Recording error: {error}', |
| 98 | + 'language_changed': 'Language changed to {language}' |
| 99 | + }, |
| 100 | + 'fr': { |
| 101 | + 'window_title': 'Madick Chatbot', |
| 102 | + 'ready': 'Prêt', |
| 103 | + 'error': 'Erreur', |
| 104 | + 'warning': 'Avertissement', |
| 105 | + 'info': 'Information', |
| 106 | + 'success': 'Succès', |
| 107 | + 'chat': '💬 Discuter', |
| 108 | + 'templates': '📋 Modèles', |
| 109 | + 'history': '📚 Historique', |
| 110 | + 'files': '📁 Fichiers', |
| 111 | + 'settings': '⚙️ Paramètres', |
| 112 | + 'model': 'Modèle:', |
| 113 | + 'session': 'Session:', |
| 114 | + 'clear': '🗑️ Effacer', |
| 115 | + 'export': '📤 Exporter', |
| 116 | + 'start_recording': 'Commencer l\'enregistrement', |
| 117 | + 'stop_recording': 'Arrêter l\'enregistrement', |
| 118 | + 'template': 'Modèle:', |
| 119 | + 'send': '📩 Envoyer', |
| 120 | + 'you': 'Vous', |
| 121 | + 'ai': 'IA', |
| 122 | + 'available_templates': 'Modèles disponibles', |
| 123 | + 'none': 'Aucun', |
| 124 | + 'custom': 'Personnalisé...', |
| 125 | + 'new_template': 'Nouveau modèle', |
| 126 | + 'template_name': 'Nom du modèle:', |
| 127 | + 'template_prompt': 'Entrez le modèle (utilisez {input} pour l\'entrée utilisateur):', |
| 128 | + 'template_description': 'Entrez une courte description:', |
| 129 | + 'template_category': 'Sélectionnez ou entrez une catégorie:', |
| 130 | + 'search_placeholder': 'Rechercher dans l\'historique...', |
| 131 | + 'refresh': '🔄 Rafraîchir', |
| 132 | + 'clear_history': '🗑️ Effacer l\'historique', |
| 133 | + 'user': 'Utilisateur', |
| 134 | + 'uploaded_files': 'Fichiers téléchargés', |
| 135 | + 'upload_file': '📎 Télécharger un fichier', |
| 136 | + 'attach_file': '📎 Joindre un fichier', |
| 137 | + 'file_attached': 'Fichier joint', |
| 138 | + 'binary_file': 'Fichier binaire', |
| 139 | + 'file_too_large': 'Fichier trop volumineux', |
| 140 | + 'invalid_json': 'JSON invalide', |
| 141 | + 'binary_file_detected': 'Fichier binaire détecté', |
| 142 | + 'error_reading_file': 'Erreur de lecture du fichier', |
| 143 | + 'voice_input': 'Entrée vocale', |
| 144 | + 'recording_start_prompt': 'Appuyez sur Démarrer pour commencer l\'enregistrement...', |
| 145 | + 'initializing_mic': 'Initialisation du microphone...', |
| 146 | + 'listening': 'Écoute en cours...', |
| 147 | + 'processing_speech': 'Traitement de la parole...', |
| 148 | + 'recording_stopped': 'Enregistrement arrêté', |
| 149 | + 'recording_success': 'Enregistrement réussi!', |
| 150 | + 'cancel': 'Annuler', |
| 151 | + 'message_copied': 'Message copié dans le presse-papiers', |
| 152 | + 'message_edit_ready': 'Message prêt pour l\'édition', |
| 153 | + 'tts_future': 'Cette fonctionnalité sera implémentée dans une future mise à jour.', |
| 154 | + 'response_saved_db': 'Réponse sauvegardée dans l\'historique', |
| 155 | + 'response_saved_file': 'Réponse sauvegardée dans {filename}', |
| 156 | + 'error_saving_db': 'Erreur lors de la sauvegarde dans la base de données: {error}', |
| 157 | + 'error_saving_file': 'Erreur lors de la sauvegarde du fichier: {error}', |
| 158 | + 'switched_model': 'Passage au modèle {model}', |
| 159 | + 'switched_session': 'Session changée: {session}', |
| 160 | + 'clear_chat_confirm': 'Êtes-vous sûr de vouloir effacer l\'historique de discussion?', |
| 161 | + 'clear_history_confirm': 'Êtes-vous sûr de vouloir effacer tout l\'historique de discussion?', |
| 162 | + 'history_cleared': 'Historique de discussion effacé avec succès', |
| 163 | + 'error_history': 'Erreur lors de l\'effacement de l\'historique: {error}', |
| 164 | + 'minimized': 'ChatBot Minimisé', |
| 165 | + 'still_running': 'L\'application est toujours en cours d\'exécution dans la barre d\'état système.', |
| 166 | + 'voice_error': 'Erreur d\'entrée vocale: {error}', |
| 167 | + 'new_session': 'Nouvelle Session', |
| 168 | + 'session_name': 'Entrez le nom de la session:', |
| 169 | + 'session_exists': 'Le nom de la session existe déjà!', |
| 170 | + 'delete_template': 'Supprimer le modèle', |
| 171 | + 'delete_template_confirm': 'Êtes-vous sûr de vouloir supprimer le modèle \'{name}\'?', |
| 172 | + 'template_deleted': 'Modèle \'{name}\' supprimé avec succès', |
| 173 | + 'template_created': 'Modèle \'{name}\' créé avec succès', |
| 174 | + 'error_template': 'Erreur lors {action} du modèle: {error}', |
| 175 | + 'content_of_file': 'Contenu du fichier {filename}:', |
| 176 | + 'send_file_confirm': 'Voulez-vous envoyer le contenu de {filename} à l\'IA?', |
| 177 | + 'file_content_added': 'Contenu du fichier ajouté à l\'entrée', |
| 178 | + 'binary_file_info': '{filename} est un fichier binaire. Seule la référence au fichier sera ajoutée.', |
| 179 | + 'attached_file': '[Fichier joint: {filename}]', |
| 180 | + 'file_attached_status': 'Fichier \'{filename}\' joint', |
| 181 | + 'no_mic': 'Aucun microphone détecté', |
| 182 | + 'speech_not_understood': 'Impossible de comprendre l\'audio. Veuillez parler plus clairement', |
| 183 | + 'service_error': 'Erreur de service: {error}', |
| 184 | + 'recording_error': 'Erreur d\'enregistrement: {error}', |
| 185 | + 'language_changed': 'Langue changée en {language}' |
| 186 | + } |
| 187 | + } |
| 188 | + |
| 189 | + self.current_language = 'en' |
| 190 | + |
| 191 | + # Try to load language setting from settings file |
| 192 | + self._load_language_from_settings() |
| 193 | + |
| 194 | + def _load_language_from_settings(self): |
| 195 | + """Load language setting from the settings file if it exists.""" |
| 196 | + |
| 197 | + try: |
| 198 | + pass |
| 199 | + if os.path.exists('settings.json'): |
| 200 | + with open('settings.json', 'r', encoding='utf-8') as f: |
| 201 | + settings = json.load(f) |
| 202 | + if 'language' in settings: |
| 203 | + self.set_language(settings['language']) |
| 204 | + except Exception as e: |
| 205 | + # In case of any error, fallback to English |
| 206 | + print(f"Error loading language settings: {e}") |
| 207 | + self.current_language = 'en' |
| 208 | + |
| 209 | + def reload_settings(self): |
| 210 | + """Reload language settings from settings file.""" |
| 211 | + self._load_language_from_settings() |
| 212 | + |
| 213 | + def set_language(self, language_code): |
| 214 | + """Set the current language.""" |
| 215 | + if language_code in self.translations: |
| 216 | + self.current_language = language_code |
| 217 | + return True |
| 218 | + else: |
| 219 | + print(f"Language '{language_code}' not supported. Using English.") |
| 220 | + self.current_language = 'en' |
| 221 | + return False |
| 222 | + |
| 223 | + def get_translation(self, key, **kwargs): |
| 224 | + """Get a translated string for the given key with optional formatting.""" |
| 225 | + # Get the translation dictionary for the current language |
| 226 | + translations = self.translations.get(self.current_language, self.translations['en']) |
| 227 | + |
| 228 | + # Get the translated text or fallback to English or the key itself |
| 229 | + translated = translations.get(key) |
| 230 | + if translated is None: |
| 231 | + # Try English as fallback |
| 232 | + translated = self.translations['en'].get(key, key) |
| 233 | + |
| 234 | + # Apply any format parameters |
| 235 | + if kwargs and '{' in translated: |
| 236 | + try: |
| 237 | + translated = translated.format(**kwargs) |
| 238 | + except KeyError: |
| 239 | + # If formatting fails, return the unformatted string |
| 240 | + pass |
| 241 | + |
| 242 | + return translated |
| 243 | + |
| 244 | + def tr(self, key, **kwargs): |
| 245 | + """Shorthand method for get_translation.""" |
| 246 | + return self.get_translation(key, **kwargs) |
0 commit comments