2026-05-10 09:08:12 +02:00
|
|
|
import logging
|
2026-05-23 05:44:04 +02:00
|
|
|
from typing import Annotated
|
2026-05-14 04:12:19 +02:00
|
|
|
from datetime import datetime, timezone
|
2026-05-23 05:44:04 +02:00
|
|
|
from fastapi import APIRouter, Request, Form
|
2026-05-10 09:08:12 +02:00
|
|
|
from fastapi.responses import RedirectResponse
|
2026-05-23 08:34:13 +02:00
|
|
|
from devplacepy.database import get_table, update_target_stars, get_target_owner_uid
|
|
|
|
|
from devplacepy.utils import generate_uid, require_user, create_notification
|
2026-05-23 05:44:04 +02:00
|
|
|
from devplacepy.models import VoteForm
|
2026-05-10 09:08:12 +02:00
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
2026-05-23 08:34:13 +02:00
|
|
|
NOTIFY_ON_VOTE: set[str] = {"post", "comment", "gist", "project"}
|
|
|
|
|
|
2026-05-10 09:08:12 +02:00
|
|
|
|
|
|
|
|
@router.post("/{target_type}/{target_uid}")
|
2026-05-23 05:44:04 +02:00
|
|
|
async def vote(request: Request, target_type: str, target_uid: str, data: Annotated[VoteForm, Form()]):
|
2026-05-10 09:08:12 +02:00
|
|
|
user = require_user(request)
|
2026-05-23 05:44:04 +02:00
|
|
|
value = data.value
|
2026-05-10 09:08:12 +02:00
|
|
|
|
|
|
|
|
votes = get_table("votes")
|
|
|
|
|
existing = votes.find_one(user_uid=user["uid"], target_uid=target_uid, target_type=target_type)
|
|
|
|
|
|
|
|
|
|
if existing:
|
|
|
|
|
if int(existing["value"]) == value:
|
|
|
|
|
votes.delete(id=existing["id"])
|
|
|
|
|
else:
|
|
|
|
|
votes.update({"id": existing["id"], "value": value}, ["id"])
|
|
|
|
|
else:
|
|
|
|
|
votes.insert({
|
|
|
|
|
"uid": generate_uid(),
|
|
|
|
|
"user_uid": user["uid"],
|
|
|
|
|
"target_uid": target_uid,
|
|
|
|
|
"target_type": target_type,
|
|
|
|
|
"value": value,
|
2026-05-14 04:12:19 +02:00
|
|
|
"created_at": datetime.now(timezone.utc).isoformat(),
|
2026-05-10 09:08:12 +02:00
|
|
|
})
|
|
|
|
|
|
2026-05-23 06:20:27 +02:00
|
|
|
up_count = votes.count(target_uid=target_uid, value=1)
|
|
|
|
|
down_count = votes.count(target_uid=target_uid, value=-1)
|
2026-05-12 12:45:52 +02:00
|
|
|
net = up_count - down_count
|
2026-05-10 09:08:12 +02:00
|
|
|
|
2026-05-23 08:34:13 +02:00
|
|
|
update_target_stars(target_type, target_uid, net)
|
2026-05-12 12:45:52 +02:00
|
|
|
|
2026-05-23 08:34:13 +02:00
|
|
|
if value == 1 and target_type in NOTIFY_ON_VOTE:
|
|
|
|
|
owner_uid = get_target_owner_uid(target_type, target_uid)
|
|
|
|
|
if owner_uid and owner_uid != user["uid"]:
|
|
|
|
|
create_notification(owner_uid, "vote", f"{user['username']} ++'d your {target_type}", user["uid"])
|
2026-05-10 09:08:12 +02:00
|
|
|
|
|
|
|
|
referer = request.headers.get("Referer", "/feed")
|
|
|
|
|
return RedirectResponse(url=referer, status_code=302)
|