128 lines
4.5 KiB
Python
128 lines
4.5 KiB
Python
import asyncio
|
|
from aiogram import F
|
|
from aiogram.types import Message
|
|
from app import dp, cfg
|
|
from auth import is_admin_msg
|
|
from keyboards import docker_kb, arcane_kb
|
|
from services.arcane import list_projects, restart_project, set_project_state
|
|
from datetime import datetime
|
|
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery
|
|
|
|
|
|
def _arcane_cfg():
|
|
arc = cfg.get("arcane", {})
|
|
return arc.get("base_url"), arc.get("api_key"), int(arc.get("env_id", 0))
|
|
|
|
|
|
async def cmd_arcane_projects(msg: Message, *, edit: bool):
|
|
base_url, api_key, env_id = _arcane_cfg()
|
|
if not base_url or not api_key:
|
|
await msg.answer("⚠️ Arcane config missing", reply_markup=docker_kb)
|
|
return
|
|
|
|
if edit:
|
|
await msg.edit_text("⏳ Arcane projects…")
|
|
else:
|
|
await msg.answer("⏳ Arcane projects…", reply_markup=arcane_kb)
|
|
|
|
async def worker():
|
|
ok, info, items = await asyncio.to_thread(list_projects, base_url, api_key, env_id)
|
|
if not ok:
|
|
await msg.answer(f"❌ Arcane error: {info}", reply_markup=arcane_kb)
|
|
return
|
|
|
|
ts = datetime.now().strftime("%d.%m.%Y %H:%M:%S")
|
|
lines = [f"🧰 Arcane projects на {ts}\n"]
|
|
rows = []
|
|
for p in items:
|
|
status = p.get("status", "unknown")
|
|
name = p.get("name", "?")
|
|
pid = p.get("id", "")
|
|
running = p.get("runningCount", 0)
|
|
total = p.get("serviceCount", 0)
|
|
icon = "🟢" if status == "running" else "🟡"
|
|
lines.append(f"{icon} {name}: {status} ({running}/{total})")
|
|
if pid:
|
|
rows.append([
|
|
InlineKeyboardButton(text=f"🔄 {name}", callback_data=f"arcane:restart:{pid}"),
|
|
InlineKeyboardButton(text="▶️", callback_data=f"arcane:up:{pid}"),
|
|
InlineKeyboardButton(text="⏹", callback_data=f"arcane:down:{pid}"),
|
|
])
|
|
|
|
kb_inline = InlineKeyboardMarkup(inline_keyboard=rows) if rows else None
|
|
if edit:
|
|
await msg.edit_text("\n".join(lines), reply_markup=kb_inline)
|
|
else:
|
|
await msg.answer("\n".join(lines), reply_markup=kb_inline or arcane_kb)
|
|
|
|
asyncio.create_task(worker())
|
|
|
|
|
|
@dp.message(F.text == "🧰 Arcane")
|
|
async def arcane_menu(msg: Message):
|
|
if is_admin_msg(msg):
|
|
await cmd_arcane_projects(msg, edit=False)
|
|
|
|
|
|
@dp.message(F.text == "🔄 Refresh")
|
|
async def arcane_refresh(msg: Message):
|
|
if is_admin_msg(msg):
|
|
await cmd_arcane_projects(msg, edit=True)
|
|
|
|
|
|
@dp.callback_query(F.data.startswith("arcane:restart:"))
|
|
async def arcane_restart(cb: CallbackQuery):
|
|
if cb.from_user.id != cfg["telegram"]["admin_id"]:
|
|
return
|
|
|
|
_, _, pid = cb.data.split(":", 2)
|
|
base_url, api_key, env_id = _arcane_cfg()
|
|
if not base_url or not api_key:
|
|
await cb.answer("Arcane config missing")
|
|
return
|
|
|
|
await cb.answer("Restarting…")
|
|
ok, info = await asyncio.to_thread(restart_project, base_url, api_key, env_id, pid)
|
|
if ok:
|
|
await cb.message.answer("✅ Arcane restart triggered", reply_markup=arcane_kb)
|
|
else:
|
|
await cb.message.answer(f"❌ Arcane restart failed: {info}", reply_markup=arcane_kb)
|
|
|
|
|
|
@dp.callback_query(F.data.startswith("arcane:up:"))
|
|
async def arcane_up(cb: CallbackQuery):
|
|
if cb.from_user.id != cfg["telegram"]["admin_id"]:
|
|
return
|
|
|
|
_, _, pid = cb.data.split(":", 2)
|
|
base_url, api_key, env_id = _arcane_cfg()
|
|
if not base_url or not api_key:
|
|
await cb.answer("Arcane config missing")
|
|
return
|
|
|
|
await cb.answer("Starting…")
|
|
ok, info = await asyncio.to_thread(set_project_state, base_url, api_key, env_id, pid, "up")
|
|
if ok:
|
|
await cb.message.answer("✅ Arcane up triggered", reply_markup=arcane_kb)
|
|
else:
|
|
await cb.message.answer(f"❌ Arcane up failed: {info}", reply_markup=arcane_kb)
|
|
|
|
|
|
@dp.callback_query(F.data.startswith("arcane:down:"))
|
|
async def arcane_down(cb: CallbackQuery):
|
|
if cb.from_user.id != cfg["telegram"]["admin_id"]:
|
|
return
|
|
|
|
_, _, pid = cb.data.split(":", 2)
|
|
base_url, api_key, env_id = _arcane_cfg()
|
|
if not base_url or not api_key:
|
|
await cb.answer("Arcane config missing")
|
|
return
|
|
|
|
await cb.answer("Stopping…")
|
|
ok, info = await asyncio.to_thread(set_project_state, base_url, api_key, env_id, pid, "down")
|
|
if ok:
|
|
await cb.message.answer("✅ Arcane down triggered", reply_markup=arcane_kb)
|
|
else:
|
|
await cb.message.answer(f"❌ Arcane down failed: {info}", reply_markup=arcane_kb)
|