termainer 0.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
termainer/locale.py ADDED
@@ -0,0 +1,460 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ from typing import Dict, Optional
5
+
6
+ LANG: str = "es"
7
+
8
+ _TEXTS: Dict[str, Dict[str, str]] = {
9
+ "es": {
10
+ # ── App ──
11
+ "app.title": "Termainer",
12
+ "app.subtitle": "Observabilidad y operación de contenedores desde tu terminal",
13
+ "app.error.no_runtime": "No se detectó ningún runtime de contenedores. Asegurate de que Docker, Swarm, Podman, kubectl u oc esté disponible y en ejecución.",
14
+ "app.error.unknown_provider": "Proveedor desconocido '{provider}'. Proveedores disponibles: {available}",
15
+ "app.error.provider_not_available": "El proveedor '{provider}' no está disponible",
16
+ # CLI
17
+ "cli.description": "Termainer — Observabilidad y operación de contenedores desde tu terminal",
18
+ "cli.help.provider": "Runtime de contenedores a usar",
19
+ "cli.help.host": "Host SSH remoto (IP o hostname). Sobreescribe TERMAINER_REMOTE_HOST en .env",
20
+ "cli.help.ssh_user": "Usuario SSH (default: root, o TERMAINER_REMOTE_USER del .env)",
21
+ "cli.help.ssh_key": "Ruta a clave privada SSH (.pem). Sobreescribe TERMAINER_REMOTE_KEY_PATH del .env",
22
+ "cli.help.ssh_password": "Contraseña SSH. Sobreescribe TERMAINER_REMOTE_PASSWORD del .env",
23
+ "cli.help.ssh_port": "Puerto SSH (default: 22, o TERMAINER_REMOTE_PORT del .env)",
24
+ "cli.help.version": "Muestra la versión y sale",
25
+ "cli.help.env_file": "Ruta al archivo .env (default: .env)",
26
+ "cli.help.config_file": "Ruta a config.yaml para multi-servidor (default: ruta XDG)",
27
+ "app.server.local_label": "Local {provider}",
28
+ "app.server.remote_label": "{provider} ({host})",
29
+ # ── Home ──
30
+ "home.bind.continue": "Continuar",
31
+ "home.bind.quit": "Salir",
32
+ "home.brand": "TERMAINER",
33
+ "home.welcome": "B I E N V E N I D O A",
34
+ "home.status.connected": "Multi-Server: {connected}/{total} conectados",
35
+ "home.about.title": "¿QUÉ ES TERMAINER?",
36
+ "home.about.description": "[#66FF33]Termainer[/] es una plataforma de observabilidad y operaciones terminal-native para ecosistemas modernos de contenedores.\n\nConecta con entornos [bold]locales[/] o [bold]remotos por SSH[/] y opera [bold #3399FF]Docker[/], [bold #3399FF]Kubernetes[/], [bold #FFD400]Swarm[/], [bold #B366FF]Podman[/] y [bold #FF3B30]OpenShift[/] desde una única interfaz interactiva, rápida y sin fricción.\n\nDiseñado para equipos [bold]DevOps[/] y [bold]SRE[/] que prefieren el control y la velocidad de la terminal.",
37
+ "home.features.title": "CARACTERÍSTICAS PRINCIPALES",
38
+ "home.platforms.title": "PLATAFORMAS SOPORTADAS",
39
+ "home.platforms.supported": "✓ Soportado",
40
+ "home.servers.title": "SERVIDORES DISPONIBLES",
41
+ "home.servers.guide": "[bold #22d3ee]↑/↓[/] recorre servidores [bold #22d3ee]Enter[/] abre selección",
42
+ "home.server.tag_local": "[LOCAL]",
43
+ "home.server.tag_ssh": "[SSH]",
44
+ "home.server.empty": "Configura tu primer servidor",
45
+ "home.dashboard_select.title": "SELECCIONA DASHBOARD",
46
+ "home.footer.shortcuts": "[bold #4ade80]↑/↓[/] Navegar [bold #22d3ee]Enter[/] Continuar [bold #22d3ee]?[/] Ayuda [bold #22d3ee]q[/] Salir",
47
+ "home.footer.credit": "Hecho con [bold #f87171]♥[/] por [bold #4ade80]Alan Stefanov[/] | v{version}",
48
+ "home.hero.tagline": "Una única interfaz para todas tus plataformas de contenedores.",
49
+ "home.header.status": "[bold]Multi-Server[/]\n[dim]{connected}/{total} conectados[/]",
50
+ "home.platform.docker": "Docker Standalone",
51
+ "home.platform.k8s": "Kubernetes",
52
+ "home.platform.swarm": "Docker Swarm",
53
+ "home.platform.podman": "Podman",
54
+ "home.platform.openshift": "OpenShift",
55
+ "home.platform.ssh": "SSH Remoto",
56
+ "home.features.obs.title": "Observabilidad",
57
+ "home.features.obs.items": "● Métricas en tiempo real\n● Logs en vivo\n● Estado de recursos\n● Eventos y alertas",
58
+ "home.features.inspection.title": "Inspección",
59
+ "home.features.inspection.items": "● Contenedores / Pods\n● Imágenes\n● Volúmenes\n● Redes\n● Variables de entorno",
60
+ "home.features.ops.title": "Operaciones",
61
+ "home.features.ops.items": "● Iniciar / Detener\n● Reiniciar\n● Ejecutar comandos\n● Acceso a shell",
62
+ "home.features.export.title": "Exportación",
63
+ "home.features.export.items": "● Logs completos\n● Reportes de bug\n● Snapshots de estado\n● Formato texto",
64
+ "home.features.unified.title": "Gestión Unificada",
65
+ "home.features.unified.items": "● Multi-servidor\n● SSH integrado\n● Switch de plataforma\n● Vista centralizada",
66
+ "home.footer.enter_hint": "Presiona ENTER para comenzar",
67
+ "home.footer.credits": "[dim]Desarrollado por[/] [bold #66FF33]Alan Stefanov[/] [dim]│[/] [#00E5FF]github.com/alanstefanov[/] [dim]│[/] [#00E5FF]astefanov.com[/]",
68
+ # ── Environment ──
69
+ "environment.bind.up": "Arriba",
70
+ "environment.bind.down": "Abajo",
71
+ "environment.bind.left": "Izquierda",
72
+ "environment.bind.right": "Derecha",
73
+ "environment.bind.select": "Seleccionar",
74
+ "environment.bind.help": "Ayuda",
75
+ "environment.bind.quit": "Salir",
76
+ "environment.title": "Selecciona la tecnología que quieres monitorear",
77
+ "environment.copy": "Cada dashboard permite vista multi-servidor con selector de conexiones SSH/locales.",
78
+ "environment.footer.full": "[reverse] ↑↓←→ [/reverse] Navegar [reverse] Enter [/reverse] Seleccionar [reverse] q [/reverse] Salir",
79
+ "environment.footer.compact": "[reverse] Enter [/reverse] Seleccionar [reverse] q [/reverse] Salir",
80
+ "environment.button.open": "Abrir dashboard",
81
+ "environment.status.connections": "[bold #4ade80]{count} conexión(es) disponible(s)[/]",
82
+ "environment.status.cli_no_context": "[bold #fbbf24]CLI detectada, falta login/contexto o conexión remota[/]",
83
+ "environment.status.cli_no_cluster": "[bold #fbbf24]CLI detectada, cluster local no disponible[/]",
84
+ "environment.status.cli_no_servers": "[bold #fbbf24]CLI detectada, sin servidores configurados[/]",
85
+ "environment.status.not_available": "[bold #f87171]No instalado local ni conexión remota[/]",
86
+ "environment.subtitle.docker": "Contenedores Docker standalone",
87
+ "environment.subtitle.kubernetes": "Pods y namespaces en clusters K8s",
88
+ "environment.subtitle.podman": "Contenedores rootless y pods locales/remotos",
89
+ "environment.subtitle.openshift": "Workloads sobre clusters OpenShift",
90
+ "environment.subtitle.swarm": "Servicios, tasks y nodos Swarm",
91
+ "environment.notify.ssh_hint": "Configura servidores remotos en ~/.ssh/config para acceso multi-servidor",
92
+ "environment.notify.no_context": "{provider} detectado, pero sin contexto activo (login/kubeconfig) ni servidor remoto configurado.",
93
+ "environment.notify.no_cluster": "{provider} detectado, pero cluster local no disponible.",
94
+ "environment.notify.no_servers": "{provider} detectado, pero sin servidores locales/remotos listos para monitorear.",
95
+ "environment.notify.not_installed": "{provider} no está instalado en tu local o no está conectado a un servidor remoto.",
96
+ # ── Dashboard ──
97
+ "dashboard.bind.up": "Arriba",
98
+ "dashboard.bind.down": "Abajo",
99
+ "dashboard.bind.select": "Seleccionar",
100
+ "dashboard.bind.refresh": "Refrescar",
101
+ "dashboard.bind.pause_logs": "Pausar Logs",
102
+ "dashboard.bind.export": "Exportar",
103
+ "dashboard.bind.start": "Iniciar",
104
+ "dashboard.bind.stop": "Detener",
105
+ "dashboard.bind.restart": "Reiniciar",
106
+ "dashboard.bind.delete": "Eliminar",
107
+ "dashboard.bind.restart_policy": "Política",
108
+ "dashboard.bind.exec": "Ejecutar",
109
+ "dashboard.bind.back": "Volver",
110
+ "dashboard.bind.quit": "Salir",
111
+ "dashboard.resource.pods": "PODS",
112
+ "dashboard.resource.containers": "CONTENEDORES",
113
+ "dashboard.resource.pod": "pod",
114
+ "dashboard.resource.container": "contenedor",
115
+ "dashboard.search.placeholder": "Buscar {resource}...",
116
+ "dashboard.status.connected": "[bold #22d3ee]● {provider}: conectado[/]",
117
+ "dashboard.status.disconnected": "[bold #fbbf24]● Sin conexión[/]",
118
+ "dashboard.tagline": "Todo lo que necesitas saber de TODOS tus contenedores en una sola terminal",
119
+ "dashboard.server_info.ssh": "Servidor: {server} - {host}",
120
+ "dashboard.server_info.local": "Servidor: {hostname} - {ip}",
121
+ "dashboard.details.header_pod": "DETALLES DEL POD",
122
+ "dashboard.details.header_container": "DETALLES DEL CONTENEDOR",
123
+ "dashboard.details.placeholder": "(Selecciona un {resource})",
124
+ "dashboard.stats.header": "ESTADÍSTICAS EN TIEMPO REAL",
125
+ "dashboard.logs.header": "REGSITROS (Selecciona un contenedor)",
126
+ "dashboard.logs.live": "● EN VIVO",
127
+ "dashboard.logs.paused": "⏸ PAUSADO",
128
+ "dashboard.logs.title": "[bold white]› REGSITROS[/] [dim]({name}) - Presiona 'p' para pausar, 'e' para exportar[/]",
129
+ "dashboard.logs.status_paused": "pausado",
130
+ "dashboard.logs.status_resumed": "reanudado",
131
+ "dashboard.logs.toggle_notify": "REGSITROS {status}",
132
+ "dashboard.sidebar.multi_server": " (de {count} servidor(es))",
133
+ "dashboard.notify.server_not_found": "Servidor '{alias}' no encontrado en ~/.ssh/config",
134
+ "dashboard.notify.ssh_error": "Error al conectar con '{alias}': {e}",
135
+ "dashboard.notify.list_error": "Error al listar contenedores: {e}",
136
+ "dashboard.notify.details_error": "Error al cargar detalles",
137
+ "dashboard.notify.log_stream_ended": "\[error: el flujo de registros terminó\]",
138
+ "dashboard.notify.select_container": "Selecciona un contenedor primero",
139
+ "dashboard.notify.action_error": "Error ejecutando {action}: {e}",
140
+ "dashboard.notify.select_container_remove": "Selecciona un contenedor primero",
141
+ "dashboard.notify.select_container_policy": "Selecciona un contenedor primero",
142
+ "dashboard.notify.select_container_exec": "Selecciona un contenedor primero",
143
+ "dashboard.notify.no_logs": "No hay registros para exportar",
144
+ "dashboard.notify.logs_exported": "Registros exportados a {filepath}",
145
+ "dashboard.notify.policy_changed": "Política cambiada a '{policy}'",
146
+ "dashboard.notify.generic_error": "Error: {e}",
147
+ "dashboard.action.start_success": "Contenedor iniciado",
148
+ "dashboard.action.stop_success": "Contenedor detenido",
149
+ "dashboard.action.restart_success": "Contenedor reiniciado",
150
+ "dashboard.action.remove_success": "Contenedor eliminado",
151
+ # Dashboard modals
152
+ "dashboard.remove_modal.title": "[bold #f87171]Eliminar {resource}[/]",
153
+ "dashboard.remove_modal.body": "Vas a eliminar [bold white]{name}[/]",
154
+ "dashboard.remove_modal.warning": "Esta acción no se puede deshacer.",
155
+ "dashboard.remove_modal.cancel": "Cancelar",
156
+ "dashboard.remove_modal.confirm": "Eliminar",
157
+ "dashboard.policy_modal.title": "Política de Reinicio",
158
+ "dashboard.policy_modal.container": "Contenedor: {name}",
159
+ "dashboard.policy_modal.current": "Actual: {policy}",
160
+ "dashboard.policy_modal.undefined": "no definida",
161
+ "dashboard.policy_modal.cancel": "Cancelar",
162
+ "dashboard.policy_modal.apply": "Aplicar",
163
+ "dashboard.exec_modal.title": "[bold #22d3ee]Exec:[/] [bold white]{name}[/]",
164
+ "dashboard.exec_modal.placeholder": "ej: ls -la /app | cat /etc/hosts | env",
165
+ "dashboard.exec_modal.run": "Ejecutar",
166
+ "dashboard.exec_modal.close": "Cerrar",
167
+ "dashboard.exec_modal.prompt": "[dim]$ {command}[/]",
168
+ "dashboard.exec_modal.end": "--- fin ---",
169
+ "dashboard.exec_modal.error": "[bold #f87171]Error: {error}[/]",
170
+ # ── Widgets ──
171
+ "widgets.details.image": "Imagen:",
172
+ "widgets.details.status": "Estado:",
173
+ "widgets.details.id": "ID:",
174
+ "widgets.details.created": "Creado:",
175
+ "widgets.details.ports": "Puerto(s):",
176
+ "widgets.details.networks": "Red(es):",
177
+ "widgets.details.restart": "Reinicio:",
178
+ "widgets.details.namespace": "Espacio:",
179
+ "widgets.details.ready": "Listo:",
180
+ "widgets.details.node": "Nodo:",
181
+ "widgets.details.env_title": "VARIABLES DE ENTORNO ({count})",
182
+ "widgets.details.env_empty": "(sin variables de entorno)",
183
+ "widgets.stats.cpu": "CPU",
184
+ "widgets.stats.memory": "MEMORIA",
185
+ "widgets.stats.net": "RED I/O",
186
+ "widgets.stats.pids": "PIDS",
187
+ "widgets.stats.cpu_chart": "CPU % (Últimos 60s)",
188
+ "widgets.stats.mem_chart": "Memoria (Últimos 60s)",
189
+ "widgets.stats.net_chart": "Red I/O (Últimos 60s)",
190
+ # ── Splash (legacy) ──
191
+ "splash.welcome": "B I E N V E N I D O A",
192
+ "splash.tagline": "Todo lo que necesitas saber de TODOS tus contenedores en una sola terminal",
193
+ "splash.about.title": "¿QUÉ ES TERMAINER?",
194
+ "splash.features.title": "CARACTERÍSTICAS PRINCIPALES",
195
+ "splash.features.realtime": "▥ Estadísticas en Tiempo Real",
196
+ "splash.features.realtime.desc": "[dim]Monitorea CPU, memoria\ny red al instante.[/]",
197
+ "splash.features.logs": "▤ Logs en Vivo",
198
+ "splash.features.logs.desc": "[dim]Visualiza y navega logs\ncon scroll suave.[/]",
199
+ "splash.features.inspection": "⌕ Inspección Detallada",
200
+ "splash.features.inspection.desc": "[dim]Variables, redes,\nvolúmenes y más.[/]",
201
+ "splash.features.multi": "⇶ Multi-Tecnología + SSH",
202
+ "splash.features.multi.desc": "[dim]Docker, Podman, K8s, OpenShift,\nSwarm y multi-servidor.[/]",
203
+ "splash.shortcuts.title": "ATAJOS DE TECLADO",
204
+ "splash.shortcuts.navigate": "↑ / ↓ Navegar contenedores",
205
+ "splash.shortcuts.select": "Enter Seleccionar contenedor",
206
+ "splash.shortcuts.refresh": "F5 Refrescar",
207
+ "splash.shortcuts.export": "e Exportar logs",
208
+ "splash.shortcuts.pause": "p Pausar / Reanudar logs",
209
+ "splash.shortcuts.next": "n Siguiente panel",
210
+ "splash.shortcuts.switch": "← / → Cambiar panel",
211
+ "splash.shortcuts.back": "b Volver a tecnologías",
212
+ "splash.shortcuts.actions": "a/t/r Iniciar / Detener / Reiniciar",
213
+ "splash.shortcuts.delete": "Del Eliminar contenedor",
214
+ "splash.shortcuts.quit": "q Salir de Termainer",
215
+ "splash.shortcuts.help": "? Mostrar ayuda",
216
+ "splash.quickstart.flow": "ESTADÍSTICAS -> DETALLES -> REGISTROS",
217
+ "splash.enter_hint": "Presiona Enter para continuar",
218
+ "splash.footer": "desarrollada por Alan Stefanov",
219
+ # ── Boot screen ──
220
+ "splash.boot.init": "Inicializando Termainer",
221
+ "splash.boot.docker": "Conectando con Docker",
222
+ "splash.boot.k8s": "Conectando con Kubernetes",
223
+ "splash.boot.openshift": "Conectando con OpenShift",
224
+ "splash.boot.discover": "Descubriendo servidores",
225
+ "splash.boot.sync": "Sincronizando plataformas",
226
+ },
227
+ "en": {
228
+ # ── App ──
229
+ "app.title": "Termainer",
230
+ "app.subtitle": "Container observability and operations from your terminal",
231
+ "app.error.no_runtime": "No container runtime detected. Please ensure Docker, Swarm, Podman, or kubectl/oc is available and running.",
232
+ "app.error.unknown_provider": "Unknown provider '{provider}'. Available providers: {available}",
233
+ "app.error.provider_not_available": "Provider '{provider}' is not available",
234
+ # CLI
235
+ "cli.description": "Termainer — Container observability and operations from your terminal",
236
+ "cli.help.provider": "Container runtime provider to use",
237
+ "cli.help.host": "Remote SSH host (IP or hostname). Overrides TERMAINER_REMOTE_HOST in .env",
238
+ "cli.help.ssh_user": "SSH user (default: root, or TERMAINER_REMOTE_USER from .env)",
239
+ "cli.help.ssh_key": "SSH private key path (.pem). Overrides TERMAINER_REMOTE_KEY_PATH in .env",
240
+ "cli.help.ssh_password": "SSH password. Overrides TERMAINER_REMOTE_PASSWORD in .env",
241
+ "cli.help.ssh_port": "SSH port (default: 22, or TERMAINER_REMOTE_PORT from .env)",
242
+ "cli.help.version": "Show version and exit",
243
+ "cli.help.env_file": "Path to .env file for remote configuration (default: .env)",
244
+ "cli.help.config_file": "Path to config.yaml for multi-server setup (default: auto-detect XDG path)",
245
+ "app.server.local_label": "Local {provider}",
246
+ "app.server.remote_label": "{provider} ({host})",
247
+ # ── Home ──
248
+ "home.bind.continue": "Continue",
249
+ "home.bind.quit": "Quit",
250
+ "home.brand": "TERMAINER",
251
+ "home.welcome": "W E L C O M E T O",
252
+ "home.status.connected": "Multi-Server: {connected}/{total} connected",
253
+ "home.about.title": "WHAT IS TERMAINER?",
254
+ "home.about.description": "[#66FF33]Termainer[/] is a terminal-native observability and operations platform for modern container ecosystems.\n\nConnect to [bold]local[/] or [bold]remote SSH[/] environments and manage [bold #3399FF]Docker[/], [bold #3399FF]Kubernetes[/], [bold #FFD400]Swarm[/], [bold #B366FF]Podman[/], and [bold #FF3B30]OpenShift[/] from a single interactive, fast, frictionless interface.\n\nDesigned for [bold]DevOps[/] and [bold]SRE[/] teams who prefer the control and speed of the terminal.",
255
+ "home.features.title": "KEY FEATURES",
256
+ "home.platforms.title": "SUPPORTED PLATFORMS",
257
+ "home.platforms.supported": "✓ Supported",
258
+ "home.servers.title": "AVAILABLE SERVERS",
259
+ "home.servers.guide": "[bold #22d3ee]↑/↓[/] browse servers [bold #22d3ee]Enter[/] open selection",
260
+ "home.server.tag_local": "[LOCAL]",
261
+ "home.server.tag_ssh": "[SSH]",
262
+ "home.server.empty": "Configure your first server",
263
+ "home.dashboard_select.title": "SELECT DASHBOARD",
264
+ "home.footer.shortcuts": "[bold #4ade80]↑/↓[/] Navigate [bold #22d3ee]Enter[/] Continue [bold #22d3ee]?[/] Help [bold #22d3ee]q[/] Quit",
265
+ "home.footer.credit": "Made with [bold #f87171]♥[/] by [bold #4ade80]Alan Stefanov[/] | v{version}",
266
+ "home.hero.tagline": "A single interface for all your container platforms.",
267
+ "home.header.status": "[bold]Multi-Server[/]\n[dim]{connected}/{total} connected[/]",
268
+ "home.platform.docker": "Docker Standalone",
269
+ "home.platform.k8s": "Kubernetes",
270
+ "home.platform.swarm": "Docker Swarm",
271
+ "home.platform.podman": "Podman",
272
+ "home.platform.openshift": "OpenShift",
273
+ "home.platform.ssh": "SSH Remote",
274
+ "home.features.obs.title": "Observability",
275
+ "home.features.obs.items": "● Real-time metrics\n● Live logs\n● Resource status\n● Events & alerts",
276
+ "home.features.inspection.title": "Inspection",
277
+ "home.features.inspection.items": "● Containers / Pods\n● Images\n● Volumes\n● Networks\n● Environment variables",
278
+ "home.features.ops.title": "Operations",
279
+ "home.features.ops.items": "● Start / Stop\n● Restart\n● Exec commands\n● Shell access",
280
+ "home.features.export.title": "Export",
281
+ "home.features.export.items": "● Full logs\n● Bug reports\n● State snapshots\n● Text format",
282
+ "home.features.unified.title": "Unified Management",
283
+ "home.features.unified.items": "● Multi-server\n● Integrated SSH\n● Platform switching\n● Centralized view",
284
+ "home.footer.enter_hint": "Press ENTER to start",
285
+ "home.footer.credits": "[dim]Developed by[/] [bold #66FF33]Alan Stefanov[/] [dim]│[/] [#00E5FF]github.com/alanstefanov[/] [dim]│[/] [#00E5FF]astefanov.com[/]",
286
+ # ── Environment ──
287
+ "environment.bind.up": "Up",
288
+ "environment.bind.down": "Down",
289
+ "environment.bind.left": "Left",
290
+ "environment.bind.right": "Right",
291
+ "environment.bind.select": "Select",
292
+ "environment.bind.help": "Help",
293
+ "environment.bind.quit": "Quit",
294
+ "environment.title": "Select the technology you want to monitor",
295
+ "environment.copy": "Each dashboard provides a multi-server view with an SSH/local connection selector.",
296
+ "environment.footer.full": "↑↓←→ Navigate Enter Select q Quit",
297
+ "environment.footer.compact": "Enter Select q Quit",
298
+ "environment.button.open": "Open dashboard",
299
+ "environment.status.connections": "{count} connection(s) available",
300
+ "environment.status.cli_no_context": "CLI detected, missing login/context or remote connection",
301
+ "environment.status.cli_no_cluster": "CLI detected, local cluster not available",
302
+ "environment.status.cli_no_servers": "CLI detected, no servers configured",
303
+ "environment.status.not_available": "Not installed locally nor remote connection",
304
+ "environment.subtitle.docker": "Standalone Docker containers",
305
+ "environment.subtitle.kubernetes": "Pods and namespaces in K8s clusters",
306
+ "environment.subtitle.podman": "Rootless containers and local/remote pods",
307
+ "environment.subtitle.openshift": "Workloads on OpenShift clusters",
308
+ "environment.subtitle.swarm": "Services, tasks and Swarm nodes",
309
+ "environment.notify.ssh_hint": "Configure remote servers in ~/.ssh/config for multi-server access",
310
+ "environment.notify.no_context": "{provider} detected, but no active context (login/kubeconfig) or remote server configured.",
311
+ "environment.notify.no_cluster": "{provider} detected, but local cluster not available.",
312
+ "environment.notify.no_servers": "{provider} detected, but no local/remote servers ready to monitor.",
313
+ "environment.notify.not_installed": "{provider} is not installed locally or connected to a remote server.",
314
+ # ── Dashboard ──
315
+ "dashboard.bind.up": "Up",
316
+ "dashboard.bind.down": "Down",
317
+ "dashboard.bind.select": "Select",
318
+ "dashboard.bind.refresh": "Refresh",
319
+ "dashboard.bind.pause_logs": "Pause Logs",
320
+ "dashboard.bind.export": "Export",
321
+ "dashboard.bind.start": "Start",
322
+ "dashboard.bind.stop": "Stop",
323
+ "dashboard.bind.restart": "Restart",
324
+ "dashboard.bind.delete": "Remove",
325
+ "dashboard.bind.restart_policy": "Policy",
326
+ "dashboard.bind.exec": "Exec",
327
+ "dashboard.bind.back": "Back",
328
+ "dashboard.bind.quit": "Quit",
329
+ "dashboard.resource.pods": "PODS",
330
+ "dashboard.resource.containers": "CONTAINERS",
331
+ "dashboard.resource.pod": "pod",
332
+ "dashboard.resource.container": "container",
333
+ "dashboard.search.placeholder": "Search {resource}...",
334
+ "dashboard.status.connected": "[bold #22d3ee]● {provider}: connected[/]",
335
+ "dashboard.status.disconnected": "[bold #fbbf24]● Disconnected[/]",
336
+ "dashboard.tagline": "Everything you need to know about ALL your containers in a single terminal",
337
+ "dashboard.server_info.ssh": "Server: {server} - {host}",
338
+ "dashboard.server_info.local": "Server: {hostname} - {ip}",
339
+ "dashboard.details.header_pod": "POD DETAILS",
340
+ "dashboard.details.header_container": "CONTAINER DETAILS",
341
+ "dashboard.details.placeholder": "(Select a {resource})",
342
+ "dashboard.stats.header": "REAL-TIME STATISTICS",
343
+ "dashboard.logs.header": "LOGS (Select a container)",
344
+ "dashboard.logs.live": "● LIVE",
345
+ "dashboard.logs.paused": "⏸ PAUSED",
346
+ "dashboard.logs.title": "[bold white]› LOGS[/] [dim]({name}) - Press 'p' to pause, 'e' to export[/]",
347
+ "dashboard.logs.status_paused": "paused",
348
+ "dashboard.logs.status_resumed": "resumed",
349
+ "dashboard.logs.toggle_notify": "Logs {status}",
350
+ "dashboard.sidebar.multi_server": " (from {count} server(s))",
351
+ "dashboard.notify.server_not_found": "Server '{alias}' not found in ~/.ssh/config",
352
+ "dashboard.notify.ssh_error": "Error connecting to '{alias}': {e}",
353
+ "dashboard.notify.list_error": "Error listing containers: {e}",
354
+ "dashboard.notify.details_error": "Error loading details",
355
+ "dashboard.notify.log_stream_ended": "[error: log stream ended]",
356
+ "dashboard.notify.select_container": "Select a container first",
357
+ "dashboard.notify.action_error": "Error running {action}: {e}",
358
+ "dashboard.notify.select_container_remove": "Select a container first",
359
+ "dashboard.notify.select_container_policy": "Select a container first",
360
+ "dashboard.notify.select_container_exec": "Select a container first",
361
+ "dashboard.notify.no_logs": "No logs to export",
362
+ "dashboard.notify.logs_exported": "Logs exported to {filepath}",
363
+ "dashboard.notify.policy_changed": "Policy changed to '{policy}'",
364
+ "dashboard.notify.generic_error": "Error: {e}",
365
+ "dashboard.action.start_success": "Container started",
366
+ "dashboard.action.stop_success": "Container stopped",
367
+ "dashboard.action.restart_success": "Container restarted",
368
+ "dashboard.action.remove_success": "Container removed",
369
+ # Dashboard modals
370
+ "dashboard.remove_modal.title": "[bold #f87171]Remove {resource}[/]",
371
+ "dashboard.remove_modal.body": "You are about to remove [bold white]{name}[/]",
372
+ "dashboard.remove_modal.warning": "This action cannot be undone.",
373
+ "dashboard.remove_modal.cancel": "Cancel",
374
+ "dashboard.remove_modal.confirm": "Remove",
375
+ "dashboard.policy_modal.title": "Restart Policy",
376
+ "dashboard.policy_modal.container": "Container: {name}",
377
+ "dashboard.policy_modal.current": "Current: {policy}",
378
+ "dashboard.policy_modal.undefined": "undefined",
379
+ "dashboard.policy_modal.cancel": "Cancel",
380
+ "dashboard.policy_modal.apply": "Apply",
381
+ "dashboard.exec_modal.title": "[bold #22d3ee]Exec:[/] [bold white]{name}[/]",
382
+ "dashboard.exec_modal.placeholder": "e.g.: ls -la /app | cat /etc/hosts | env",
383
+ "dashboard.exec_modal.run": "Run",
384
+ "dashboard.exec_modal.close": "Close",
385
+ "dashboard.exec_modal.prompt": "[dim]$ {command}[/]",
386
+ "dashboard.exec_modal.end": "--- end ---",
387
+ "dashboard.exec_modal.error": "[bold #f87171]Error: {error}[/]",
388
+ # ── Widgets ──
389
+ "widgets.details.image": "Image:",
390
+ "widgets.details.status": "Status:",
391
+ "widgets.details.id": "ID:",
392
+ "widgets.details.created": "Created:",
393
+ "widgets.details.ports": "Port(s):",
394
+ "widgets.details.networks": "Network(s):",
395
+ "widgets.details.restart": "Restart:",
396
+ "widgets.details.namespace": "Namespace:",
397
+ "widgets.details.ready": "Ready:",
398
+ "widgets.details.node": "Node:",
399
+ "widgets.details.env_title": "ENVIRONMENT VARIABLES ({count})",
400
+ "widgets.details.env_empty": "(no environment variables)",
401
+ "widgets.stats.cpu": "CPU",
402
+ "widgets.stats.memory": "MEMORY",
403
+ "widgets.stats.net": "NET I/O",
404
+ "widgets.stats.pids": "PIDS",
405
+ "widgets.stats.cpu_chart": "CPU % (Last 60s)",
406
+ "widgets.stats.mem_chart": "Memory (Last 60s)",
407
+ "widgets.stats.net_chart": "Net I/O (Last 60s)",
408
+ # ── Splash (legacy) ──
409
+ "splash.welcome": "W E L C O M E T O",
410
+ "splash.tagline": "Everything you need to know about ALL your containers in a single terminal",
411
+ "splash.about.title": "WHAT IS TERMAINER?",
412
+ "splash.features.title": "KEY FEATURES",
413
+ "splash.features.realtime": "▥ Real-time Stats",
414
+ "splash.features.realtime.desc": "[dim]Monitor CPU, memory,\nand network instantly.[/]",
415
+ "splash.features.logs": "▤ Live Logs",
416
+ "splash.features.logs.desc": "[dim]View and navigate logs\nwith smooth scrolling.[/]",
417
+ "splash.features.inspection": "⌕ Detailed Inspection",
418
+ "splash.features.inspection.desc": "[dim]Variables, networks,\nvolumes, and more.[/]",
419
+ "splash.features.multi": "⇶ Multi-Tech + SSH",
420
+ "splash.features.multi.desc": "[dim]Docker, Podman, K8s,\nOpenShift, Swarm, and multi-server.[/]",
421
+ "splash.shortcuts.title": "KEYBOARD SHORTCUTS",
422
+ "splash.shortcuts.navigate": "↑ / ↓ Navigate containers",
423
+ "splash.shortcuts.select": "Enter Select container",
424
+ "splash.shortcuts.refresh": "F5 Refresh",
425
+ "splash.shortcuts.export": "e Export logs",
426
+ "splash.shortcuts.pause": "p Pause / Resume logs",
427
+ "splash.shortcuts.next": "n Next panel",
428
+ "splash.shortcuts.switch": "← / → Switch panel",
429
+ "splash.shortcuts.back": "b Back to technologies",
430
+ "splash.shortcuts.actions": "a/t/r Start / Stop / Restart",
431
+ "splash.shortcuts.delete": "Del Remove container",
432
+ "splash.shortcuts.quit": "q Quit Termainer",
433
+ "splash.shortcuts.help": "? Show help",
434
+ "splash.quickstart.flow": "STATS -> DETAILS -> LOGS",
435
+ "splash.enter_hint": "Press Enter to continue",
436
+ "splash.footer": "developed by Alan Stefanov",
437
+ # ── Boot screen ──
438
+ "splash.boot.init": "Initializing Termainer",
439
+ "splash.boot.docker": "Connecting to Docker",
440
+ "splash.boot.k8s": "Connecting to Kubernetes",
441
+ "splash.boot.openshift": "Connecting to OpenShift",
442
+ "splash.boot.discover": "Discovering servers",
443
+ "splash.boot.sync": "Syncing platforms",
444
+ },
445
+ }
446
+
447
+
448
+ def init(env: Optional[Dict[str, str]] = None) -> None:
449
+ global LANG
450
+ if env and "TERMAINER_LANG" in env:
451
+ LANG = env["TERMAINER_LANG"].lower()
452
+ else:
453
+ LANG = (os.environ.get("TERMAINER_LANG") or "es").lower()
454
+
455
+
456
+ def _(key: str, **kwargs: str) -> str:
457
+ text = _TEXTS.get(LANG, _TEXTS["es"]).get(key, key)
458
+ if kwargs:
459
+ text = text.format(**kwargs)
460
+ return text
File without changes
@@ -0,0 +1,61 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, AsyncIterator, Dict, List, Optional, Protocol, runtime_checkable
4
+
5
+ from ..remote.ssh import SSHConnection
6
+
7
+
8
+ ContainerSummary = Dict[str, Any]
9
+ ContainerDetails = Dict[str, Any]
10
+ ContainerStats = Dict[str, Any]
11
+
12
+
13
+ @runtime_checkable
14
+ class Provider(Protocol):
15
+ name: str
16
+
17
+ async def list_containers(self) -> List[ContainerSummary]:
18
+ ...
19
+
20
+ async def inspect(self, container_id: str) -> ContainerDetails:
21
+ ...
22
+
23
+ async def stats(self, container_id: str) -> AsyncIterator[ContainerStats]:
24
+ ...
25
+
26
+ async def logs(
27
+ self, container_id: str, tail: int = 100, follow: bool = False
28
+ ) -> AsyncIterator[str]:
29
+ ...
30
+
31
+ async def get_env(self, container_id: str) -> Dict[str, str]:
32
+ ...
33
+
34
+ async def start(self, container_id: str) -> None:
35
+ ...
36
+
37
+ async def stop(self, container_id: str) -> None:
38
+ ...
39
+
40
+ async def restart(self, container_id: str) -> None:
41
+ ...
42
+
43
+ async def remove(self, container_id: str, force: bool = False) -> None:
44
+ ...
45
+
46
+ async def set_restart_policy(self, container_id: str, policy: str) -> None:
47
+ ...
48
+
49
+ async def exec_command(self, container_id: str, command: str) -> AsyncIterator[str]:
50
+ ...
51
+ yield "" # make this a generator for the Protocol
52
+
53
+ async def is_available(self) -> bool:
54
+ ...
55
+
56
+ async def close(self) -> None:
57
+ ...
58
+
59
+
60
+ class SSHAwareProvider:
61
+ _ssh: Optional[SSHConnection] = None