From d4a19d309fc51a3136e546bbf98281f37c30a753 Mon Sep 17 00:00:00 2001 From: benya Date: Sun, 8 Feb 2026 22:52:40 +0300 Subject: [PATCH] Add multi-page inline help --- handlers/help.py | 105 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 93 insertions(+), 12 deletions(-) diff --git a/handlers/help.py b/handlers/help.py index 2ad3c78..56383fa 100644 --- a/handlers/help.py +++ b/handlers/help.py @@ -1,24 +1,105 @@ from aiogram import F -from aiogram.types import Message -from app import dp +from aiogram.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton +from app import dp, ADMIN_ID from auth import is_admin_msg from keyboards import menu_kb +HELP_PAGES = [ + ( + "Overview", + "ℹ️ **Help — Overview**\n\n" + "🩺 *Health* — быстрый health-check.\n" + "📊 *Статус* — общая загрузка.\n" + "📋 */status_short* — кратко (load/RAM/диски).\n" + "🩺 */health_short* — краткий health.\n" + "🔧 Разделы: Docker, Backup, Artifacts, System, OpenWrt.", + ), + ( + "Alerts", + "🚨 **Alerts & Mute**\n\n" + "Команды:\n" + "• `/alerts test `\n" + "• `/alerts mute ` / `/alerts unmute ` / `/alerts list`\n" + "• `/alerts recent [hours]`\n" + "Категории: load, disk, smart, ssl, docker, test.\n" + "Quiet hours: `alerts.quiet_hours` для не‑критичных.\n" + "Только красные load: `alerts.load_only_critical: true`.\n" + "Валидатор конфига: `/config_check`.", + ), + ( + "Backup", + "💾 **Backup (restic)**\n\n" + "Кнопки: Status, Last snapshot, Repo stats, Run backup, Queue, Restic check, Weekly report.\n" + "Run backup/Check учитывают `safety.dry_run`.\n" + "После бэкапа приходит TL;DR + путь к логу `/var/log/backup-auto.log`.\n" + "Queue → Details показывает отложенные задачи.", + ), + ( + "Docker & System", + "🐳 **Docker**\n" + "Status/Restart/Logs/Stats — клавиатура Docker.\n\n" + "🖥 **System**\n" + "Info: Disks/Security/Metrics/Hardware/SMART/OpenWrt.\n" + "Ops: Updates/Upgrade/Reboot.\n" + "Logs: Audit/Incidents/Security/Integrations/Processes.", + ), + ( + "Admin", + "🛠 **Admin & Deploy**\n\n" + "Config: `/config_check`, файл `config.yaml` (см. config.example.yaml).\n" + "Deploy: `deploy.sh` (ssh 10.10.10.10:1090 → git pull → systemctl restart tg-bot).\n" + "Безопасность: `safety.dry_run: true` блокирует опасные действия.\n" + "OpenWrt: кнопка в System → Info.", + ), +] + + +def _help_kb(idx: int) -> InlineKeyboardMarkup: + buttons = [] + if idx > 0: + buttons.append(InlineKeyboardButton(text="◀️ Prev", callback_data=f"help:{idx-1}")) + buttons.append(InlineKeyboardButton(text=f"{idx+1}/{len(HELP_PAGES)}", callback_data="help:noop")) + if idx < len(HELP_PAGES) - 1: + buttons.append(InlineKeyboardButton(text="Next ▶️", callback_data=f"help:{idx+1}")) + return InlineKeyboardMarkup(inline_keyboard=[buttons]) + + +def _help_text(idx: int) -> str: + _title, body = HELP_PAGES[idx] + return body + + @dp.message(F.text.in_({"ℹ️ Help", "ℹ Help", "Help"})) async def help_cmd(msg: Message): if not is_admin_msg(msg): return - + idx = 0 await msg.answer( - "ℹ️ **Help / Справка**\n\n" - "🩺 Health — быстрый health-check сервера\n" - "📊 Статус — общая загрузка сервера\n" - "🐳 Docker — управление контейнерами\n" - "📦 Backup — restic бэкапы\n" - "🧉 Artifacts — критичные образы (Clonezilla, NAND)\n" - "⚙️ System — подменю: Info / Ops / Logs\n\n" - "Inline-кнопки используются для выбора контейнеров.", - reply_markup=menu_kb, + _help_text(idx), + reply_markup=_help_kb(idx), parse_mode="Markdown", ) + + +@dp.callback_query(F.data.startswith("help:")) +async def help_cb(cb: CallbackQuery): + if cb.from_user.id != ADMIN_ID: + await cb.answer() + return + payload = cb.data.split(":", 1)[1] + if payload == "noop": + await cb.answer() + return + try: + idx = int(payload) + except ValueError: + await cb.answer() + return + idx = max(0, min(idx, len(HELP_PAGES) - 1)) + await cb.message.edit_text( + _help_text(idx), + reply_markup=_help_kb(idx), + parse_mode="Markdown", + ) + await cb.answer()