import json from aiogram import F from aiogram.types import CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton from app import dp, ADMIN_ID from services.docker import docker_cmd from state import DOCKER_MAP from handlers.backup import cmd_backup_status @dp.callback_query(F.data.startswith("docker:")) async def docker_callback(cb: CallbackQuery): if cb.from_user.id != ADMIN_ID: return _, action, alias = cb.data.split(":", 2) real = DOCKER_MAP[alias] if action == "restart": await cb.answer("Restarting…") rc, out = await docker_cmd(["restart", real]) await cb.message.answer( f"🔄 **{alias} restarted**\n```{out}```", parse_mode="Markdown" ) elif action == "logs": await cb.answer("Loading logs…") rc, out = await docker_cmd(["logs", "--tail", "80", real]) await cb.message.answer( f"📜 **Logs: {alias}**\n```{out}```", parse_mode="Markdown" ) @dp.callback_query(F.data.startswith("snap:")) async def snapshot_details(cb: CallbackQuery): if cb.from_user.id != ADMIN_ID: return snap_id = cb.data.split(":", 1)[1] await cb.answer("Loading snapshot…") # получаем статистику snapshot rc, raw = await run_cmd( ["restic", "stats", snap_id, "--json"], use_restic_env=True, timeout=20 ) if rc != 0: await cb.message.answer(raw) return stats = json.loads(raw) msg = ( f"🧉 **Snapshot {snap_id}**\n\n" f"📁 Files: {stats.get('total_file_count', 'n/a')}\n" f"💽 Size: {stats.get('total_size', 0) / (1024**3):.2f} GiB\n\n" "🧯 Restore:\n" f"`restic restore {snap_id} --target /restore`\n" ) back_kb = InlineKeyboardMarkup( inline_keyboard=[ [ InlineKeyboardButton( text="⬅️ Back to snapshots", callback_data="snapback" ) ] ] ) await cb.message.answer(msg, reply_markup=back_kb, parse_mode="Markdown") @dp.callback_query(F.data == "snapback") async def snapshot_back(cb: CallbackQuery): await cb.answer() # просто вызываем статус снова fake_msg = cb.message await cmd_backup_status(fake_msg)