import re from fastapi import APIRouter, Depends, HTTPException, Request from sqlalchemy.orm import Session from pathlib import Path import subprocess from ..database import get_db from ..models import User from .auth import get_current_admin router = APIRouter(prefix="/api", tags=["optimizer_logs"]) PROJECT_ROOT = Path(__file__).parent.parent.parent.parent.parent @router.post("/optimizer/run") async def run_optimizer( request: Request, db: Session = Depends(get_db), current_user: User = Depends(get_current_admin) ): """ 触发合规优化器运行(管理员) """ try: body = await request.json() except Exception: raise HTTPException(status_code=400, detail="Invalid JSON") topic_id = body.get("topic_id") if not topic_id: raise HTTPException(status_code=400, detail="topic_id is required") script_path = PROJECT_ROOT / "automation" / "scripts" / "compliance_optimizer.py" if not script_path.exists(): raise HTTPException(status_code=500, detail="Optimizer script not found") try: result = subprocess.run( ["python", str(script_path), "--topic-id", topic_id], capture_output=True, text=True, timeout=600, cwd=PROJECT_ROOT ) if result.returncode != 0: raise HTTPException(status_code=500, detail=f"Optimizer failed: {result.stderr}") return {"ok": True, "message": "Optimization completed", "output": result.stdout} except subprocess.TimeoutExpired: raise HTTPException(status_code=500, detail="Optimizer timed out") @router.get("/logs") def get_logs( request: Request, type: str = None, # creator, optimizer, collector date: str = None, # YYYY-MM-DD db: Session = Depends(get_db), current_user: User = Depends(get_current_admin) ): """ 读取系统日志文件内容(管理员) """ if not type or not date: raise HTTPException(status_code=400, detail="type and date parameters are required") _ALLOWED_LOG_TYPES = {"creator", "collector", "optimizer", "sources", "metrics", "trends", "rank_tracker"} if type not in _ALLOWED_LOG_TYPES: raise HTTPException(status_code=400, detail=f"Invalid log type: {type}") if not re.match(r'^\d{4}-\d{2}-\d{2}$', date): raise HTTPException(status_code=400, detail="Invalid date format (expected YYYY-MM-DD)") logs_dir = PROJECT_ROOT / "automation" / "logs" filename = f"{type}_{date}.log" log_path = logs_dir / filename if not log_path.exists(): # 日志文件不存在返回空内容 return {"type": type, "date": date, "content": ""} try: content = log_path.read_text(encoding="utf-8") except Exception as e: raise HTTPException(status_code=500, detail=f"Failed to read log: {str(e)}") return {"type": type, "date": date, "content": content}