1746 lines
69 KiB
Python
1746 lines
69 KiB
Python
"""
|
||
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 / Codex 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 and Codex 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 / Codex 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_off": "OFFLINE",
|
||
"ctx_disconnect": "Disconnect",
|
||
"term_click_to_connect": "Double-click to connect to {alias}",
|
||
"sftp_click_to_connect": "Double-click server to browse files",
|
||
"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
|
||
"agent_integration": "AI Agent Integration",
|
||
"agent_desc": (
|
||
"Setup everything so Claude Code, Codex, and Gemini can manage your servers via shared local skills.\n"
|
||
"ServerManager, Claude Code, Codex, and Gemini share the same servers.json — add a server here,\n"
|
||
"all agents see it immediately."
|
||
),
|
||
"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_claude_skill": "/ssh skill for Claude Code",
|
||
"status_codex_skill": "ServerManager skill for Codex",
|
||
"status_codex_wrapper": "Codex wrapper (codex-ssh)",
|
||
"status_gemini_skill": "ServerManager skill for Gemini",
|
||
"status_gemini_wrapper": "Gemini wrapper (gemini-ssh)",
|
||
"status_ssh_key": "SSH key (ed25519)",
|
||
"install_everything": "Install Everything",
|
||
"installing_all": "Installing...",
|
||
"install_ssh_py": "ssh.py",
|
||
"install_skill": "/ssh skill",
|
||
"install_claude_skill": "Claude skill",
|
||
"install_codex_skill": "Codex skill",
|
||
"install_gemini_skill": "Gemini 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, Codex, and Gemini can now use ServerManager 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",
|
||
|
||
# Database tree
|
||
"tree_databases": "Databases",
|
||
"tree_refresh": "Refresh",
|
||
"tree_use_db": "Use database",
|
||
"tree_select_top": "SELECT TOP 1000",
|
||
"tree_describe": "Describe table",
|
||
"tree_copy_name": "Copy name",
|
||
"tree_select_column": "Insert column",
|
||
"tree_loading": "Loading...",
|
||
"tree_no_tables": "(no tables)",
|
||
"tree_no_columns": "(no columns)",
|
||
"tree_connected": "Connected",
|
||
# Results context menu
|
||
"res_copy_cell": "Copy Cell",
|
||
"res_copy_row": "Copy Row",
|
||
"res_copy_row_as": "Copy Row As",
|
||
"res_copy_all_as": "Copy All As",
|
||
"query_exported": "Exported to {path}",
|
||
|
||
# Redis tab
|
||
"redis_clear": "Clear",
|
||
"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}",
|
||
|
||
# S3 tab
|
||
"objects": "Objects",
|
||
"access_key": "Access Key",
|
||
"secret_key": "Secret Key",
|
||
"placeholder_secret_key": "Secret key...",
|
||
"bucket": "Bucket",
|
||
"s3_objects": "S3 Objects",
|
||
"s3_bucket": "Bucket:",
|
||
"s3_back": "Back",
|
||
"s3_refresh": "Refresh",
|
||
"s3_upload": "Upload",
|
||
"s3_download": "Download",
|
||
"s3_delete": "Delete",
|
||
"s3_col_name": "Name",
|
||
"s3_col_size": "Size",
|
||
"s3_col_modified": "Modified",
|
||
"s3_connecting": "Connecting...",
|
||
"s3_connect_failed": "Connection failed",
|
||
"s3_loading": "Loading...",
|
||
"s3_items_count": "{count} items",
|
||
"s3_uploading": "Uploading...",
|
||
"s3_upload_failed": "Upload failed",
|
||
"s3_downloading": "Downloading...",
|
||
"s3_download_ok": "Download complete",
|
||
"s3_download_failed": "Download failed",
|
||
"s3_deleting": "Deleting...",
|
||
"s3_delete_failed": "Delete failed",
|
||
"s3_drop_hint": "Drag files here to upload",
|
||
"s3_uploading_n": "Uploading {count} files...",
|
||
"s3_uploaded_n": "Uploaded {count} files",
|
||
"s3_upload_partial": "Uploaded {ok}/{total} files",
|
||
"s3_create_bucket": "Create Bucket",
|
||
"s3_bucket_name_prompt": "Bucket name:",
|
||
"s3_delete_bucket": "Delete Bucket",
|
||
"s3_delete_bucket_confirm": "Delete bucket \"{name}\"? It must be empty.",
|
||
"s3_bucket_created": "Bucket \"{name}\" created",
|
||
"s3_bucket_deleted": "Bucket \"{name}\" deleted",
|
||
"s3_new_folder": "New Folder",
|
||
"s3_folder_name_prompt": "Folder name:",
|
||
"s3_creating_folder": "Creating folder...",
|
||
"s3_folder_failed": "Failed to create folder",
|
||
"s3_delete_folder_confirm": "Delete folder \"{folder}\" and all its contents?",
|
||
"s3_deleted_n": "Deleted {count} objects",
|
||
"s3_download_folder_title": "Save folder to...",
|
||
"s3_downloading_n": "Downloading {count} files...",
|
||
"s3_downloaded_n": "Downloaded {count} files",
|
||
"s3_download_partial": "Downloaded {ok}/{total} files",
|
||
"s3_copy_link_48h": "Copy Link (48h)",
|
||
"s3_copy_link_permanent": "Copy Direct Link",
|
||
"s3_generating_link": "Generating link...",
|
||
"s3_link_copied": "Link copied to clipboard",
|
||
"s3_link_failed": "Failed to generate link",
|
||
|
||
# Grafana tab
|
||
"grafana_refresh": "Refresh",
|
||
"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",
|
||
"grafana_loading": "Loading...",
|
||
"grafana_loaded": "{dashboards} dashboards, {alerts} alerts, {datasources} datasources",
|
||
"grafana_no_server": "No server selected",
|
||
"grafana_open_browser": "Open Grafana",
|
||
"grafana_datasources": "Datasources",
|
||
"grafana_ds_name": "Name",
|
||
"grafana_ds_type": "Type",
|
||
"grafana_ds_default": "Default",
|
||
"grafana_dash_title": "Title",
|
||
"grafana_dash_folder": "Folder",
|
||
"grafana_alert_state": "State",
|
||
"grafana_alert_name": "Name",
|
||
"grafana_alert_severity": "Severity",
|
||
|
||
# Prometheus tab
|
||
"prom_refresh": "Refresh",
|
||
"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",
|
||
"prom_loading": "Loading...",
|
||
"prom_loaded": "{targets} targets, {alerts} alerts, {rules} rules",
|
||
"prom_no_server": "No server selected",
|
||
"prom_executing": "Executing...",
|
||
"prom_results": "Results",
|
||
"prom_query_placeholder": "e.g. up, node_cpu_seconds_total",
|
||
"prom_metrics_browser": "Metrics",
|
||
"prom_filter_metrics": "Filter metrics...",
|
||
"prom_rules": "Rules",
|
||
"prom_rule_type": "Type",
|
||
"prom_rule_name": "Name",
|
||
"prom_rule_group": "Group",
|
||
"prom_rule_health": "Health",
|
||
"prom_target_job": "Job",
|
||
"prom_target_instance": "Instance",
|
||
"prom_target_health": "Health",
|
||
"prom_target_scrape": "Last Scrape",
|
||
|
||
# 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",
|
||
|
||
# Embedded RDP
|
||
"rdp_settings": "RDP Settings",
|
||
"rdp_quality": "Quality",
|
||
"rdp_quality_auto": "Auto Detect",
|
||
"rdp_quality_lan": "LAN (Best)",
|
||
"rdp_quality_broadband": "Broadband",
|
||
"rdp_quality_modem": "Low Bandwidth",
|
||
"rdp_resolution": "Resolution",
|
||
"rdp_resolution_auto": "Auto (Fit Window)",
|
||
"rdp_clipboard": "Share Clipboard",
|
||
"rdp_drives": "Share Drives (Files)",
|
||
"rdp_printers": "Share Printers",
|
||
"rdp_connecting": "Connecting to {alias}...",
|
||
"rdp_embedding": "Embedding RDP window...",
|
||
"rdp_connected": "Connected to {alias}",
|
||
"rdp_reconnected": "Reconnected to {alias}",
|
||
"rdp_disconnected": "Disconnected",
|
||
"rdp_disconnect": "Disconnect",
|
||
"rdp_fullscreen": "Fullscreen",
|
||
"rdp_exit_fullscreen": "Exit Fullscreen",
|
||
"rdp_error_embed": "Failed to embed: {error}",
|
||
"rdp_error_timeout": "Timed out waiting for RDP window",
|
||
|
||
# Info tab type-specific
|
||
"info_database": "Database:",
|
||
"info_ssl": "SSL:",
|
||
"info_db_index": "DB Index:",
|
||
|
||
# Context menu
|
||
"ctx_open_terminal": "Open Terminal",
|
||
"ctx_browse_files": "Browse Files",
|
||
"ctx_install_key": "Install Key",
|
||
"ctx_open_powershell": "Open PowerShell",
|
||
"ctx_open_query": "Open Query Editor",
|
||
"ctx_open_console": "Open Console",
|
||
"ctx_connect": "Connect",
|
||
"ctx_open_browser": "Open in Browser",
|
||
"ctx_check_status": "Check Status",
|
||
"ctx_copy_alias": "Copy Alias",
|
||
"ctx_alias_copied": "Alias copied",
|
||
|
||
# Updates
|
||
"update_available": "ServerManager v{version} is available",
|
||
"update_available_title": "Update Available",
|
||
"update_check": "Check for Updates",
|
||
"update_checking": "Checking for updates...",
|
||
"update_download_install": "Download & Install",
|
||
"update_downloading": "Downloading...",
|
||
"update_downloaded": "Downloaded",
|
||
"update_install": "Update",
|
||
"update_restart": "Restart to Update",
|
||
"update_skip": "Skip",
|
||
"update_later": "Later",
|
||
"update_error": "Update failed",
|
||
"update_changelog": "What's New",
|
||
"update_no_changelog": "No changelog available.",
|
||
"update_current": "Current",
|
||
"update_ready": "Ready to install",
|
||
"update_mode": "Update Mode",
|
||
"update_mode_notify": "Notify Only",
|
||
"update_mode_download": "Auto-Download",
|
||
"update_mode_auto": "Full Auto",
|
||
"update_no_updates": "You're up to date!",
|
||
"update_not_frozen": "Updates only work in packaged (exe) mode",
|
||
# Groups
|
||
"group": "Group",
|
||
"no_group": "No group",
|
||
"ungrouped": "Ungrouped",
|
||
"add_group": "Add Group",
|
||
"edit_group": "Edit Group",
|
||
"rename_group": "Rename",
|
||
"delete_group": "Delete Group",
|
||
"delete_group_confirm": "Delete group '{name}'? Servers will become ungrouped.",
|
||
"group_name": "Group Name",
|
||
"group_color": "Color",
|
||
"group_name_required": "Group name is required",
|
||
"move_to_group": "Move to Group",
|
||
"move_up": "Move Up",
|
||
"move_down": "Move Down",
|
||
"change_color": "Change Color",
|
||
}
|
||
|
||
_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 / Codex."
|
||
),
|
||
"about_features_title": "⚡ Возможности",
|
||
"about_features": (
|
||
"• SSH-терминал с авто-sudo\n"
|
||
"• SFTP-передача файлов с прогрессом\n"
|
||
"• Управление SSH-ключами\n"
|
||
"• TOTP / 2FA (Google Authenticator)\n"
|
||
"• Шифрование паролей (Fernet)\n"
|
||
"• Автоматические бэкапы\n"
|
||
"• Интеграция с Claude Code и Codex"
|
||
),
|
||
"about_howto_title": "🚀 Быстрый старт",
|
||
"about_howto": (
|
||
"1. Нажмите \"+ Добавить\" для добавления сервера\n"
|
||
"2. Выберите сервер → Терминал / Файлы\n"
|
||
"3. Вкладка Настройка → интеграция Claude Code / Codex"
|
||
),
|
||
"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_off": "ОТКЛЮЧЕНО",
|
||
"ctx_disconnect": "Отключиться",
|
||
"term_click_to_connect": "Двойной клик для подключения к {alias}",
|
||
"sftp_click_to_connect": "Двойной клик для просмотра файлов",
|
||
"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
|
||
"agent_integration": "Интеграция AI-агентов",
|
||
"claude_integration": "Интеграция с Claude Code",
|
||
"claude_desc": (
|
||
"Настройте всё, чтобы Claude Code мог управлять серверами через скилл /ssh.\n"
|
||
"GUI и Claude Code используют один servers.json — добавьте сервер здесь,\n"
|
||
"Claude увидит его сразу."
|
||
),
|
||
"agent_desc": (
|
||
"Настройте всё, чтобы Claude Code, Codex и Gemini могли управлять серверами через локальные skills.\n"
|
||
"ServerManager, Claude Code, Codex и Gemini используют один и тот же servers.json — добавьте сервер здесь,\n"
|
||
"все агенты увидят его сразу."
|
||
),
|
||
"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_claude_skill": "Скилл /ssh для Claude Code",
|
||
"status_codex_skill": "Скилл ServerManager для Codex",
|
||
"status_codex_wrapper": "Обёртка Codex (codex-ssh)",
|
||
"status_gemini_skill": "Скилл ServerManager для Gemini",
|
||
"status_gemini_wrapper": "Обёртка Gemini (gemini-ssh)",
|
||
"status_ssh_key": "SSH-ключ (ed25519)",
|
||
"install_everything": "Установить всё",
|
||
"installing_all": "Установка...",
|
||
"install_ssh_py": "ssh.py",
|
||
"install_skill": "Скилл /ssh",
|
||
"install_claude_skill": "Скилл Claude",
|
||
"install_codex_skill": "Скилл Codex",
|
||
"install_gemini_skill": "Скилл Gemini",
|
||
"install_ssh_key": "SSH-ключ",
|
||
"refresh": "Обновить",
|
||
"configuration": "Конфигурация",
|
||
"config_label": "Конфиг:",
|
||
"change_path": "Изменить путь",
|
||
"backup_now": "Бэкап сейчас",
|
||
"select_backup": "Выберите бэкап...",
|
||
"no_backups": "Нет бэкапов",
|
||
"restore": "Восстановить",
|
||
"install_done": "Готово! Claude Code, Codex и Gemini теперь могут использовать ServerManager для управления серверами.",
|
||
"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}",
|
||
|
||
# Database tree
|
||
"tree_databases": "Базы данных",
|
||
"tree_refresh": "Обновить",
|
||
"tree_use_db": "Выбрать базу",
|
||
"tree_select_top": "SELECT TOP 1000",
|
||
"tree_describe": "Описание таблицы",
|
||
"tree_copy_name": "Копировать имя",
|
||
"tree_select_column": "Вставить колонку",
|
||
"tree_loading": "Загрузка...",
|
||
"tree_no_tables": "(нет таблиц)",
|
||
"tree_no_columns": "(нет колонок)",
|
||
"tree_connected": "Подключено",
|
||
# Results context menu
|
||
"res_copy_cell": "Копировать ячейку",
|
||
"res_copy_row": "Копировать строку",
|
||
"res_copy_row_as": "Копировать строку как",
|
||
"res_copy_all_as": "Копировать всё как",
|
||
|
||
# Redis tab
|
||
"redis_clear": "Очистить",
|
||
"redis_execute": "Выполнить",
|
||
"redis_db": "БД:",
|
||
"redis_keys_count": "Ключей: {count}",
|
||
"redis_memory": "Память: {mem}",
|
||
"redis_prompt": "redis>",
|
||
"redis_connected": "Подключено к {alias}",
|
||
"redis_connecting": "Подключение...",
|
||
"redis_disconnected": "Не подключено",
|
||
"redis_error": "Ошибка: {error}",
|
||
|
||
# S3 tab
|
||
"objects": "Объекты",
|
||
"access_key": "Access Key",
|
||
"secret_key": "Secret Key",
|
||
"placeholder_secret_key": "Секретный ключ...",
|
||
"bucket": "Бакет",
|
||
"s3_objects": "Объекты S3",
|
||
"s3_bucket": "Бакет:",
|
||
"s3_back": "Назад",
|
||
"s3_refresh": "Обновить",
|
||
"s3_upload": "Загрузить",
|
||
"s3_download": "Скачать",
|
||
"s3_delete": "Удалить",
|
||
"s3_col_name": "Имя",
|
||
"s3_col_size": "Размер",
|
||
"s3_col_modified": "Изменён",
|
||
"s3_connecting": "Подключение...",
|
||
"s3_connect_failed": "Ошибка подключения",
|
||
"s3_loading": "Загрузка...",
|
||
"s3_items_count": "{count} объектов",
|
||
"s3_uploading": "Загрузка файла...",
|
||
"s3_upload_failed": "Ошибка загрузки",
|
||
"s3_downloading": "Скачивание...",
|
||
"s3_download_ok": "Скачивание завершено",
|
||
"s3_download_failed": "Ошибка скачивания",
|
||
"s3_deleting": "Удаление...",
|
||
"s3_delete_failed": "Ошибка удаления",
|
||
"s3_drop_hint": "Перетащите файлы сюда для загрузки",
|
||
"s3_uploading_n": "Загрузка {count} файлов...",
|
||
"s3_uploaded_n": "Загружено {count} файлов",
|
||
"s3_upload_partial": "Загружено {ok}/{total} файлов",
|
||
"s3_create_bucket": "Создать бакет",
|
||
"s3_bucket_name_prompt": "Имя бакета:",
|
||
"s3_delete_bucket": "Удалить бакет",
|
||
"s3_delete_bucket_confirm": "Удалить бакет \"{name}\"? Он должен быть пустым.",
|
||
"s3_bucket_created": "Бакет \"{name}\" создан",
|
||
"s3_bucket_deleted": "Бакет \"{name}\" удалён",
|
||
"s3_new_folder": "Новая папка",
|
||
"s3_folder_name_prompt": "Имя папки:",
|
||
"s3_creating_folder": "Создание папки...",
|
||
"s3_folder_failed": "Ошибка создания папки",
|
||
"s3_delete_folder_confirm": "Удалить папку \"{folder}\" со всем содержимым?",
|
||
"s3_deleted_n": "Удалено {count} объектов",
|
||
"s3_download_folder_title": "Сохранить папку в...",
|
||
"s3_downloading_n": "Скачивание {count} файлов...",
|
||
"s3_downloaded_n": "Скачано {count} файлов",
|
||
"s3_download_partial": "Скачано {ok}/{total} файлов",
|
||
"s3_copy_link_48h": "Ссылка (48ч)",
|
||
"s3_copy_link_permanent": "Прямая ссылка",
|
||
"s3_generating_link": "Генерация ссылки...",
|
||
"s3_link_copied": "Ссылка скопирована",
|
||
"s3_link_failed": "Ошибка генерации ссылки",
|
||
|
||
# Grafana tab
|
||
"grafana_refresh": "Обновить",
|
||
"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": "Нет оповещений",
|
||
"grafana_loading": "Загрузка...",
|
||
"grafana_loaded": "{dashboards} дашб., {alerts} оповещ., {datasources} источн.",
|
||
"grafana_no_server": "Сервер не выбран",
|
||
"grafana_open_browser": "Открыть Grafana",
|
||
"grafana_datasources": "Источники данных",
|
||
"grafana_ds_name": "Имя",
|
||
"grafana_ds_type": "Тип",
|
||
"grafana_ds_default": "По умолч.",
|
||
"grafana_dash_title": "Название",
|
||
"grafana_dash_folder": "Папка",
|
||
"grafana_alert_state": "Состояние",
|
||
"grafana_alert_name": "Имя",
|
||
"grafana_alert_severity": "Серьёзность",
|
||
|
||
# Prometheus tab
|
||
"prom_refresh": "Обновить",
|
||
"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",
|
||
"prom_loading": "Загрузка...",
|
||
"prom_loaded": "{targets} целей, {alerts} оповещ., {rules} правил",
|
||
"prom_no_server": "Сервер не выбран",
|
||
"prom_executing": "Выполнение...",
|
||
"prom_results": "Результаты",
|
||
"prom_query_placeholder": "напр. up, node_cpu_seconds_total",
|
||
"prom_metrics_browser": "Метрики",
|
||
"prom_filter_metrics": "Фильтр метрик...",
|
||
"prom_rules": "Правила",
|
||
"prom_rule_type": "Тип",
|
||
"prom_rule_name": "Имя",
|
||
"prom_rule_group": "Группа",
|
||
"prom_rule_health": "Здоровье",
|
||
"prom_target_job": "Job",
|
||
"prom_target_instance": "Инстанс",
|
||
"prom_target_health": "Здоровье",
|
||
"prom_target_scrape": "Последний опрос",
|
||
|
||
# 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": "Выберите сервер для подключения",
|
||
|
||
# Embedded RDP
|
||
"rdp_settings": "Настройки RDP",
|
||
"rdp_quality": "Качество",
|
||
"rdp_quality_auto": "Авто",
|
||
"rdp_quality_lan": "LAN (лучшее)",
|
||
"rdp_quality_broadband": "Broadband",
|
||
"rdp_quality_modem": "Низкое",
|
||
"rdp_resolution": "Разрешение",
|
||
"rdp_resolution_auto": "Авто (по размеру окна)",
|
||
"rdp_clipboard": "Буфер обмена",
|
||
"rdp_drives": "Проброс дисков (файлы)",
|
||
"rdp_printers": "Принтеры",
|
||
"rdp_connecting": "Подключение к {alias}...",
|
||
"rdp_embedding": "Встраивание RDP окна...",
|
||
"rdp_connected": "Подключено к {alias}",
|
||
"rdp_reconnected": "Переподключено к {alias}",
|
||
"rdp_disconnected": "Отключено",
|
||
"rdp_disconnect": "Отключить",
|
||
"rdp_fullscreen": "Во весь экран",
|
||
"rdp_exit_fullscreen": "Выход из полного экрана",
|
||
"rdp_error_embed": "Ошибка встраивания: {error}",
|
||
"rdp_error_timeout": "Таймаут ожидания RDP окна",
|
||
|
||
# Info tab type-specific
|
||
"info_database": "База данных:",
|
||
"info_ssl": "SSL:",
|
||
"info_db_index": "Индекс БД:",
|
||
|
||
# Context menu
|
||
"ctx_open_terminal": "Открыть терминал",
|
||
"ctx_browse_files": "Обзор файлов",
|
||
"ctx_install_key": "Установить ключ",
|
||
"ctx_open_powershell": "Открыть PowerShell",
|
||
"ctx_open_query": "Открыть SQL-редактор",
|
||
"ctx_open_console": "Открыть консоль",
|
||
"ctx_connect": "Подключиться",
|
||
"ctx_open_browser": "Открыть в браузере",
|
||
"ctx_check_status": "Проверить статус",
|
||
"ctx_copy_alias": "Копировать алиас",
|
||
"ctx_alias_copied": "Алиас скопирован",
|
||
|
||
# Updates
|
||
"update_available": "Доступен ServerManager v{version}",
|
||
"update_available_title": "Доступно обновление",
|
||
"update_check": "Проверить обновления",
|
||
"update_checking": "Проверка обновлений...",
|
||
"update_download_install": "Скачать и установить",
|
||
"update_downloading": "Скачивание...",
|
||
"update_downloaded": "Скачано",
|
||
"update_install": "Обновить",
|
||
"update_restart": "Перезапустить",
|
||
"update_skip": "Пропустить",
|
||
"update_later": "Позже",
|
||
"update_error": "Ошибка обновления",
|
||
"update_changelog": "Что нового",
|
||
"update_no_changelog": "Описание изменений отсутствует.",
|
||
"update_current": "Текущая",
|
||
"update_ready": "Готово к установке",
|
||
"update_mode": "Режим обновлений",
|
||
"update_mode_notify": "Только уведомлять",
|
||
"update_mode_download": "Авто-скачивание",
|
||
"update_mode_auto": "Полный авто",
|
||
"update_no_updates": "У вас последняя версия!",
|
||
"update_not_frozen": "Обновления работают только в exe-режиме",
|
||
# Groups
|
||
"group": "Группа",
|
||
"no_group": "Без группы",
|
||
"ungrouped": "Без группы",
|
||
"add_group": "Добавить группу",
|
||
"edit_group": "Редактировать группу",
|
||
"rename_group": "Переименовать",
|
||
"delete_group": "Удалить группу",
|
||
"delete_group_confirm": "Удалить группу '{name}'? Серверы станут без группы.",
|
||
"group_name": "Название группы",
|
||
"group_color": "Цвет",
|
||
"group_name_required": "Название группы обязательно",
|
||
"move_to_group": "Переместить в группу",
|
||
"move_up": "Вверх",
|
||
"move_down": "Вниз",
|
||
"change_color": "Изменить цвет",
|
||
}
|
||
|
||
_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 / Codex集成。"
|
||
),
|
||
"about_features_title": "⚡ 功能特点",
|
||
"about_features": (
|
||
"• SSH终端(自动sudo)\n"
|
||
"• SFTP文件传输(含进度条)\n"
|
||
"• SSH密钥管理\n"
|
||
"• TOTP / 2FA(Google Authenticator)\n"
|
||
"• 凭据加密(Fernet)\n"
|
||
"• 自动备份\n"
|
||
"• Claude Code 和 Codex 集成"
|
||
),
|
||
"about_howto_title": "🚀 快速开始",
|
||
"about_howto": (
|
||
"1. 点击\"+ 添加\"来添加服务器\n"
|
||
"2. 选择服务器 → 终端 / 文件\n"
|
||
"3. 设置标签 → Claude Code / Codex 集成"
|
||
),
|
||
"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_off": "未连接",
|
||
"ctx_disconnect": "断开连接",
|
||
"term_click_to_connect": "双击连接 {alias}",
|
||
"sftp_click_to_connect": "双击服务器浏览文件",
|
||
"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
|
||
"agent_integration": "AI代理集成",
|
||
"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": "加密模块",
|
||
"agent_desc": (
|
||
"完成设置后,Claude Code、Codex 和 Gemini 都可以通过共享的本地 skills 管理您的服务器。\n"
|
||
"ServerManager、Claude Code、Codex 和 Gemini 共用同一个 servers.json — 在此添加服务器后,\n"
|
||
"所有代理都会立即看到。"
|
||
),
|
||
"status_skill": "Claude Code的/ssh技能",
|
||
"status_claude_skill": "Claude Code 的 /ssh 技能",
|
||
"status_codex_skill": "Codex 的 ServerManager 技能",
|
||
"status_codex_wrapper": "Codex 包装器(codex-ssh)",
|
||
"status_gemini_skill": "Gemini 的 ServerManager 技能",
|
||
"status_gemini_wrapper": "Gemini 包装器(gemini-ssh)",
|
||
"status_ssh_key": "SSH密钥(ed25519)",
|
||
"install_everything": "全部安装",
|
||
"installing_all": "安装中...",
|
||
"install_ssh_py": "ssh.py",
|
||
"install_skill": "/ssh技能",
|
||
"install_claude_skill": "Claude 技能",
|
||
"install_codex_skill": "Codex 技能",
|
||
"install_gemini_skill": "Gemini 技能",
|
||
"install_ssh_key": "SSH密钥",
|
||
"refresh": "刷新",
|
||
"configuration": "配置",
|
||
"config_label": "配置:",
|
||
"change_path": "更改路径",
|
||
"backup_now": "立即备份",
|
||
"select_backup": "选择备份...",
|
||
"no_backups": "无备份",
|
||
"restore": "恢复",
|
||
"install_done": "完成!Claude Code、Codex 和 Gemini 现在都可以使用 ServerManager 来管理您的服务器。",
|
||
"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}",
|
||
|
||
# Database tree
|
||
"tree_databases": "数据库",
|
||
"tree_refresh": "刷新",
|
||
"tree_use_db": "选择数据库",
|
||
"tree_select_top": "SELECT TOP 1000",
|
||
"tree_describe": "表描述",
|
||
"tree_copy_name": "复制名称",
|
||
"tree_select_column": "插入列",
|
||
"tree_loading": "加载中...",
|
||
"tree_no_tables": "(无表)",
|
||
"tree_no_columns": "(无列)",
|
||
"tree_connected": "已连接",
|
||
# Results context menu
|
||
"res_copy_cell": "复制单元格",
|
||
"res_copy_row": "复制行",
|
||
"res_copy_row_as": "复制行为",
|
||
"res_copy_all_as": "全部复制为",
|
||
|
||
# Redis tab
|
||
"redis_clear": "清除",
|
||
"redis_execute": "执行",
|
||
"redis_db": "数据库:",
|
||
"redis_keys_count": "键数: {count}",
|
||
"redis_memory": "内存: {mem}",
|
||
"redis_prompt": "redis>",
|
||
"redis_connected": "已连接到 {alias}",
|
||
"redis_connecting": "连接中...",
|
||
"redis_disconnected": "未连接",
|
||
"redis_error": "错误: {error}",
|
||
|
||
# S3 tab
|
||
"objects": "对象",
|
||
"access_key": "Access Key",
|
||
"secret_key": "Secret Key",
|
||
"placeholder_secret_key": "密钥...",
|
||
"bucket": "存储桶",
|
||
"s3_objects": "S3 对象",
|
||
"s3_bucket": "存储桶:",
|
||
"s3_back": "返回",
|
||
"s3_refresh": "刷新",
|
||
"s3_upload": "上传",
|
||
"s3_download": "下载",
|
||
"s3_delete": "删除",
|
||
"s3_col_name": "名称",
|
||
"s3_col_size": "大小",
|
||
"s3_col_modified": "修改时间",
|
||
"s3_connecting": "连接中...",
|
||
"s3_connect_failed": "连接失败",
|
||
"s3_loading": "加载中...",
|
||
"s3_items_count": "{count} 个对象",
|
||
"s3_uploading": "上传中...",
|
||
"s3_upload_failed": "上传失败",
|
||
"s3_downloading": "下载中...",
|
||
"s3_download_ok": "下载完成",
|
||
"s3_download_failed": "下载失败",
|
||
"s3_deleting": "删除中...",
|
||
"s3_delete_failed": "删除失败",
|
||
"s3_drop_hint": "拖拽文件到此处上传",
|
||
"s3_uploading_n": "正在上传 {count} 个文件...",
|
||
"s3_uploaded_n": "已上传 {count} 个文件",
|
||
"s3_upload_partial": "已上传 {ok}/{total} 个文件",
|
||
"s3_create_bucket": "创建存储桶",
|
||
"s3_bucket_name_prompt": "存储桶名称:",
|
||
"s3_delete_bucket": "删除存储桶",
|
||
"s3_delete_bucket_confirm": "删除存储桶 \"{name}\"?必须为空。",
|
||
"s3_bucket_created": "存储桶 \"{name}\" 已创建",
|
||
"s3_bucket_deleted": "存储桶 \"{name}\" 已删除",
|
||
"s3_new_folder": "新建文件夹",
|
||
"s3_folder_name_prompt": "文件夹名称:",
|
||
"s3_creating_folder": "创建文件夹中...",
|
||
"s3_folder_failed": "创建文件夹失败",
|
||
"s3_delete_folder_confirm": "删除文件夹 \"{folder}\" 及其所有内容?",
|
||
"s3_deleted_n": "已删除 {count} 个对象",
|
||
"s3_download_folder_title": "保存文件夹到...",
|
||
"s3_downloading_n": "正在下载 {count} 个文件...",
|
||
"s3_downloaded_n": "已下载 {count} 个文件",
|
||
"s3_download_partial": "已下载 {ok}/{total} 个文件",
|
||
"s3_copy_link_48h": "复制链接 (48小时)",
|
||
"s3_copy_link_permanent": "复制直接链接",
|
||
"s3_generating_link": "生成链接中...",
|
||
"s3_link_copied": "链接已复制",
|
||
"s3_link_failed": "生成链接失败",
|
||
|
||
# Grafana tab
|
||
"grafana_refresh": "刷新",
|
||
"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": "无告警",
|
||
"grafana_loading": "加载中...",
|
||
"grafana_loaded": "{dashboards}仪表盘, {alerts}告警, {datasources}数据源",
|
||
"grafana_no_server": "未选择服务器",
|
||
"grafana_open_browser": "打开Grafana",
|
||
"grafana_datasources": "数据源",
|
||
"grafana_ds_name": "名称",
|
||
"grafana_ds_type": "类型",
|
||
"grafana_ds_default": "默认",
|
||
"grafana_dash_title": "标题",
|
||
"grafana_dash_folder": "文件夹",
|
||
"grafana_alert_state": "状态",
|
||
"grafana_alert_name": "名称",
|
||
"grafana_alert_severity": "严重程度",
|
||
|
||
# Prometheus tab
|
||
"prom_refresh": "刷新",
|
||
"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",
|
||
"prom_loading": "加载中...",
|
||
"prom_loaded": "{targets}目标, {alerts}告警, {rules}规则",
|
||
"prom_no_server": "未选择服务器",
|
||
"prom_executing": "执行中...",
|
||
"prom_results": "结果",
|
||
"prom_query_placeholder": "例如 up, node_cpu_seconds_total",
|
||
"prom_metrics_browser": "指标",
|
||
"prom_filter_metrics": "过滤指标...",
|
||
"prom_rules": "规则",
|
||
"prom_rule_type": "类型",
|
||
"prom_rule_name": "名称",
|
||
"prom_rule_group": "组",
|
||
"prom_rule_health": "健康",
|
||
"prom_target_job": "任务",
|
||
"prom_target_instance": "实例",
|
||
"prom_target_health": "健康",
|
||
"prom_target_scrape": "最后抓取",
|
||
|
||
# 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": "选择服务器以连接",
|
||
|
||
# Embedded RDP
|
||
"rdp_settings": "RDP设置",
|
||
"rdp_quality": "质量",
|
||
"rdp_quality_auto": "自动检测",
|
||
"rdp_quality_lan": "局域网 (最佳)",
|
||
"rdp_quality_broadband": "宽带",
|
||
"rdp_quality_modem": "低带宽",
|
||
"rdp_resolution": "分辨率",
|
||
"rdp_resolution_auto": "自动 (适应窗口)",
|
||
"rdp_clipboard": "共享剪贴板",
|
||
"rdp_drives": "共享驱动器 (文件)",
|
||
"rdp_printers": "共享打印机",
|
||
"rdp_connecting": "正在连接 {alias}...",
|
||
"rdp_embedding": "嵌入RDP窗口...",
|
||
"rdp_connected": "已连接 {alias}",
|
||
"rdp_reconnected": "已重新连接到 {alias}",
|
||
"rdp_disconnected": "已断开",
|
||
"rdp_disconnect": "断开连接",
|
||
"rdp_fullscreen": "全屏",
|
||
"rdp_exit_fullscreen": "退出全屏",
|
||
"rdp_error_embed": "嵌入失败: {error}",
|
||
"rdp_error_timeout": "等待RDP窗口超时",
|
||
|
||
# Info tab type-specific
|
||
"info_database": "数据库:",
|
||
"info_ssl": "SSL:",
|
||
"info_db_index": "数据库索引:",
|
||
|
||
# Context menu
|
||
"ctx_open_terminal": "打开终端",
|
||
"ctx_browse_files": "浏览文件",
|
||
"ctx_install_key": "安装密钥",
|
||
"ctx_open_powershell": "打开 PowerShell",
|
||
"ctx_open_query": "打开查询编辑器",
|
||
"ctx_open_console": "打开控制台",
|
||
"ctx_connect": "连接",
|
||
"ctx_open_browser": "在浏览器中打开",
|
||
"ctx_check_status": "检查状态",
|
||
"ctx_copy_alias": "复制别名",
|
||
"ctx_alias_copied": "别名已复制",
|
||
|
||
# Updates
|
||
"update_available": "ServerManager v{version} 可用",
|
||
"update_available_title": "有可用更新",
|
||
"update_check": "检查更新",
|
||
"update_checking": "正在检查更新...",
|
||
"update_download_install": "下载并安装",
|
||
"update_downloading": "下载中...",
|
||
"update_downloaded": "已下载",
|
||
"update_install": "更新",
|
||
"update_restart": "重启更新",
|
||
"update_skip": "跳过",
|
||
"update_later": "稍后",
|
||
"update_error": "更新失败",
|
||
"update_changelog": "更新内容",
|
||
"update_no_changelog": "无更新日志。",
|
||
"update_current": "当前版本",
|
||
"update_ready": "准备安装",
|
||
"update_mode": "更新模式",
|
||
"update_mode_notify": "仅通知",
|
||
"update_mode_download": "自动下载",
|
||
"update_mode_auto": "全自动",
|
||
"update_no_updates": "已是最新版本!",
|
||
"update_not_frozen": "更新仅在打包(exe)模式下有效",
|
||
# Groups
|
||
"group": "分组",
|
||
"no_group": "无分组",
|
||
"ungrouped": "未分组",
|
||
"add_group": "添加分组",
|
||
"edit_group": "编辑分组",
|
||
"rename_group": "重命名",
|
||
"delete_group": "删除分组",
|
||
"delete_group_confirm": "删除分组 '{name}'? 服务器将变为未分组。",
|
||
"group_name": "分组名称",
|
||
"group_color": "颜色",
|
||
"group_name_required": "分组名称为必填项",
|
||
"move_to_group": "移动到分组",
|
||
"move_up": "上移",
|
||
"move_down": "下移",
|
||
"change_color": "更改颜色",
|
||
}
|
||
|
||
_TRANSLATIONS = {
|
||
"en": _EN,
|
||
"ru": _RU,
|
||
"zh": _ZH,
|
||
}
|