109 lines
4.0 KiB
Python
109 lines
4.0 KiB
Python
from aiogram import F
|
||
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 <critical|warn|info>`\n"
|
||
"• `/alerts mute <cat> <minutes>` / `/alerts unmute <cat>` / `/alerts list`\n"
|
||
"• `/alerts recent [hours]`\n"
|
||
"Шорткаты: `/alerts_list`, `/alerts_recent`, `/alerts_mute_load` (60м).\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"
|
||
"Команды: `/docker_status`, `/docker_health <alias>`.\n\n"
|
||
"🖥 **System**\n"
|
||
"Info: Disks/Security/Metrics/Hardware/SMART/OpenWrt.\n"
|
||
"Ops: Updates/Upgrade/Reboot.\n"
|
||
"Logs: Audit/Incidents/Security/Integrations/Processes.\n"
|
||
"OpenWrt: `/openwrt`, `/openwrt_wan`, `/openwrt_clients`.",
|
||
),
|
||
(
|
||
"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", "/help"}))
|
||
async def help_cmd(msg: Message):
|
||
if not is_admin_msg(msg):
|
||
return
|
||
idx = 0
|
||
await msg.answer(
|
||
_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()
|