import asyncio import json from datetime import datetime from pathlib import Path from aiogram import F from aiogram.types import Message from app import dp, ARTIFACT_STATE from auth import is_admin_msg from keyboards import artifacts_kb from lock_utils import acquire_lock, release_lock from services.artifacts import artifact_last from services.queue import enqueue from services.runner import run_cmd async def cmd_artifacts_status(msg: Message): p = Path(ARTIFACT_STATE) if not p.exists(): await msg.answer("❌ state.json не найден", reply_markup=artifacts_kb) return data = json.loads(p.read_text()) lines = [f"🧉 Artifacts ({len(data)})\n"] for name, info in data.items(): t = datetime.fromisoformat(info["updated_at"]) lines.append(f"• {name} — {t:%Y-%m-%d %H:%M}") await msg.answer("\n".join(lines), reply_markup=artifacts_kb) async def cmd_artifacts_last(msg: Message): p = Path(ARTIFACT_STATE) if not p.exists(): await msg.answer("❌ state.json не найден", reply_markup=artifacts_kb) return try: text = await asyncio.to_thread(artifact_last, ARTIFACT_STATE) except Exception as e: await msg.answer(f"❌ Last artifact failed: {type(e).__name__}: {e}", reply_markup=artifacts_kb) return await msg.answer(text, reply_markup=artifacts_kb) async def cmd_artifacts_upload(msg: Message): async def job(): if not acquire_lock("artifacts"): await msg.answer("⚠️ Upload уже идёт", reply_markup=artifacts_kb) return await msg.answer("📤 Upload…", reply_markup=artifacts_kb) try: rc, out = await run_cmd(["sudo", "/usr/local/bin/backup.py", "artifact-upload"], timeout=12 * 3600) await msg.answer(("✅ OK\n" if rc == 0 else "❌ FAIL\n") + out, reply_markup=artifacts_kb) finally: release_lock("artifacts") pos = await enqueue("artifact-upload", job) await msg.answer(f"🕓 Upload queued (#{pos})", reply_markup=artifacts_kb) @dp.message(F.text == "🧉 Status") async def ars(msg: Message): if is_admin_msg(msg): await cmd_artifacts_status(msg) @dp.message(F.text == "🧉 Last artifact") async def ala(msg: Message): if is_admin_msg(msg): await cmd_artifacts_last(msg) @dp.message(F.text == "📤 Upload") async def aru(msg: Message): if is_admin_msg(msg): await cmd_artifacts_upload(msg)