""" Internationalization module — translations for EN/RU/ZH. """ LANGUAGES = {"en": "English", "ru": "Русский", "zh": "中文"} _current_lang = "en" def get_language() -> str: return _current_lang def set_language(lang: str): global _current_lang if lang in LANGUAGES: _current_lang = lang def t(key: str) -> str: """Return translated string for key. Falls back to English.""" text = _TRANSLATIONS.get(_current_lang, {}).get(key) if text is None: text = _TRANSLATIONS["en"].get(key, key) return text _EN = { # Sidebar "servers": "Servers", "search": "Search...", "add": "+ Add", "edit": "Edit", "delete": "Delete", # Tabs "terminal": "Terminal", "files": "Files", "info": "Info", "keys": "Keys", "setup": "Setup", # About "about": "ⓘ", "about_title": "ServerManager", "about_desc": ( "Desktop application for managing remote servers.\n" "SSH terminal, SFTP file transfer, key management,\n" "encrypted credentials, and Claude Code integration." ), "about_features_title": "⚡ Features", "about_features": ( "• SSH terminal with auto-sudo\n" "• SFTP file transfer with progress\n" "• SSH key management\n" "• TOTP / 2FA (Google Authenticator)\n" "• Encrypted credentials (Fernet)\n" "• Automatic backups\n" "• Claude Code integration" ), "about_howto_title": "🚀 Quick Start", "about_howto": ( "1. Click \"+ Add\" to add a server\n" "2. Select server → Terminal / Files\n" "3. Setup tab → Claude Code integration" ), "version": "Version", "author": "Author", "close": "Close", # Language "language": "Language", # Delete confirmation "delete_server": "Delete Server", "delete_confirm": "Remove '{alias}'?", # Server dialog "add_server": "Add Server", "edit_server": "Edit Server", "alias": "Alias", "ip": "IP / Hostname", "type": "Type", "port": "Port", "username": "Username", "password": "Password", "notes": "Notes", "save": "Save", "cancel": "Cancel", "show": "Show", "hide": "Hide", "alias_required": "Alias is required", "alias_exists": "Alias '{alias}' already exists", "ip_required": "IP is required", "port_must_be_number": "Port must be a number", "error_prefix": "Error: {msg}", "placeholder_alias": "my-server", "placeholder_ip": "1.2.3.4", "placeholder_port": "22", "placeholder_user": "root", "placeholder_password": "password", "placeholder_notes": "optional description", # Terminal "sudo": "sudo", "enter_command": "Enter command...", "run": "Run", "clear": "Clear", "no_server_selected": "[!] No server selected", "server_not_found": "[!] Server '{alias}' not found", "term_connecting": "Connecting to {alias}...", "term_connected": "Connected to {alias}", "term_disconnected": "Disconnected", "term_reconnecting": "Reconnecting ({n}/{max})...", "term_connect_failed": "Connection failed: {error}", "term_reconnect_fail": "Disconnected (reconnect failed)", # Files "upload": "Upload", "download": "Download", "local": "Local:", "remote": "Remote:", "browse": "Browse", "both_paths_required": "[!] Both paths required", "file_not_found": "[!] File not found: {path}", "upload_ok": "OK: {local} -> {alias}:{remote}", "download_ok": "OK: {alias}:{remote} -> {local}", "placeholder_local_file": "/path/to/local/file", "placeholder_remote_file": "/remote/path/file", "placeholder_save_path": "/path/to/save", # Info "no_server_selected_info": "No server selected", "info_alias": "Alias:", "info_ip": "IP:", "info_port": "Port:", "info_user": "User:", "info_type": "Type:", "info_notes": "Notes:", "info_status": "Status:", "edit_server_btn": "Edit Server", # Keys "ssh_key": "SSH Key", "key_path": "Path: {path}", "generate_key": "Generate Key", "key_exists": "Key exists", "no_key_found": "No key found. Click 'Generate Key' to create one.", "install_on_server": "Install on Server", "installing": "Installing...", "copy_public_key": "Copy Public Key", "key_copied": "Public key copied to clipboard", "no_public_key": "[!] No public key to copy", # Setup "claude_integration": "Claude Code Integration", "claude_desc": ( "Setup everything so Claude Code can manage your servers via /ssh skill.\n" "Both GUI and Claude Code share the same servers.json — add a server here,\n" "Claude sees it immediately." ), "status": "Status", "status_shared_dir": "Shared config dir (~/.server-connections)", "status_servers_json": "servers.json", "status_ssh_script": "ssh.py (CLI tool)", "status_encryption": "Encryption module", "status_skill": "/ssh skill for Claude Code", "status_ssh_key": "SSH key (ed25519)", "install_everything": "Install Everything", "installing_all": "Installing...", "install_ssh_py": "ssh.py", "install_skill": "/ssh skill", "install_ssh_key": "SSH key", "refresh": "Refresh", "configuration": "Configuration", "config_label": "Config:", "change_path": "Change Path", "backup_now": "Backup Now", "select_backup": "Select backup...", "no_backups": "No backups", "restore": "Restore", "install_done": "Done! Claude Code can now use /ssh to manage your servers.", "config_changed": "Config path changed: {path}", "backup_created": "Backup created: {name}", "backup_failed": "Backup failed: {e}", "no_backup_selected": "No backup selected.", "restore_backup_title": "Restore Backup", "restore_confirm": "Restore from '{name}'?\nCurrent data will be overwritten.", "restored": "Restored from: {name}", "restore_failed": "Restore failed: {e}", "export_config": "Export Config", "import_config": "Import Config", "export_backup": "Export Backup", "import_backup": "Import Backup", "export_config_title": "Export Configuration", "export_config_ok": "Config exported to: {path}", "export_config_failed": "Export failed: {e}", "import_config_title": "Import Configuration", "import_config_confirm": "Import will replace all current servers.\nContinue?", "import_config_ok": "Config imported from: {path}", "import_config_failed": "Import failed: {e}", "export_backup_title": "Export Backup", "export_backup_ok": "Backup exported to: {path}", "export_backup_failed": "Backup export failed: {e}", "import_backup_title": "Import Backup", "import_backup_ok": "Backup imported: {name}", "import_backup_failed": "Backup import failed: {e}", "select_servers_json": "Select servers.json", # TOTP / 2FA "totp": "2FA", "totp_title": "Two-Factor Authentication (TOTP)", "totp_desc": ( "Google Authenticator compatible 2FA codes.\n" "Add a TOTP secret to any server — the code refreshes every 30 seconds.\n" "Click the code to copy it to clipboard." ), "totp_copy": "Copy Code", "totp_secret_label": "TOTP Secret (Base32)", "totp_secret_placeholder": "JBSWY3DPEHPK3PXP...", "totp_save_secret": "Save", "totp_remove_secret": "Remove", "totp_generate_secret": "Generate Random Secret", "totp_no_secret": "No TOTP secret configured", "totp_remaining": "{sec}s remaining", "totp_copied": "Code copied to clipboard", "totp_no_code": "No code to copy", "totp_secret_empty": "Secret cannot be empty", "totp_secret_invalid": "Invalid TOTP secret (must be Base32)", "totp_secret_saved": "TOTP secret saved", "totp_secret_removed": "TOTP secret removed", "totp_secret_generated": "Random secret generated (click Save to store)", "totp_secret_dialog": "TOTP Secret", "placeholder_totp_secret": "Base32 secret (optional)", "port_out_of_range": "Port must be 1-65535", "database": "Database", "db_index": "DB Index", "api_token": "API Token", "placeholder_api_token": "Bearer token or API key", "use_ssl": "Use SSL / HTTPS", "db_index_must_be_number": "DB index must be a number", # Monitoring "monitoring": "Monitoring", "check_interval": "Check interval", "skip_check": "Skip status checks", "skip_check_desc": "Don't check this server's availability", "interval_30s": "30s", "interval_60s": "60s", "interval_120s": "2min", "interval_300s": "5min", "status_disabled": "disabled", # Network interface "network_interface": "Network Interface", "auto_default": "Auto (default)", # File browser "file_browser": "File Browser", "local_files": "Local", "remote_files": "Remote", "connect_to_browse": "Select a server to browse files", "connecting_sftp": "Connecting...", "connected_sftp": "Connected to {alias}", "disconnected_sftp": "Disconnected", "sftp_error": "SFTP error: {e}", "uploading": "Uploading: {name}", "downloading": "Downloading: {name}", "transfer_done": "Transfer complete: {name}", "transfer_failed": "Transfer failed: {e}", "new_folder": "New Folder", "new_folder_name": "Folder name:", "delete_files": "Delete", "delete_files_confirm": "Delete {count} item(s)?", "rename_file": "Rename", "rename_prompt": "New name:", "permission_denied": "Permission denied: {path}", "name_col": "Name", "size_col": "Size", "date_col": "Date", "perm_col": "Perm", "parent_dir": "Parent directory", "refresh_files": "Refresh", "items_count": "{count} items", "sudo_mode": "Sudo", "try_sudo_hint": "Try enabling Sudo mode", "switching_servers": "Switching servers...", "disconnected": "Disconnected", "sftp_server_not_found": "[!] Server not found", "uploading_dir": "Uploading folder: {name}", "downloading_dir": "Downloading folder: {name}", "transfer_file_progress": "File {cur}/{total}: {name}", "drop_to_upload": "Drop to upload", "drop_to_download": "Drop to download", "recursive_delete_confirm": "Delete folder '{name}' and all contents?", "drive": "Drive", "active_sessions": "Active: {count}", # Tab names (new server types) "query": "Query", "console": "Console", "dashboards": "Dashboards", "alerts": "Alerts", "metrics": "Metrics", "targets": "Targets", "powershell": "PowerShell", "launch": "Connect", # Server dialog fields (new types) "database": "Database", "placeholder_database": "mydb", "db_index": "DB Index (0-15)", "placeholder_db_index": "0", "api_token": "API Token", "placeholder_api_token": "Token...", "use_ssl": "Use SSL/TLS", # Query tab "query_execute": "Execute (F5)", "query_clear": "Clear", "query_export_csv": "Export CSV", "query_database": "Database:", "query_editor_placeholder": "Enter SQL query...", "query_status_rows": "{rows} rows | {elapsed}s", "query_error": "Error: {error}", "query_no_results": "Query executed, no results", "query_connected": "Connected to {alias} ({db})", "query_connecting": "Connecting...", "query_disconnected": "Not connected", "query_exported": "Exported to {path}", # Redis tab "redis_execute": "Execute", "redis_db": "DB:", "redis_keys_count": "Keys: {count}", "redis_memory": "Mem: {mem}", "redis_prompt": "redis>", "redis_connected": "Connected to {alias}", "redis_connecting": "Connecting...", "redis_disconnected": "Not connected", "redis_error": "Error: {error}", # Grafana tab "grafana_dashboards": "Dashboards", "grafana_alerts": "Alerts", "grafana_uid": "UID", "grafana_title": "Title", "grafana_folder": "Folder", "grafana_state": "State", "grafana_name": "Name", "grafana_severity": "Severity", "grafana_connected": "Connected to {alias}", "grafana_no_dashboards": "No dashboards found", "grafana_no_alerts": "No alerts", # Prometheus tab "prom_query": "PromQL Query", "prom_execute": "Execute", "prom_targets": "Targets", "prom_alerts": "Alerts", "prom_job": "Job", "prom_instance": "Instance", "prom_health": "Health", "prom_last_scrape": "Last Scrape", "prom_connected": "Connected to {alias}", "prom_no_targets": "No targets", "prom_no_alerts": "No alerts", "prom_placeholder": "up", # PowerShell tab "ps_execute": "Execute", "ps_mode_ps": "PowerShell", "ps_mode_cmd": "CMD", "ps_placeholder_ps": "Get-Process...", "ps_placeholder_cmd": "dir...", "ps_history_empty": "No command history", "ps_disconnected": "Not connected", "ps_connecting": "Connecting...", "ps_connected": "Connected to {alias}", "ps_connect_failed": "Connection failed: {error}", "ps_not_connected": "Not connected to server", "ps_running": "Running...", "ps_done": "Done", "ps_exec_error": "Error: {error}", # Launch tab "launch_connect": "Connect", "launch_rdp_info": "Remote Desktop (RDP) to {alias}", "launch_vnc_info": "VNC connection to {alias}", "launch_started": "Client launched", "launch_starting": "Launching...", "launch_error": "Launch failed: {error}", "launch_no_server": "Select a server to connect", # Info tab type-specific "info_database": "Database:", "info_ssl": "SSL:", "info_db_index": "DB Index:", } _RU = { # Sidebar "servers": "Серверы", "search": "Поиск...", "add": "+ Добавить", "edit": "Изменить", "delete": "Удалить", # Tabs "terminal": "Терминал", "files": "Файлы", "info": "Инфо", "keys": "Ключи", "setup": "Настройка", # About "about": "ⓘ", "about_title": "ServerManager", "about_desc": ( "Настольное приложение для управления удалёнными серверами.\n" "SSH-терминал, SFTP-передача файлов, управление ключами,\n" "шифрование паролей и интеграция с Claude Code." ), "about_features_title": "⚡ Возможности", "about_features": ( "• SSH-терминал с авто-sudo\n" "• SFTP-передача файлов с прогрессом\n" "• Управление SSH-ключами\n" "• TOTP / 2FA (Google Authenticator)\n" "• Шифрование паролей (Fernet)\n" "• Автоматические бэкапы\n" "• Интеграция с Claude Code" ), "about_howto_title": "🚀 Быстрый старт", "about_howto": ( "1. Нажмите \"+ Добавить\" для добавления сервера\n" "2. Выберите сервер → Терминал / Файлы\n" "3. Вкладка Настройка → интеграция Claude Code" ), "version": "Версия", "author": "Автор", "close": "Закрыть", # Language "language": "Язык", # Delete confirmation "delete_server": "Удалить сервер", "delete_confirm": "Удалить '{alias}'?", # Server dialog "add_server": "Добавить сервер", "edit_server": "Изменить сервер", "alias": "Алиас", "ip": "IP / Хост", "type": "Тип", "port": "Порт", "username": "Пользователь", "password": "Пароль", "notes": "Заметки", "save": "Сохранить", "cancel": "Отмена", "show": "Показать", "hide": "Скрыть", "alias_required": "Алиас обязателен", "alias_exists": "Алиас '{alias}' уже существует", "ip_required": "IP обязателен", "port_must_be_number": "Порт должен быть числом", "error_prefix": "Ошибка: {msg}", "placeholder_alias": "мой-сервер", "placeholder_ip": "1.2.3.4", "placeholder_port": "22", "placeholder_user": "root", "placeholder_password": "пароль", "placeholder_notes": "описание (необязательно)", # Terminal "sudo": "sudo", "enter_command": "Введите команду...", "run": "Выполнить", "clear": "Очистить", "no_server_selected": "[!] Сервер не выбран", "server_not_found": "[!] Сервер '{alias}' не найден", "term_connecting": "Подключение к {alias}...", "term_connected": "Подключено к {alias}", "term_disconnected": "Отключено", "term_reconnecting": "Переподключение ({n}/{max})...", "term_connect_failed": "Ошибка подключения: {error}", "term_reconnect_fail": "Отключено (не удалось переподключиться)", # Files "upload": "Загрузить", "download": "Скачать", "local": "Локальный:", "remote": "Удалённый:", "browse": "Обзор", "both_paths_required": "[!] Оба пути обязательны", "file_not_found": "[!] Файл не найден: {path}", "upload_ok": "OK: {local} -> {alias}:{remote}", "download_ok": "OK: {alias}:{remote} -> {local}", "placeholder_local_file": "/путь/к/локальному/файлу", "placeholder_remote_file": "/удалённый/путь/файл", "placeholder_save_path": "/путь/для/сохранения", # Info "no_server_selected_info": "Сервер не выбран", "info_alias": "Алиас:", "info_ip": "IP:", "info_port": "Порт:", "info_user": "Пользователь:", "info_type": "Тип:", "info_notes": "Заметки:", "info_status": "Статус:", "edit_server_btn": "Изменить сервер", # Keys "ssh_key": "SSH-ключ", "key_path": "Путь: {path}", "generate_key": "Создать ключ", "key_exists": "Ключ существует", "no_key_found": "Ключ не найден. Нажмите 'Создать ключ'.", "install_on_server": "Установить на сервер", "installing": "Установка...", "copy_public_key": "Копировать ключ", "key_copied": "Публичный ключ скопирован", "no_public_key": "[!] Нет публичного ключа", # Setup "claude_integration": "Интеграция с Claude Code", "claude_desc": ( "Настройте всё, чтобы Claude Code мог управлять серверами через скилл /ssh.\n" "GUI и Claude Code используют один servers.json — добавьте сервер здесь,\n" "Claude увидит его сразу." ), "status": "Статус", "status_shared_dir": "Общий каталог (~/.server-connections)", "status_servers_json": "servers.json", "status_ssh_script": "ssh.py (CLI-утилита)", "status_encryption": "Модуль шифрования", "status_skill": "Скилл /ssh для Claude Code", "status_ssh_key": "SSH-ключ (ed25519)", "install_everything": "Установить всё", "installing_all": "Установка...", "install_ssh_py": "ssh.py", "install_skill": "Скилл /ssh", "install_ssh_key": "SSH-ключ", "refresh": "Обновить", "configuration": "Конфигурация", "config_label": "Конфиг:", "change_path": "Изменить путь", "backup_now": "Бэкап сейчас", "select_backup": "Выберите бэкап...", "no_backups": "Нет бэкапов", "restore": "Восстановить", "install_done": "Готово! Claude Code теперь может использовать /ssh для управления серверами.", "config_changed": "Путь конфига изменён: {path}", "backup_created": "Бэкап создан: {name}", "backup_failed": "Ошибка бэкапа: {e}", "no_backup_selected": "Бэкап не выбран.", "restore_backup_title": "Восстановление бэкапа", "restore_confirm": "Восстановить из '{name}'?\nТекущие данные будут перезаписаны.", "restored": "Восстановлено из: {name}", "restore_failed": "Ошибка восстановления: {e}", "export_config": "Экспорт конфига", "import_config": "Импорт конфига", "export_backup": "Экспорт бэкапа", "import_backup": "Импорт бэкапа", "export_config_title": "Экспорт конфигурации", "export_config_ok": "Конфиг экспортирован в: {path}", "export_config_failed": "Ошибка экспорта: {e}", "import_config_title": "Импорт конфигурации", "import_config_confirm": "Импорт заменит все текущие серверы.\nПродолжить?", "import_config_ok": "Конфиг импортирован из: {path}", "import_config_failed": "Ошибка импорта: {e}", "export_backup_title": "Экспорт бэкапа", "export_backup_ok": "Бэкап экспортирован в: {path}", "export_backup_failed": "Ошибка экспорта бэкапа: {e}", "import_backup_title": "Импорт бэкапа", "import_backup_ok": "Бэкап импортирован: {name}", "import_backup_failed": "Ошибка импорта бэкапа: {e}", "select_servers_json": "Выберите servers.json", # TOTP / 2FA "totp": "2FA", "totp_title": "Двухфакторная аутентификация (TOTP)", "totp_desc": ( "Коды 2FA, совместимые с Google Authenticator.\n" "Добавьте TOTP-секрет к серверу — код обновляется каждые 30 секунд.\n" "Нажмите на код, чтобы скопировать в буфер обмена." ), "totp_copy": "Копировать код", "totp_secret_label": "TOTP-секрет (Base32)", "totp_secret_placeholder": "JBSWY3DPEHPK3PXP...", "totp_save_secret": "Сохранить", "totp_remove_secret": "Удалить", "totp_generate_secret": "Сгенерировать секрет", "totp_no_secret": "TOTP-секрет не настроен", "totp_remaining": "Осталось {sec}с", "totp_copied": "Код скопирован в буфер обмена", "totp_no_code": "Нет кода для копирования", "totp_secret_empty": "Секрет не может быть пустым", "totp_secret_invalid": "Недопустимый TOTP-секрет (должен быть Base32)", "totp_secret_saved": "TOTP-секрет сохранён", "totp_secret_removed": "TOTP-секрет удалён", "totp_secret_generated": "Случайный секрет создан (нажмите Сохранить)", "totp_secret_dialog": "TOTP-секрет", "placeholder_totp_secret": "Base32 секрет (необязательно)", "port_out_of_range": "Порт должен быть от 1 до 65535", "database": "База данных", "db_index": "Индекс БД", "api_token": "API-токен", "placeholder_api_token": "Bearer-токен или API-ключ", "use_ssl": "Использовать SSL / HTTPS", "db_index_must_be_number": "Индекс БД должен быть числом", # Monitoring "monitoring": "Мониторинг", "check_interval": "Интервал проверки", "skip_check": "Не проверять доступность", "skip_check_desc": "Исключить сервер из автопроверки", "interval_30s": "30с", "interval_60s": "60с", "interval_120s": "2мин", "interval_300s": "5мин", "status_disabled": "отключено", # Network interface "network_interface": "Сетевой интерфейс", "auto_default": "Авто (по умолчанию)", # File browser "file_browser": "Файл-менеджер", "local_files": "Локальные", "remote_files": "Удалённые", "connect_to_browse": "Выберите сервер для просмотра файлов", "connecting_sftp": "Подключение...", "connected_sftp": "Подключено к {alias}", "disconnected_sftp": "Отключено", "sftp_error": "Ошибка SFTP: {e}", "uploading": "Загрузка: {name}", "downloading": "Скачивание: {name}", "transfer_done": "Передача завершена: {name}", "transfer_failed": "Ошибка передачи: {e}", "new_folder": "Новая папка", "new_folder_name": "Имя папки:", "delete_files": "Удалить", "delete_files_confirm": "Удалить {count} элемент(ов)?", "rename_file": "Переименовать", "rename_prompt": "Новое имя:", "permission_denied": "Нет доступа: {path}", "name_col": "Имя", "size_col": "Размер", "date_col": "Дата", "perm_col": "Права", "parent_dir": "Родительская папка", "refresh_files": "Обновить", "items_count": "{count} элементов", "sudo_mode": "Sudo", "try_sudo_hint": "Попробуйте включить Sudo", "switching_servers": "Переключение серверов...", "disconnected": "Отключено", "sftp_server_not_found": "[!] Сервер не найден", "uploading_dir": "Загрузка папки: {name}", "downloading_dir": "Скачивание папки: {name}", "transfer_file_progress": "Файл {cur}/{total}: {name}", "drop_to_upload": "Отпустите для загрузки", "drop_to_download": "Отпустите для скачивания", "recursive_delete_confirm": "Удалить папку '{name}' со всем содержимым?", "drive": "Диск", "active_sessions": "Активных: {count}", # Tab names (new server types) "query": "Запросы", "console": "Консоль", "dashboards": "Дашборды", "alerts": "Оповещения", "metrics": "Метрики", "targets": "Цели", "powershell": "PowerShell", "launch": "Подключение", # Server dialog fields (new types) "database": "База данных", "placeholder_database": "mydb", "db_index": "Индекс БД (0-15)", "placeholder_db_index": "0", "api_token": "API-токен", "placeholder_api_token": "Токен...", "use_ssl": "Использовать SSL/TLS", # Query tab "query_execute": "Выполнить (F5)", "query_clear": "Очистить", "query_export_csv": "Экспорт CSV", "query_database": "База данных:", "query_editor_placeholder": "Введите SQL запрос...", "query_status_rows": "{rows} строк | {elapsed}с", "query_error": "Ошибка: {error}", "query_no_results": "Запрос выполнен, нет результатов", "query_connected": "Подключено к {alias} ({db})", "query_connecting": "Подключение...", "query_disconnected": "Не подключено", "query_exported": "Экспортировано в {path}", # Redis tab "redis_execute": "Выполнить", "redis_db": "БД:", "redis_keys_count": "Ключей: {count}", "redis_memory": "Память: {mem}", "redis_prompt": "redis>", "redis_connected": "Подключено к {alias}", "redis_connecting": "Подключение...", "redis_disconnected": "Не подключено", "redis_error": "Ошибка: {error}", # Grafana tab "grafana_dashboards": "Дашборды", "grafana_alerts": "Оповещения", "grafana_uid": "UID", "grafana_title": "Название", "grafana_folder": "Папка", "grafana_state": "Состояние", "grafana_name": "Имя", "grafana_severity": "Серьёзность", "grafana_connected": "Подключено к {alias}", "grafana_no_dashboards": "Дашборды не найдены", "grafana_no_alerts": "Нет оповещений", # Prometheus tab "prom_query": "PromQL запрос", "prom_execute": "Выполнить", "prom_targets": "Цели", "prom_alerts": "Оповещения", "prom_job": "Job", "prom_instance": "Инстанс", "prom_health": "Здоровье", "prom_last_scrape": "Последний опрос", "prom_connected": "Подключено к {alias}", "prom_no_targets": "Нет целей", "prom_no_alerts": "Нет оповещений", "prom_placeholder": "up", # PowerShell tab "ps_execute": "Выполнить", "ps_mode_ps": "PowerShell", "ps_mode_cmd": "CMD", "ps_placeholder_ps": "Get-Process...", "ps_placeholder_cmd": "dir...", "ps_history_empty": "Нет истории команд", "ps_disconnected": "Не подключено", "ps_connecting": "Подключение...", "ps_connected": "Подключено к {alias}", "ps_connect_failed": "Ошибка подключения: {error}", "ps_not_connected": "Нет подключения к серверу", "ps_running": "Выполнение...", "ps_done": "Готово", "ps_exec_error": "Ошибка: {error}", # Launch tab "launch_connect": "Подключиться", "launch_rdp_info": "Удалённый рабочий стол (RDP) к {alias}", "launch_vnc_info": "VNC-подключение к {alias}", "launch_started": "Клиент запущен", "launch_starting": "Запуск...", "launch_error": "Ошибка запуска: {error}", "launch_no_server": "Выберите сервер для подключения", # Info tab type-specific "info_database": "База данных:", "info_ssl": "SSL:", "info_db_index": "Индекс БД:", } _ZH = { # Sidebar "servers": "服务器", "search": "搜索...", "add": "+ 添加", "edit": "编辑", "delete": "删除", # Tabs "terminal": "终端", "files": "文件", "info": "信息", "keys": "密钥", "setup": "设置", # About "about": "ⓘ", "about_title": "ServerManager", "about_desc": ( "用于管理远程服务器的桌面应用程序。\n" "SSH终端、SFTP文件传输、密钥管理、\n" "凭据加密以及Claude Code集成。" ), "about_features_title": "⚡ 功能特点", "about_features": ( "• SSH终端(自动sudo)\n" "• SFTP文件传输(含进度条)\n" "• SSH密钥管理\n" "• TOTP / 2FA(Google Authenticator)\n" "• 凭据加密(Fernet)\n" "• 自动备份\n" "• Claude Code集成" ), "about_howto_title": "🚀 快速开始", "about_howto": ( "1. 点击\"+ 添加\"来添加服务器\n" "2. 选择服务器 → 终端 / 文件\n" "3. 设置标签 → Claude Code集成" ), "version": "版本", "author": "作者", "close": "关闭", # Language "language": "语言", # Delete confirmation "delete_server": "删除服务器", "delete_confirm": "删除 '{alias}'?", # Server dialog "add_server": "添加服务器", "edit_server": "编辑服务器", "alias": "别名", "ip": "IP / 主机名", "type": "类型", "port": "端口", "username": "用户名", "password": "密码", "notes": "备注", "save": "保存", "cancel": "取消", "show": "显示", "hide": "隐藏", "alias_required": "别名不能为空", "alias_exists": "别名 '{alias}' 已存在", "ip_required": "IP不能为空", "port_must_be_number": "端口必须是数字", "error_prefix": "错误:{msg}", "placeholder_alias": "我的服务器", "placeholder_ip": "1.2.3.4", "placeholder_port": "22", "placeholder_user": "root", "placeholder_password": "密码", "placeholder_notes": "可选描述", # Terminal "sudo": "sudo", "enter_command": "输入命令...", "run": "执行", "clear": "清除", "no_server_selected": "[!] 未选择服务器", "server_not_found": "[!] 未找到服务器 '{alias}'", "term_connecting": "正在连接 {alias}...", "term_connected": "已连接到 {alias}", "term_disconnected": "已断开", "term_reconnecting": "重新连接中 ({n}/{max})...", "term_connect_failed": "连接失败:{error}", "term_reconnect_fail": "已断开(重连失败)", # Files "upload": "上传", "download": "下载", "local": "本地:", "remote": "远程:", "browse": "浏览", "both_paths_required": "[!] 两个路径都必须填写", "file_not_found": "[!] 文件未找到:{path}", "upload_ok": "OK: {local} -> {alias}:{remote}", "download_ok": "OK: {alias}:{remote} -> {local}", "placeholder_local_file": "/本地/文件/路径", "placeholder_remote_file": "/远程/路径/文件", "placeholder_save_path": "/保存/路径", # Info "no_server_selected_info": "未选择服务器", "info_alias": "别名:", "info_ip": "IP:", "info_port": "端口:", "info_user": "用户:", "info_type": "类型:", "info_notes": "备注:", "info_status": "状态:", "edit_server_btn": "编辑服务器", # Keys "ssh_key": "SSH密钥", "key_path": "路径:{path}", "generate_key": "生成密钥", "key_exists": "密钥已存在", "no_key_found": "未找到密钥。点击'生成密钥'来创建。", "install_on_server": "安装到服务器", "installing": "安装中...", "copy_public_key": "复制公钥", "key_copied": "公钥已复制到剪贴板", "no_public_key": "[!] 没有公钥可复制", # Setup "claude_integration": "Claude Code集成", "claude_desc": ( "设置一切以便Claude Code通过/ssh技能管理您的服务器。\n" "GUI和Claude Code共享同一个servers.json — 在此添加服务器,\n" "Claude会立即看到。" ), "status": "状态", "status_shared_dir": "共享配置目录 (~/.server-connections)", "status_servers_json": "servers.json", "status_ssh_script": "ssh.py(CLI工具)", "status_encryption": "加密模块", "status_skill": "Claude Code的/ssh技能", "status_ssh_key": "SSH密钥(ed25519)", "install_everything": "全部安装", "installing_all": "安装中...", "install_ssh_py": "ssh.py", "install_skill": "/ssh技能", "install_ssh_key": "SSH密钥", "refresh": "刷新", "configuration": "配置", "config_label": "配置:", "change_path": "更改路径", "backup_now": "立即备份", "select_backup": "选择备份...", "no_backups": "无备份", "restore": "恢复", "install_done": "完成!Claude Code现在可以使用/ssh来管理您的服务器。", "config_changed": "配置路径已更改:{path}", "backup_created": "备份已创建:{name}", "backup_failed": "备份失败:{e}", "no_backup_selected": "未选择备份。", "restore_backup_title": "恢复备份", "restore_confirm": "从 '{name}' 恢复?\n当前数据将被覆盖。", "restored": "已从 {name} 恢复", "restore_failed": "恢复失败:{e}", "export_config": "导出配置", "import_config": "导入配置", "export_backup": "导出备份", "import_backup": "导入备份", "export_config_title": "导出配置", "export_config_ok": "配置已导出到:{path}", "export_config_failed": "导出失败:{e}", "import_config_title": "导入配置", "import_config_confirm": "导入将替换所有当前服务器。\n是否继续?", "import_config_ok": "配置已从 {path} 导入", "import_config_failed": "导入失败:{e}", "export_backup_title": "导出备份", "export_backup_ok": "备份已导出到:{path}", "export_backup_failed": "备份导出失败:{e}", "import_backup_title": "导入备份", "import_backup_ok": "备份已导入:{name}", "import_backup_failed": "备份导入失败:{e}", "select_servers_json": "选择servers.json", # TOTP / 2FA "totp": "2FA", "totp_title": "双因素认证(TOTP)", "totp_desc": ( "兼容Google Authenticator的2FA验证码。\n" "为服务器添加TOTP密钥 — 验证码每30秒自动刷新。\n" "点击验证码即可复制到剪贴板。" ), "totp_copy": "复制验证码", "totp_secret_label": "TOTP密钥(Base32)", "totp_secret_placeholder": "JBSWY3DPEHPK3PXP...", "totp_save_secret": "保存", "totp_remove_secret": "删除", "totp_generate_secret": "生成随机密钥", "totp_no_secret": "未配置TOTP密钥", "totp_remaining": "剩余 {sec}秒", "totp_copied": "验证码已复制到剪贴板", "totp_no_code": "没有可复制的验证码", "totp_secret_empty": "密钥不能为空", "totp_secret_invalid": "无效的TOTP密钥(必须是Base32格式)", "totp_secret_saved": "TOTP密钥已保存", "totp_secret_removed": "TOTP密钥已删除", "totp_secret_generated": "已生成随机密钥(点击保存以存储)", "totp_secret_dialog": "TOTP密钥", "placeholder_totp_secret": "Base32密钥(可选)", "port_out_of_range": "端口必须在1-65535之间", "database": "数据库", "db_index": "数据库索引", "api_token": "API令牌", "placeholder_api_token": "Bearer令牌或API密钥", "use_ssl": "使用 SSL / HTTPS", "db_index_must_be_number": "数据库索引必须是数字", # Monitoring "monitoring": "监控", "check_interval": "检查间隔", "skip_check": "跳过状态检查", "skip_check_desc": "不检查此服务器的可用性", "interval_30s": "30秒", "interval_60s": "60秒", "interval_120s": "2分钟", "interval_300s": "5分钟", "status_disabled": "已禁用", # Network interface "network_interface": "网络接口", "auto_default": "自动(默认)", # File browser "file_browser": "文件管理器", "local_files": "本地", "remote_files": "远程", "connect_to_browse": "选择服务器以浏览文件", "connecting_sftp": "连接中...", "connected_sftp": "已连接到 {alias}", "disconnected_sftp": "已断开", "sftp_error": "SFTP错误:{e}", "uploading": "上传中:{name}", "downloading": "下载中:{name}", "transfer_done": "传输完成:{name}", "transfer_failed": "传输失败:{e}", "new_folder": "新建文件夹", "new_folder_name": "文件夹名称:", "delete_files": "删除", "delete_files_confirm": "删除 {count} 个项目?", "rename_file": "重命名", "rename_prompt": "新名称:", "permission_denied": "权限被拒绝:{path}", "name_col": "名称", "size_col": "大小", "date_col": "日期", "perm_col": "权限", "parent_dir": "上级目录", "refresh_files": "刷新", "items_count": "{count} 个项目", "sudo_mode": "Sudo", "try_sudo_hint": "尝试启用Sudo模式", "switching_servers": "切换服务器...", "disconnected": "已断开", "sftp_server_not_found": "[!] 未找到服务器", "uploading_dir": "上传文件夹: {name}", "downloading_dir": "下载文件夹: {name}", "transfer_file_progress": "文件 {cur}/{total}: {name}", "drop_to_upload": "释放以上传", "drop_to_download": "释放以下载", "recursive_delete_confirm": "删除文件夹 '{name}' 及所有内容?", "drive": "驱动器", "active_sessions": "活跃: {count}", # Tab names (new server types) "query": "查询", "console": "控制台", "dashboards": "仪表盘", "alerts": "告警", "metrics": "指标", "targets": "目标", "powershell": "PowerShell", "launch": "连接", # Server dialog fields (new types) "database": "数据库", "placeholder_database": "mydb", "db_index": "数据库索引 (0-15)", "placeholder_db_index": "0", "api_token": "API令牌", "placeholder_api_token": "令牌...", "use_ssl": "使用SSL/TLS", # Query tab "query_execute": "执行 (F5)", "query_clear": "清除", "query_export_csv": "导出CSV", "query_database": "数据库:", "query_editor_placeholder": "输入SQL查询...", "query_status_rows": "{rows} 行 | {elapsed}秒", "query_error": "错误: {error}", "query_no_results": "查询已执行,无结果", "query_connected": "已连接到 {alias} ({db})", "query_connecting": "连接中...", "query_disconnected": "未连接", "query_exported": "已导出到 {path}", # Redis tab "redis_execute": "执行", "redis_db": "数据库:", "redis_keys_count": "键数: {count}", "redis_memory": "内存: {mem}", "redis_prompt": "redis>", "redis_connected": "已连接到 {alias}", "redis_connecting": "连接中...", "redis_disconnected": "未连接", "redis_error": "错误: {error}", # Grafana tab "grafana_dashboards": "仪表盘", "grafana_alerts": "告警", "grafana_uid": "UID", "grafana_title": "标题", "grafana_folder": "文件夹", "grafana_state": "状态", "grafana_name": "名称", "grafana_severity": "严重程度", "grafana_connected": "已连接到 {alias}", "grafana_no_dashboards": "未找到仪表盘", "grafana_no_alerts": "无告警", # Prometheus tab "prom_query": "PromQL查询", "prom_execute": "执行", "prom_targets": "目标", "prom_alerts": "告警", "prom_job": "任务", "prom_instance": "实例", "prom_health": "健康", "prom_last_scrape": "最后抓取", "prom_connected": "已连接到 {alias}", "prom_no_targets": "无目标", "prom_no_alerts": "无告警", "prom_placeholder": "up", # PowerShell tab "ps_execute": "执行", "ps_mode_ps": "PowerShell", "ps_mode_cmd": "CMD", "ps_placeholder_ps": "Get-Process...", "ps_placeholder_cmd": "dir...", "ps_history_empty": "无命令历史", "ps_disconnected": "未连接", "ps_connecting": "连接中...", "ps_connected": "已连接到 {alias}", "ps_connect_failed": "连接失败: {error}", "ps_not_connected": "未连接到服务器", "ps_running": "执行中...", "ps_done": "完成", "ps_exec_error": "错误: {error}", # Launch tab "launch_connect": "连接", "launch_rdp_info": "远程桌面 (RDP) 到 {alias}", "launch_vnc_info": "VNC连接到 {alias}", "launch_started": "客户端已启动", "launch_starting": "启动中...", "launch_error": "启动失败: {error}", "launch_no_server": "选择服务器以连接", # Info tab type-specific "info_database": "数据库:", "info_ssl": "SSL:", "info_db_index": "数据库索引:", } _TRANSLATIONS = { "en": _EN, "ru": _RU, "zh": _ZH, }