"""Log file endpoints — list, download, and delete historical RPT log files.""" from __future__ import annotations import logging from pathlib import Path from typing import Annotated from fastapi import APIRouter, Depends, HTTPException from fastapi.responses import FileResponse from sqlalchemy.engine import Connection from adapters.registry import GameAdapterRegistry from core.dal.server_repository import ServerRepository from database import get_db from dependencies import get_current_user, require_admin logger = logging.getLogger(__name__) router = APIRouter(prefix="/servers/{server_id}/logfiles", tags=["logfiles"]) def _ok(data): return {"success": True, "data": data, "error": None} def _get_rpt_parser(server_id: int, db: Connection): server = ServerRepository(db).get_by_id(server_id) if server is None: raise HTTPException(status_code=404, detail="Server not found") adapter = GameAdapterRegistry.get(server["game_type"]) if not adapter.has_capability("log_parser"): raise HTTPException(status_code=404, detail="Server does not support log files") # RPT files live next to the server exe (e.g. A3Master/server/*.rpt) exe_dir = Path(server["exe_path"]).parent return adapter.get_log_parser(), exe_dir @router.get("") def list_log_files( server_id: int, db: Annotated[Connection, Depends(get_db)], _user: Annotated[dict, Depends(get_current_user)], ) -> dict: parser, server_dir = _get_rpt_parser(server_id, db) files = parser.list_log_files(server_dir) return _ok(files) @router.get("/{filename}/download") def download_log_file( server_id: int, filename: str, db: Annotated[Connection, Depends(get_db)], _user: Annotated[dict, Depends(get_current_user)], ): parser, server_dir = _get_rpt_parser(server_id, db) path = parser.get_log_file_path(server_dir, filename) if path is None: raise HTTPException(status_code=404, detail="Log file not found") return FileResponse( path=str(path), filename=filename, media_type="text/plain", ) @router.delete("/{filename}") def delete_log_file( server_id: int, filename: str, db: Annotated[Connection, Depends(get_db)], _admin: Annotated[dict, Depends(require_admin)], ) -> dict: parser, server_dir = _get_rpt_parser(server_id, db) path = parser.get_log_file_path(server_dir, filename) if path is None: raise HTTPException(status_code=404, detail="Log file not found") try: path.unlink() except OSError as exc: raise HTTPException(status_code=500, detail=f"Could not delete file: {exc}") from exc return _ok({"message": f"{filename} deleted"})