bmc_hub/app/settings/backend/views.py
2026-01-28 10:47:29 +01:00

104 lines
3.2 KiB
Python

"""
Settings Frontend Views
"""
from datetime import datetime
from pathlib import Path
from fastapi import APIRouter, Request, HTTPException
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from pydantic import BaseModel
import os
import shutil
import subprocess
from app.core.config import settings
router = APIRouter()
templates = Jinja2Templates(directory="app")
@router.get("/settings", response_class=HTMLResponse, tags=["Frontend"])
async def settings_page(request: Request):
"""Render settings page"""
return templates.TemplateResponse("settings/frontend/settings.html", {
"request": request,
"title": "Indstillinger"
})
@router.get("/settings/migrations", response_class=HTMLResponse, tags=["Frontend"])
async def migrations_page(request: Request):
"""Render database migrations page"""
migrations_dir = Path(__file__).resolve().parents[3] / "migrations"
migrations = []
if migrations_dir.exists():
for migration_file in sorted(migrations_dir.glob("*.sql")):
stat = migration_file.stat()
migrations.append({
"name": migration_file.name,
"size_kb": round(stat.st_size / 1024, 1),
"modified": datetime.fromtimestamp(stat.st_mtime).strftime("%Y-%m-%d %H:%M")
})
return templates.TemplateResponse("settings/frontend/migrations.html", {
"request": request,
"title": "Database Migrationer",
"migrations": migrations,
"db_user": settings.POSTGRES_USER,
"db_name": settings.POSTGRES_DB,
"db_container": "bmc-hub-postgres"
})
class MigrationExecution(BaseModel):
file_name: str
@router.post("/settings/migrations/execute", tags=["Frontend"])
def execute_migration(payload: MigrationExecution):
"""Execute a migration SQL file"""
migrations_dir = Path(__file__).resolve().parents[3] / "migrations"
migration_file = migrations_dir / payload.file_name
if not migration_file.exists():
raise HTTPException(status_code=404, detail="Migration file not found")
# Determine the container runtime (Podman or Docker)
runtime_preference = (settings.CONTAINER_RUNTIME or "").strip().lower()
available_runtimes = [cmd for cmd in ("podman", "docker") if shutil.which(cmd)]
if not available_runtimes:
raise HTTPException(status_code=500, detail="No container runtime (docker/podman) found in PATH")
if runtime_preference and runtime_preference in available_runtimes:
runtime = runtime_preference
else:
runtime = available_runtimes[0]
command = [
runtime,
"exec",
"-i",
"bmc-hub-postgres",
"psql",
"-U",
settings.POSTGRES_USER,
"-d",
settings.POSTGRES_DB,
]
migration_sql = migration_file.read_text()
result = subprocess.run(
command,
input=migration_sql,
capture_output=True,
text=True,
env={**os.environ, "PGPASSWORD": settings.POSTGRES_PASSWORD},
)
if result.returncode != 0:
raise HTTPException(status_code=500, detail=f"Migration failed: {result.stderr}")
return {"message": "Migration executed successfully", "output": result.stdout}