|
# 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 NotificationDefaultForm
|
|
from devplacepy.database import (
|
|
NOTIFICATION_TYPES,
|
|
NOTIFICATION_CHANNELS,
|
|
get_notification_default,
|
|
set_notification_default,
|
|
)
|
|
from devplacepy.utils import require_admin
|
|
from devplacepy.seo import base_seo_context, site_url, website_schema
|
|
from devplacepy.responses import respond, action_result, json_error
|
|
from devplacepy.schemas import AdminNotificationsOut
|
|
from devplacepy.services.audit import record as audit
|
|
from devplacepy.dependencies import json_or_form
|
|
|
|
logger = logging.getLogger(__name__)
|
|
router = APIRouter()
|
|
|
|
def _notification_defaults_view() -> list:
|
|
defaults = []
|
|
for entry in NOTIFICATION_TYPES:
|
|
defaults.append(
|
|
{
|
|
"key": entry["key"],
|
|
"label": entry["label"],
|
|
"description": entry["description"],
|
|
"in_app": get_notification_default(entry["key"], "in_app"),
|
|
"push": get_notification_default(entry["key"], "push"),
|
|
}
|
|
)
|
|
return defaults
|
|
|
|
@router.get("/notifications", response_class=HTMLResponse)
|
|
async def admin_notifications(request: Request):
|
|
admin = require_admin(request)
|
|
base = site_url(request)
|
|
seo_ctx = base_seo_context(
|
|
request,
|
|
title="Notifications - Admin",
|
|
description="Manage default notification settings for all users.",
|
|
robots="noindex,nofollow",
|
|
breadcrumbs=[
|
|
{"name": "Home", "url": "/feed"},
|
|
{"name": "Admin", "url": "/admin"},
|
|
{"name": "Notifications", "url": "/admin/notifications"},
|
|
],
|
|
schemas=[website_schema(base)],
|
|
)
|
|
return respond(
|
|
request,
|
|
"admin_notifications.html",
|
|
{
|
|
**seo_ctx,
|
|
"request": request,
|
|
"user": admin,
|
|
"notification_defaults": _notification_defaults_view(),
|
|
"admin_section": "notifications",
|
|
},
|
|
model=AdminNotificationsOut,
|
|
)
|
|
|
|
@router.post("/notifications")
|
|
async def admin_set_notification_default(
|
|
request: Request, data: Annotated[NotificationDefaultForm, Depends(json_or_form(NotificationDefaultForm))]
|
|
):
|
|
admin = require_admin(request)
|
|
valid_types = {entry["key"] for entry in NOTIFICATION_TYPES}
|
|
if data.notification_type not in valid_types or data.channel not in NOTIFICATION_CHANNELS:
|
|
return json_error(400, "Unknown notification type or channel")
|
|
set_notification_default(data.notification_type, data.channel, data.value)
|
|
logger.info(
|
|
f"Admin {admin['username']} set default {data.notification_type}/{data.channel} "
|
|
f"to {'on' if data.value else 'off'}"
|
|
)
|
|
audit.record(
|
|
request,
|
|
"admin.notification.default",
|
|
user=admin,
|
|
target_type="setting",
|
|
target_uid=f"notif_default_{data.notification_type}_{data.channel}",
|
|
old_value=0 if data.value else 1,
|
|
new_value=1 if data.value else 0,
|
|
summary=(
|
|
f"admin {admin['username']} set default {data.channel} "
|
|
f"{data.notification_type} notifications to {'on' if data.value else 'off'}"
|
|
),
|
|
metadata={"type": data.notification_type, "channel": data.channel},
|
|
)
|
|
return action_result(
|
|
request,
|
|
"/admin/notifications",
|
|
data={
|
|
"notification_type": data.notification_type,
|
|
"channel": data.channel,
|
|
"value": data.value,
|
|
},
|
|
)
|