feat: ordenar backups por cliente, generar codigos unicos de cliente UUID y soporte para compilar agente desde la web

This commit is contained in:
Carlos Tello
2026-08-17 00:00:03 -03:00
parent bdce625767
commit 7badc34816
4 changed files with 280 additions and 11 deletions
+87 -5
View File
@@ -1,7 +1,11 @@
import uuid
import sys
import subprocess
from pathlib import Path
from datetime import datetime, timedelta, timezone
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, status, Request
from fastapi import APIRouter, Depends, HTTPException, status, Request, BackgroundTasks
from fastapi.responses import FileResponse
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func, desc
@@ -99,10 +103,8 @@ async def register_client(
client.last_seen_at = now
client.is_active = True
else:
# Create a new Client
max_id_res = await db.execute(select(func.max(Client.id)))
max_id = max_id_res.scalar() or 0
client_code = f"CLIENT-{max_id + 1:04d}"
# Create a new Client with a unique generated client_code
client_code = f"CLI-{uuid.uuid4().hex[:8].upper()}"
# Load default client quota from settings
from app.services.settings_service import get_setting
@@ -356,3 +358,83 @@ async def delete_client(
)
return {"message": f"Client {client.client_code} deleted"}
# Global in-memory build state
BUILD_STATE = {
"status": "IDLE", # IDLE, BUILDING, SUCCESS, FAILED
"started_at": None,
"finished_at": None,
"error_message": None
}
def run_pyinstaller_build():
global BUILD_STATE
BUILD_STATE["status"] = "BUILDING"
BUILD_STATE["started_at"] = datetime.now(timezone.utc).isoformat()
BUILD_STATE["error_message"] = None
try:
# Cwd is workspace root
base_dir = Path(__file__).resolve().parent.parent.parent.parent
script_path = base_dir / "windows-agent" / "build_exe.py"
venv_python = base_dir / "backend" / "venv" / "Scripts" / "python.exe"
if not venv_python.exists():
venv_python = sys.executable
print(f"Starting PyInstaller compilation: {venv_python} {script_path}")
result = subprocess.run(
[str(venv_python), str(script_path)],
capture_output=True,
text=True,
cwd=str(base_dir / "windows-agent")
)
if result.returncode == 0:
BUILD_STATE["status"] = "SUCCESS"
else:
BUILD_STATE["status"] = "FAILED"
BUILD_STATE["error_message"] = result.stderr or result.stdout
except Exception as e:
BUILD_STATE["status"] = "FAILED"
BUILD_STATE["error_message"] = str(e)
finally:
BUILD_STATE["finished_at"] = datetime.now(timezone.utc).isoformat()
@router.post("/build-agent")
async def trigger_build_agent(
background_tasks: BackgroundTasks,
admin_user: User = Depends(require_admin)
):
global BUILD_STATE
if BUILD_STATE["status"] == "BUILDING":
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="A compilation is already in progress."
)
background_tasks.add_task(run_pyinstaller_build)
return {"message": "Compilation started in the background."}
@router.get("/build-agent/status")
async def get_build_agent_status(
current_user: User = Depends(get_current_user)
):
return BUILD_STATE
@router.get("/download-agent")
async def download_agent(
current_user: User = Depends(get_current_user)
):
base_dir = Path(__file__).resolve().parent.parent.parent.parent
exe_path = base_dir / "windows-agent" / "dist" / "OnEverDriveAgent-Standalone.exe"
if not exe_path.exists():
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Agent executable not found. Please compile it first."
)
return FileResponse(
path=str(exe_path),
filename="OnEverDriveAgent-Standalone.exe",
media_type="application/octet-stream"
)