Split System menu into submenus
This commit is contained in:
@@ -4,7 +4,7 @@ from aiogram import F
|
||||
from aiogram.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton
|
||||
from app import dp, cfg
|
||||
from auth import is_admin_msg
|
||||
from keyboards import system_kb
|
||||
from keyboards import system_info_kb, system_ops_kb, system_logs_kb
|
||||
from system_checks import security, disks, hardware
|
||||
from services.http_checks import get_url_checks, check_url
|
||||
from services.queue import enqueue
|
||||
@@ -21,13 +21,13 @@ from services.incidents import read_recent, incidents_path
|
||||
@dp.message(F.text == "💽 Disks")
|
||||
async def sd(msg: Message):
|
||||
if is_admin_msg(msg):
|
||||
await msg.answer(disks(), reply_markup=system_kb)
|
||||
await msg.answer(disks(), reply_markup=system_info_kb)
|
||||
|
||||
|
||||
@dp.message(F.text == "🔐 Security")
|
||||
async def sec(msg: Message):
|
||||
if is_admin_msg(msg):
|
||||
await msg.answer(security(), reply_markup=system_kb)
|
||||
await msg.answer(security(), reply_markup=system_info_kb)
|
||||
|
||||
|
||||
@dp.message(F.text == "🌐 URLs")
|
||||
@@ -37,10 +37,10 @@ async def urls(msg: Message):
|
||||
|
||||
checks = list(get_url_checks(cfg))
|
||||
if not checks:
|
||||
await msg.answer("⚠️ Нет URL для проверки", reply_markup=system_kb)
|
||||
await msg.answer("⚠️ Нет URL для проверки", reply_markup=system_logs_kb)
|
||||
return
|
||||
|
||||
await msg.answer("⏳ Проверяю URL…", reply_markup=system_kb)
|
||||
await msg.answer("⏳ Проверяю URL…", reply_markup=system_logs_kb)
|
||||
|
||||
async def worker():
|
||||
tasks = [asyncio.to_thread(check_url, url) for _, url in checks]
|
||||
@@ -56,7 +56,7 @@ async def urls(msg: Message):
|
||||
reason = err or "error"
|
||||
lines.append(f"🔴 {alias}: {reason} ({ms}ms)")
|
||||
|
||||
await msg.answer("\n".join(lines), reply_markup=system_kb)
|
||||
await msg.answer("\n".join(lines), reply_markup=system_logs_kb)
|
||||
|
||||
asyncio.create_task(worker())
|
||||
|
||||
@@ -66,9 +66,9 @@ async def metrics(msg: Message):
|
||||
if not is_admin_msg(msg):
|
||||
return
|
||||
if state.METRICS_STORE is None:
|
||||
await msg.answer("⚠️ Metrics not initialized", reply_markup=system_kb)
|
||||
await msg.answer("⚠️ Metrics not initialized", reply_markup=system_info_kb)
|
||||
return
|
||||
await msg.answer(summarize(state.METRICS_STORE, minutes=15), reply_markup=system_kb)
|
||||
await msg.answer(summarize(state.METRICS_STORE, minutes=15), reply_markup=system_info_kb)
|
||||
|
||||
|
||||
@dp.message(F.text == "🧾 Audit")
|
||||
@@ -77,9 +77,9 @@ async def audit_log(msg: Message):
|
||||
return
|
||||
text = read_audit_tail(cfg, limit=200)
|
||||
if text.startswith("⚠️") or text.startswith("ℹ️"):
|
||||
await msg.answer(text, reply_markup=system_kb)
|
||||
await msg.answer(text, reply_markup=system_logs_kb)
|
||||
else:
|
||||
await msg.answer(text, reply_markup=system_kb, parse_mode="Markdown")
|
||||
await msg.answer(text, reply_markup=system_logs_kb, parse_mode="Markdown")
|
||||
|
||||
|
||||
@dp.message(F.text == "📣 Incidents")
|
||||
@@ -88,7 +88,7 @@ async def incidents(msg: Message):
|
||||
return
|
||||
path = incidents_path(cfg)
|
||||
if not os.path.exists(path):
|
||||
await msg.answer("⚠️ Incidents log not found", reply_markup=system_kb)
|
||||
await msg.answer("⚠️ Incidents log not found", reply_markup=system_logs_kb)
|
||||
return
|
||||
last_24h = read_recent(cfg, hours=24, limit=500)
|
||||
last_7d = read_recent(cfg, hours=24 * 7, limit=1000)
|
||||
@@ -102,7 +102,7 @@ async def incidents(msg: Message):
|
||||
"Recent (24h):\n"
|
||||
f"```\n{body}\n```"
|
||||
)
|
||||
await msg.answer(text, reply_markup=system_kb, parse_mode="Markdown")
|
||||
await msg.answer(text, reply_markup=system_logs_kb, parse_mode="Markdown")
|
||||
|
||||
|
||||
@dp.message(F.text == "🔒 SSL")
|
||||
@@ -110,7 +110,7 @@ async def ssl_certs(msg: Message):
|
||||
if not is_admin_msg(msg):
|
||||
return
|
||||
|
||||
await msg.answer("⏳ Checking SSL certificates…", reply_markup=system_kb)
|
||||
await msg.answer("⏳ Checking SSL certificates…", reply_markup=system_logs_kb)
|
||||
|
||||
async def worker():
|
||||
try:
|
||||
@@ -118,7 +118,7 @@ async def ssl_certs(msg: Message):
|
||||
text = format_certificates(certs)
|
||||
except Exception as e:
|
||||
text = f"⚠️ NPMplus error: {e}"
|
||||
await msg.answer(text, reply_markup=system_kb)
|
||||
await msg.answer(text, reply_markup=system_logs_kb)
|
||||
|
||||
asyncio.create_task(worker())
|
||||
|
||||
@@ -138,7 +138,7 @@ async def updates_list(msg: Message):
|
||||
await send_updates_page(msg, msg.from_user.id, 0, edit=False)
|
||||
|
||||
pos = await enqueue("pkg-updates", job)
|
||||
await msg.answer(f"🕓 Updates queued (#{pos})", reply_markup=system_kb)
|
||||
await msg.answer(f"🕓 Updates queued (#{pos})", reply_markup=system_ops_kb)
|
||||
|
||||
|
||||
@dp.message(F.text == "⬆️ Upgrade")
|
||||
@@ -172,7 +172,7 @@ async def reboot_request(msg: Message):
|
||||
@dp.message(F.text == "🧱 Hardware")
|
||||
async def hw(msg: Message):
|
||||
if is_admin_msg(msg):
|
||||
await msg.answer(hardware(), reply_markup=system_kb)
|
||||
await msg.answer(hardware(), reply_markup=system_info_kb)
|
||||
|
||||
|
||||
def _updates_kb(page: int, total_pages: int) -> InlineKeyboardMarkup:
|
||||
@@ -191,7 +191,7 @@ def _updates_kb(page: int, total_pages: int) -> InlineKeyboardMarkup:
|
||||
async def send_updates_page(msg: Message, user_id: int, page: int, edit: bool):
|
||||
data = UPDATES_CACHE.get(user_id)
|
||||
if not data:
|
||||
await msg.answer("⚠️ Updates cache empty", reply_markup=system_kb)
|
||||
await msg.answer("⚠️ Updates cache empty", reply_markup=system_ops_kb)
|
||||
return
|
||||
|
||||
lines = data["lines"]
|
||||
@@ -231,10 +231,10 @@ async def upgrade_confirm(cb: CallbackQuery):
|
||||
|
||||
async def job():
|
||||
text = await apply_updates()
|
||||
await cb.message.answer(text, reply_markup=system_kb, parse_mode="Markdown")
|
||||
await cb.message.answer(text, reply_markup=system_ops_kb, parse_mode="Markdown")
|
||||
|
||||
pos = await enqueue("pkg-upgrade", job)
|
||||
await cb.message.answer(f"🕓 Upgrade queued (#{pos})", reply_markup=system_kb)
|
||||
await cb.message.answer(f"🕓 Upgrade queued (#{pos})", reply_markup=system_ops_kb)
|
||||
|
||||
|
||||
@dp.callback_query(F.data == "upgrade:cancel")
|
||||
@@ -249,7 +249,7 @@ async def reboot_confirm(cb: CallbackQuery):
|
||||
return
|
||||
await cb.answer()
|
||||
REBOOT_PENDING[cb.from_user.id] = {}
|
||||
await cb.message.answer("🔐 Send reboot password", reply_markup=system_kb)
|
||||
await cb.message.answer("🔐 Send reboot password", reply_markup=system_ops_kb)
|
||||
|
||||
|
||||
@dp.callback_query(F.data == "reboot:cancel")
|
||||
@@ -266,16 +266,16 @@ async def reboot_password(msg: Message):
|
||||
|
||||
expected = cfg.get("security", {}).get("reboot_password")
|
||||
if not expected:
|
||||
await msg.answer("⚠️ Reboot password not configured", reply_markup=system_kb)
|
||||
await msg.answer("⚠️ Reboot password not configured", reply_markup=system_ops_kb)
|
||||
return
|
||||
|
||||
if (msg.text or "").strip() != expected:
|
||||
await msg.answer("❌ Wrong password", reply_markup=system_kb)
|
||||
await msg.answer("❌ Wrong password", reply_markup=system_ops_kb)
|
||||
return
|
||||
|
||||
async def job():
|
||||
await msg.answer("🔄 Rebooting…", reply_markup=system_kb)
|
||||
await msg.answer("🔄 Rebooting…", reply_markup=system_ops_kb)
|
||||
await run_cmd(["sudo", "reboot"], timeout=10)
|
||||
|
||||
pos = await enqueue("reboot", job)
|
||||
await msg.answer(f"🕓 Reboot queued (#{pos})", reply_markup=system_kb)
|
||||
await msg.answer(f"🕓 Reboot queued (#{pos})", reply_markup=system_ops_kb)
|
||||
|
||||
Reference in New Issue
Block a user