|
# retoor <retoor@molodetz.nl>
|
|
|
|
import logging
|
|
from typing import Annotated
|
|
from fastapi import Depends, APIRouter, Request
|
|
from fastapi.responses import HTMLResponse
|
|
from devplacepy.models import AdminSettingsForm
|
|
from devplacepy.database import get_table, clear_settings_cache
|
|
from devplacepy.utils import require_admin, generate_uid
|
|
from devplacepy.seo import base_seo_context, site_url, website_schema
|
|
from devplacepy.responses import respond, action_result
|
|
from devplacepy.schemas import AdminSettingsOut
|
|
from devplacepy.services.audit import record as audit
|
|
from devplacepy.dependencies import json_or_form
|
|
|
|
logger = logging.getLogger(__name__)
|
|
router = APIRouter()
|
|
|
|
CLEARABLE_SETTINGS = {"extra_head"}
|
|
|
|
@router.get("/settings", response_class=HTMLResponse)
|
|
async def admin_settings(request: Request):
|
|
admin = require_admin(request)
|
|
settings = get_table("site_settings")
|
|
all_settings = {s["key"]: s["value"] for s in settings.all()}
|
|
base = site_url(request)
|
|
seo_ctx = base_seo_context(
|
|
request,
|
|
title="Settings - Admin",
|
|
description="Manage DevPlace site settings.",
|
|
robots="noindex,nofollow",
|
|
breadcrumbs=[
|
|
{"name": "Home", "url": "/feed"},
|
|
{"name": "Admin", "url": "/admin"},
|
|
{"name": "Settings", "url": "/admin/settings"},
|
|
],
|
|
schemas=[website_schema(base)],
|
|
)
|
|
return respond(
|
|
request,
|
|
"admin_settings.html",
|
|
{
|
|
**seo_ctx,
|
|
"request": request,
|
|
"user": admin,
|
|
"settings": all_settings,
|
|
"admin_section": "settings",
|
|
},
|
|
model=AdminSettingsOut,
|
|
)
|
|
|
|
@router.post("/settings")
|
|
async def admin_settings_save(
|
|
request: Request, data: Annotated[AdminSettingsForm, Depends(json_or_form(AdminSettingsForm))]
|
|
):
|
|
admin = require_admin(request)
|
|
settings = get_table("site_settings")
|
|
changes = []
|
|
for key, value in data.model_dump().items():
|
|
existing = settings.find_one(key=key)
|
|
if existing:
|
|
if value == "" and key not in CLEARABLE_SETTINGS:
|
|
continue
|
|
old_value = existing.get("value")
|
|
if str(old_value) == str(value):
|
|
continue
|
|
settings.update({"id": existing["id"], "key": key, "value": value}, ["id"])
|
|
changes.append((key, old_value, value))
|
|
else:
|
|
settings.insert({"uid": generate_uid(), "key": key, "value": value})
|
|
changes.append((key, None, value))
|
|
clear_settings_cache()
|
|
logger.info(f"Admin {admin['username']} updated settings")
|
|
for key, old_value, new_value in changes:
|
|
audit.record(
|
|
request,
|
|
"admin.setting.update",
|
|
user=admin,
|
|
target_type="setting",
|
|
target_uid=key,
|
|
target_label=key,
|
|
old_value=old_value,
|
|
new_value=new_value,
|
|
summary=f"admin {admin['username']} updated setting {key}",
|
|
links=[audit.setting(key)],
|
|
)
|
|
return action_result(request, "/admin/settings")
|