84 lines
3.5 KiB
Python
Raw Normal View History

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-06-06 16:31:42 +02:00
from devplacepy.database import get_table, resolve_object_url, delete_engagement
2026-05-13 21:17:57 +02:00
from devplacepy.attachments import link_attachments, delete_target_attachments
2026-05-30 20:16:39 +02:00
from devplacepy.content import is_owner
from devplacepy.utils import generate_uid, require_user, create_mention_notifications, create_notification, award_rewards, XP_COMMENT
2026-05-23 05:44:04 +02:00
from devplacepy.models import CommentForm
2026-06-08 17:38:33 +02:00
from devplacepy.responses import action_result, wants_json, json_error
2026-05-10 09:08:12 +02:00
logger = logging.getLogger(__name__)
router = APIRouter()
@router.post("/create")
2026-05-23 05:44:04 +02:00
async def create_comment(request: Request, data: Annotated[CommentForm, Form()]):
2026-05-10 09:08:12 +02:00
user = require_user(request)
2026-05-23 05:44:04 +02:00
content = data.content.strip()
target_uid = data.target_uid or data.post_uid
target_type = data.target_type
parent_uid = data.parent_uid
2026-05-10 09:08:12 +02:00
2026-05-25 16:16:53 +02:00
redirect_url = resolve_object_url(target_type, target_uid)
2026-05-11 20:49:45 +02:00
2026-05-12 15:07:34 +02:00
comment_uid = generate_uid()
2026-05-11 20:49:45 +02:00
insert = {
2026-05-12 15:07:34 +02:00
"uid": comment_uid,
2026-05-11 20:49:45 +02:00
"target_uid": target_uid,
"target_type": target_type,
2026-05-10 09:08:12 +02:00
"user_uid": user["uid"],
"content": content,
"parent_uid": parent_uid or None,
2026-05-14 04:12:19 +02:00
"created_at": datetime.now(timezone.utc).isoformat(),
2026-05-11 20:49:45 +02:00
}
if target_type == "post":
insert["post_uid"] = target_uid
get_table("comments").insert(insert)
2026-05-10 09:08:12 +02:00
2026-05-23 05:44:04 +02:00
if data.attachment_uids:
link_attachments(data.attachment_uids, "comment", comment_uid)
2026-05-12 15:07:34 +02:00
2026-05-30 20:16:39 +02:00
award_rewards(user["uid"], XP_COMMENT, "First Comment")
2026-05-11 00:41:41 +02:00
2026-05-25 16:16:53 +02:00
comment_url = f"{redirect_url}#comment-{comment_uid}"
2026-05-11 20:49:45 +02:00
if target_type == "post":
2026-05-12 12:45:52 +02:00
if parent_uid:
2026-05-23 08:34:13 +02:00
parent = get_table("comments").find_one(uid=parent_uid)
2026-05-12 12:45:52 +02:00
if parent and parent["user_uid"] != user["uid"]:
2026-05-25 16:16:53 +02:00
create_notification(parent["user_uid"], "reply", f"{user['username']} replied to your comment", user["uid"], comment_url)
2026-05-12 12:45:52 +02:00
else:
posts = get_table("posts")
post = posts.find_one(uid=target_uid)
if not post:
post = posts.find_one(slug=target_uid)
if post and post["user_uid"] != user["uid"]:
2026-05-25 16:16:53 +02:00
create_notification(post["user_uid"], "comment", f"{user['username']} commented on your post", user["uid"], comment_url)
2026-05-10 09:08:12 +02:00
2026-05-25 16:16:53 +02:00
create_mention_notifications(content, user["uid"], comment_url)
2026-05-11 20:49:45 +02:00
logger.info(f"Comment by {user['username']} on {target_type} {target_uid}")
2026-06-08 17:38:33 +02:00
return action_result(request, comment_url, data={"uid": comment_uid, "url": comment_url})
2026-05-10 09:08:12 +02:00
@router.post("/delete/{comment_uid}")
async def delete_comment(request: Request, comment_uid: str):
user = require_user(request)
comments = get_table("comments")
comment = comments.find_one(uid=comment_uid)
2026-05-30 20:16:39 +02:00
if not is_owner(comment, user):
2026-06-08 17:38:33 +02:00
if wants_json(request):
return json_error(403, "Not allowed")
2026-05-11 20:49:45 +02:00
return RedirectResponse(url="/feed", status_code=302)
target_type = comment.get("target_type", "post")
target_uid = comment.get("target_uid") or comment.get("post_uid", "")
2026-05-13 21:17:57 +02:00
delete_target_attachments("comment", comment_uid)
2026-05-12 12:45:52 +02:00
get_table("votes").delete(target_uid=comment_uid, target_type="comment")
2026-06-06 16:31:42 +02:00
delete_engagement("comment", [comment_uid])
2026-05-11 20:49:45 +02:00
comments.delete(id=comment["id"])
logger.info(f"Comment {comment_uid} deleted by {user['username']}")
2026-05-25 16:16:53 +02:00
redirect_url = resolve_object_url(target_type, target_uid)
2026-06-08 17:38:33 +02:00
return action_result(request, redirect_url)