Upload 2 files
Browse files- i18n.py +130 -30
- templates_setup.py +2 -0
i18n.py
CHANGED
|
@@ -191,36 +191,136 @@ def _populate_catalog() -> None:
|
|
| 191 |
"Запитай що завгодно\u2026 (Enter \u2014 надіслати, Shift+Enter \u2014 новий рядок, Esc \u2014 закрити)",
|
| 192 |
})
|
| 193 |
_CATALOG["ru"].update({
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 224 |
})
|
| 225 |
|
| 226 |
|
|
|
|
| 191 |
"Запитай що завгодно\u2026 (Enter \u2014 надіслати, Shift+Enter \u2014 новий рядок, Esc \u2014 закрити)",
|
| 192 |
})
|
| 193 |
_CATALOG["ru"].update({
|
| 194 |
+
'Metrics': 'Метрики',
|
| 195 |
+
'Proxy traffic, latency, error rate and per-bot upload / download activity.': 'Прокси-трафик, задержка, частота ошибок и активность загрузок/скачиваний по ботам.',
|
| 196 |
+
'Window': 'Окно',
|
| 197 |
+
'Last hour': 'Последний час',
|
| 198 |
+
'Last 6h': 'Последние 6 ч',
|
| 199 |
+
'Last 24h': 'Последние 24 ч',
|
| 200 |
+
'Last 3d': 'Последние 3 дня',
|
| 201 |
+
'Last 7d': 'Последние 7 дней',
|
| 202 |
+
'Last 30d': 'Последние 30 дней',
|
| 203 |
+
'All bots': 'Все боты',
|
| 204 |
+
'Requests': 'Запросы',
|
| 205 |
+
'in last': 'за последние',
|
| 206 |
+
'Error rate': 'Частота ошибок',
|
| 207 |
+
'errors': 'ошибок',
|
| 208 |
+
'Latency p95': 'Задержка p95',
|
| 209 |
+
'Throughput': 'Пропускная способность',
|
| 210 |
+
'requests / minute': 'запросов / минуту',
|
| 211 |
+
'Proxy traffic — hourly': 'Прокси-трафик — по часам',
|
| 212 |
+
'Stacked: requests per hour (line) and errors (filled). Hover bars/lines for exact values.': 'Стек: запросы в час (линия) и ошибки (заливка). Наведите курсор, чтобы увидеть точные значения.',
|
| 213 |
+
'Status codes': 'Коды статуса',
|
| 214 |
+
'Code': 'Код',
|
| 215 |
+
'Count': 'Количество',
|
| 216 |
+
'2xx Success': '2xx Успех',
|
| 217 |
+
'3xx Redirect': '3xx Перенаправление',
|
| 218 |
+
'4xx Client': '4xx Клиент',
|
| 219 |
+
'5xx Server': '5xx Сервер',
|
| 220 |
+
'Top endpoints': 'Топ эндпоинтов',
|
| 221 |
+
'Method / Path': 'Метод / Путь',
|
| 222 |
+
'Avg ms': 'Среднее мс',
|
| 223 |
+
'No proxy traffic in this window.': 'В этом окне нет прокси-трафика.',
|
| 224 |
+
'Bot upload / download activity — hourly': 'Активность загрузок/скачиваний ботов — по часам',
|
| 225 |
+
'Uploads: zip_upload, file_save, file_create. Downloads: file_raw.': 'Загрузки: zip_upload, file_save, file_create. Скачивания: file_raw.',
|
| 226 |
+
'Live bot snapshot': 'Живой снимок ботов',
|
| 227 |
+
'RAM': 'ОЗУ',
|
| 228 |
+
'CPU': 'CPU',
|
| 229 |
+
'Last healthcheck': 'Последняя проверка здоровья',
|
| 230 |
+
'No bots yet.': 'Пока нет ботов.',
|
| 231 |
+
'Alerts': 'Алерты',
|
| 232 |
+
'Threshold rules that fire Telegram or webhook notifications when bots misbehave.': 'Правила порогов, которые отправляют уведомления в Telegram или webhook, когда боты ведут себя непр��вильно.',
|
| 233 |
+
'New rule': 'Новое правило',
|
| 234 |
+
'Evaluate now': 'Проверить сейчас',
|
| 235 |
+
'active': 'активно',
|
| 236 |
+
'paused': 'на паузе',
|
| 237 |
+
'cluster': 'кластер',
|
| 238 |
+
'Fired': 'Срабатываний',
|
| 239 |
+
'Toggle active': 'Вкл/выкл',
|
| 240 |
+
'Test fire (sends a synthetic alert)': 'Тестовое срабатывание (отправляет синтетический алерт)',
|
| 241 |
+
'Delete': 'Удалить',
|
| 242 |
+
'Delete this rule? This cannot be undone.': 'Удалить это правило? Это действие нельзя отменить.',
|
| 243 |
+
'No alert rules yet': 'Правил алертов пока нет',
|
| 244 |
+
"Add a rule below — for example, fire when any bot's RAM exceeds 80%.": 'Добавьте правило ниже — например, срабатывание при превышении RAM любого бота 80%.',
|
| 245 |
+
'New alert rule': 'Новое правило алерта',
|
| 246 |
+
'Name': 'Название',
|
| 247 |
+
'Scope': 'Область',
|
| 248 |
+
'All bots (cluster-wide)': 'Все боты (по всему кластеру)',
|
| 249 |
+
'Metric': 'Метрика',
|
| 250 |
+
'Bot RAM (MB)': 'RAM бота (МБ)',
|
| 251 |
+
'Bot CPU (%)': 'CPU бота (%)',
|
| 252 |
+
'Bot status (string)': 'Статус бота (строка)',
|
| 253 |
+
'Error rate (% over window)': 'Частота ошибок (% за окно)',
|
| 254 |
+
'Proxy p95 latency (ms)': 'Задержка прокси p95 (мс)',
|
| 255 |
+
'Proxy requests / minute': 'Запросы к прокси / минуту',
|
| 256 |
+
'Host RAM (%)': 'RAM хоста (%)',
|
| 257 |
+
'Host CPU (%)': 'CPU хоста (%)',
|
| 258 |
+
'Operator': 'Оператор',
|
| 259 |
+
'Threshold': 'Порог',
|
| 260 |
+
'Window (minutes)': 'Окно (минут)',
|
| 261 |
+
'Cooldown (minutes)': 'Кулдаун (минут)',
|
| 262 |
+
'Severity': 'Серьёзность',
|
| 263 |
+
'Channel': 'Канал',
|
| 264 |
+
'Telegram chat_id': 'Telegram chat_id',
|
| 265 |
+
'Webhook URL': 'Webhook URL',
|
| 266 |
+
'Description (optional)': 'Описание (необязательно)',
|
| 267 |
+
'What this rule is for…': 'Для чего это правило…',
|
| 268 |
+
'Active (start firing immediately)': 'Активно (начать срабатывать сразу)',
|
| 269 |
+
'Create rule': 'Создать правило',
|
| 270 |
+
'Reset': 'Сбросить',
|
| 271 |
+
'Recent events': 'Последние события',
|
| 272 |
+
'No alerts have fired yet.': 'Пока не было ни одного алерта.',
|
| 273 |
+
'When': 'Когда',
|
| 274 |
+
'Rule': 'Правило',
|
| 275 |
+
'Bot': 'Бот',
|
| 276 |
+
'Value': 'Значение',
|
| 277 |
+
'Delivery': 'Доставка',
|
| 278 |
+
'No matching events': 'Нет событий по фильтру',
|
| 279 |
+
'Try a different filter combination.': 'Попробуйте другую комбинацию фильтров.',
|
| 280 |
+
'Try selecting different filters or typing another search.': 'Попробуйте другие фильтры или другой поисковый запрос.',
|
| 281 |
+
'All users': 'Все пользователи',
|
| 282 |
+
'Active': 'Активен',
|
| 283 |
+
'Disabled': 'Отключён',
|
| 284 |
+
'Open user detail': 'Открыть детали пользователя',
|
| 285 |
+
'Suspend': 'Приостановить',
|
| 286 |
+
'Reactivate': 'Восстановить',
|
| 287 |
+
'Password reset': 'Сброс пароля',
|
| 288 |
+
'saved (the user must sign in again).': 'сохранено (пользователь должен войти снова).',
|
| 289 |
+
'Security': 'Безопасность',
|
| 290 |
+
'Reset password': 'Сбросить пароль',
|
| 291 |
+
'New password': 'Новый пароль',
|
| 292 |
+
'min': 'мин',
|
| 293 |
+
'chars': 'символов',
|
| 294 |
+
'Type a new password': 'Введите новый пароль',
|
| 295 |
+
'Show the password back to me after submit': 'Показать мне пароль после отправки',
|
| 296 |
+
'Change plan': 'Изменить тариф',
|
| 297 |
+
'Current plan': 'Текущий тариф',
|
| 298 |
+
'Quick presets': 'Быстрые пресеты',
|
| 299 |
+
'Apply preset »{name}« to {user}?': 'Применить пресет «{name}» к {user}?',
|
| 300 |
+
'Suspend user': 'Приостановить пользователя',
|
| 301 |
+
'Reason (optional, audit-logged)': 'Причина (необязательно, пишется в аудите)',
|
| 302 |
+
'Reason': 'Причина',
|
| 303 |
+
'e.g. non-payment / abuse / testing': 'напр. неоплата / злоупотребление / тестирование',
|
| 304 |
+
'Cancel': 'Отмена',
|
| 305 |
+
'You cannot suspend your own admin account': 'Нельзя приостановить собственный админ-аккаунт',
|
| 306 |
+
'Save plan': 'Сохранить тариф',
|
| 307 |
+
'over plan': 'выше тарифа',
|
| 308 |
+
'Traffic — last 24h': 'Трафик — за ��оследние 24 ч',
|
| 309 |
+
'min)': 'мин)',
|
| 310 |
+
'select none — only one user': 'ничего не выбрано — только один пользователь',
|
| 311 |
+
'at plan cap': 'достигнут лимит тарифа',
|
| 312 |
+
'at cap': 'лимит',
|
| 313 |
+
'Ask AI': 'Спросить ИИ',
|
| 314 |
+
'Ask the panel assistant': 'Спросить ассистента панели',
|
| 315 |
+
'Open AI assistant': 'Открыть ИИ-ассистента',
|
| 316 |
+
'Panel assistant': 'Ассистент панели',
|
| 317 |
+
'Powered by NVIDIA Nemotron': 'Работает на NVIDIA Nemotron',
|
| 318 |
+
'Ask me about bots, deploys, logs — or just say “what does this panel do?”.': 'Спрашивайте про ботов, деплои, логи — или просто скажите: «что вообще делает эта панель?».',
|
| 319 |
+
'Try:': 'Попробуйте:',
|
| 320 |
+
'how do I deploy a bot?': 'как задеплоить бота?',
|
| 321 |
+
'what to check when a bot is in ERROR?': 'что проверить, если бот в ERROR?',
|
| 322 |
+
'explain the quota system': 'объясни систему квот',
|
| 323 |
+
'Ask anything… (Enter — send, Shift+Enter — newline, Esc — close)': 'Спросите что угодно… (Enter — отправить, Shift+Enter — новая строка, Esc — закрыть)',
|
| 324 |
})
|
| 325 |
|
| 326 |
|
templates_setup.py
CHANGED
|
@@ -16,6 +16,8 @@ always receives the active render context (containing the request).
|
|
| 16 |
"""
|
| 17 |
from __future__ import annotations
|
| 18 |
|
|
|
|
|
|
|
| 19 |
from fastapi.templating import Jinja2Templates
|
| 20 |
from jinja2 import pass_context
|
| 21 |
|
|
|
|
| 16 |
"""
|
| 17 |
from __future__ import annotations
|
| 18 |
|
| 19 |
+
from typing import Any
|
| 20 |
+
|
| 21 |
from fastapi.templating import Jinja2Templates
|
| 22 |
from jinja2 import pass_context
|
| 23 |
|