|
# retoor <retoor@molodetz.nl>
|
|
|
|
import logging
|
|
from datetime import datetime, timezone
|
|
from typing import Annotated
|
|
|
|
from fastapi import APIRouter, Request
|
|
from devplacepy.database import get_blocked_uids, get_table
|
|
from devplacepy.database.awards import can_give_award, has_giver_cooldown, has_receiver_cooldown
|
|
from devplacepy.dependencies import json_or_form
|
|
from devplacepy.models import AwardGiveForm
|
|
from devplacepy.responses import action_result, json_error, wants_json
|
|
from devplacepy.services.audit import record as audit
|
|
from devplacepy.services.jobs import queue
|
|
from devplacepy.utils import generate_uid, make_combined_slug, require_user
|
|
|
|
logger = logging.getLogger(__name__)
|
|
router = APIRouter()
|
|
|
|
|
|
@router.post("/{username}/award")
|
|
async def give_award(
|
|
request: Request,
|
|
username: str,
|
|
data: Annotated[AwardGiveForm, json_or_form(AwardGiveForm)],
|
|
):
|
|
giver = require_user(request)
|
|
target = get_table("users").find_one(username=username)
|
|
redirect = f"/profile/{username}"
|
|
|
|
def deny(message: str, status: int = 400):
|
|
if wants_json(request):
|
|
return json_error(status, message)
|
|
return action_result(request, redirect, status_code=302)
|
|
|
|
if not target:
|
|
return deny("User not found", 404)
|
|
if target["uid"] == giver["uid"]:
|
|
return deny("You cannot give yourself an award")
|
|
blocked = get_blocked_uids(giver["uid"])
|
|
if target["uid"] in blocked:
|
|
return deny("You cannot give an award to a blocked user")
|
|
reverse_blocked = get_blocked_uids(target["uid"])
|
|
if giver["uid"] in reverse_blocked:
|
|
return deny("You cannot give an award to this user")
|
|
if has_giver_cooldown(giver["uid"]):
|
|
return deny("You can give another award later")
|
|
if has_receiver_cooldown(target["uid"]):
|
|
return deny("This user received an award recently")
|
|
if not (giver.get("api_key") or "").strip():
|
|
return deny("Your account has no API key for award generation")
|
|
|
|
description = data.description.strip()
|
|
uid = generate_uid()
|
|
slug = make_combined_slug(description, uid)
|
|
now = datetime.now(timezone.utc).isoformat()
|
|
get_table("awards").insert(
|
|
{
|
|
"uid": uid,
|
|
"slug": slug,
|
|
"description": description,
|
|
"giver_uid": giver["uid"],
|
|
"receiver_uid": target["uid"],
|
|
"attachment_uid_512": "",
|
|
"attachment_uid_256": "",
|
|
"attachment_uid_64": "",
|
|
"generated_at": None,
|
|
"created_at": now,
|
|
"job_uid": "",
|
|
"deleted_at": None,
|
|
"deleted_by": None,
|
|
}
|
|
)
|
|
job_uid = queue.enqueue(
|
|
"award",
|
|
{
|
|
"award_uid": uid,
|
|
"giver_uid": giver["uid"],
|
|
"receiver_uid": target["uid"],
|
|
"description": description,
|
|
"api_key": giver.get("api_key", ""),
|
|
},
|
|
"user",
|
|
giver["uid"],
|
|
)
|
|
get_table("awards").update({"uid": uid, "job_uid": job_uid}, ["uid"])
|
|
logger.info("%s gave award %s to %s", giver["username"], uid, username)
|
|
audit.record(
|
|
request,
|
|
"award.give",
|
|
user=giver,
|
|
target_type="user",
|
|
target_uid=target["uid"],
|
|
target_label=username,
|
|
summary=f"{giver['username']} gave award to {username}",
|
|
links=[
|
|
audit.target("user", target["uid"], username),
|
|
audit.target("award", uid, slug),
|
|
audit.job(job_uid),
|
|
],
|
|
)
|
|
return action_result(
|
|
request,
|
|
redirect,
|
|
data={"ok": True, "award_uid": uid, "award_slug": slug},
|
|
) |