Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions forum/models/comments.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ def insert(
anonymous: bool = False,
anonymous_to_peers: bool = False,
depth: int = 0,
abuse_flaggers: Optional[List[str]] = None,
historical_abuse_flaggers: Optional[List[str]] = None,
visible: bool = True,
) -> str:
"""
Inserts a new comment document into the database.
Expand All @@ -38,16 +41,24 @@ def insert(
anonymous (bool, optional): Whether the comment is posted anonymously. Defaults to False.
anonymous_to_peers (bool, optional): Whether the comment is anonymous to peers. Defaults to False.
depth (int, optional): The depth of the comment in the thread hierarchy. Defaults to 0.
abuse_flaggers (Optional[List[str]], optional): Users who flagged the comment. Defaults to None.
historical_abuse_flaggers (Optional[List[str]], optional): Users historically flagged the comment.
visible (bool, optional): Whether the comment is visible. Defaults to True.

Returns:
str: The ID of the inserted document.
"""
if abuse_flaggers is None:
abuse_flaggers = []
if historical_abuse_flaggers is None:
historical_abuse_flaggers = []

date = datetime.now()
comment_data = {
"votes": self.get_votes_dict(up=[], down=[]),
"visible": True,
"abuse_flaggers": [],
"historical_abuse_flaggers": [],
"visible": visible,
"abuse_flaggers": abuse_flaggers,
"historical_abuse_flaggers": historical_abuse_flaggers,
"parent_ids": [],
"at_position_list": [],
"body": body,
Expand Down Expand Up @@ -81,6 +92,7 @@ def update(
author_username: Optional[str] = None,
votes: Optional[Dict[str, int]] = None,
abuse_flaggers: Optional[List[str]] = None,
historical_abuse_flaggers: Optional[List[str]] = None,
endorsed: Optional[bool] = None,
child_count: Optional[int] = None,
depth: Optional[int] = None,
Expand All @@ -101,6 +113,7 @@ def update(
author_username (Optional[str], optional): The username of the author.
votes (Optional[Dict[str, int]], optional): The votes for the comment.
abuse_flaggers (Optional[List[str]], optional): A list of users who flagged the comment for abuse.
historical_abuse_flaggers (Optional[List[str]], optional): Users who historically flagged the comment.
endorsed (Optional[bool], optional): Whether the comment is endorsed.
child_count (Optional[int], optional): The number of child comments.
depth (Optional[int], optional): The depth of the comment in the thread hierarchy.
Expand All @@ -120,6 +133,7 @@ def update(
("author_username", author_username),
("votes", votes),
("abuse_flaggers", abuse_flaggers),
("historical_abuse_flaggers", historical_abuse_flaggers),
("endorsed", endorsed),
("child_count", child_count),
("depth", depth),
Expand Down
19 changes: 16 additions & 3 deletions forum/models/threads.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ def insert(
thread_type: str = "discussion",
context: str = "course",
pinned: bool = False,
visible: bool = True,
abuse_flaggers: Optional[List[str]] = None,
historical_abuse_flaggers: Optional[List[str]] = None,
) -> str:
"""
Inserts a new thread document into the database.
Expand All @@ -44,6 +47,9 @@ def insert(
thread_type (str, optional): The type of the thread, either 'question' or 'discussion'.
context (str, optional): The context of the thread, either 'course' or 'standalone'.
pinned (bool): Whether the thread is pinned. Defaults to False.
visible (bool): Whether the thread is visible. Defaults to True.
abuse_flaggers: A list of users who flagged the thread for abuse.
historical_abuse_flaggers: A list of users who historically flagged the thread for abuse.

Raises:
ValueError: If `thread_type` is not 'question' or 'discussion'.
Expand All @@ -54,15 +60,16 @@ def insert(
"""
if thread_type not in ["question", "discussion"]:
raise ValueError("Invalid thread_type")

if context not in ["course", "standalone"]:
raise ValueError("Invalid context")
if abuse_flaggers is None:
abuse_flaggers = []
if historical_abuse_flaggers is None:
historical_abuse_flaggers = []

date = datetime.now()
thread_data = {
"votes": self.get_votes_dict(up=[], down=[]),
"abuse_flaggers": [],
"historical_abuse_flaggers": [],
"thread_type": thread_type,
"context": context,
"comment_count": 0,
Expand All @@ -81,6 +88,9 @@ def insert(
"updated_at": date,
"last_activity_at": date,
"pinned": pinned,
"visible": visible,
"abuse_flaggers": abuse_flaggers,
"historical_abuse_flaggers": historical_abuse_flaggers,
}
result = self._collection.insert_one(thread_data)
return str(result.inserted_id)
Expand All @@ -102,6 +112,7 @@ def update(
author_username: Optional[str] = None,
votes: Optional[Dict[str, int]] = None,
abuse_flaggers: Optional[List[str]] = None,
historical_abuse_flaggers: Optional[List[str]] = None,
closed_by: Optional[str] = None,
pinned: Optional[bool] = None,
comments_count: Optional[int] = None,
Expand All @@ -126,6 +137,7 @@ def update(
author_username: The username of the author.
votes: The votes for the thread.
abuse_flaggers: A list of users who flagged the thread for abuse.
historical_abuse_flaggers: A list of users who historically flagged the thread for abuse.
closed_by: The ID of the user who closed the thread.
pinned: Whether the thread is pinned.
comments_count: The number of comments on the thread.
Expand All @@ -149,6 +161,7 @@ def update(
("author_username", author_username),
("votes", votes),
("abuse_flaggers", abuse_flaggers),
("historical_abuse_flaggers", historical_abuse_flaggers),
("closed_by", closed_by),
("pinned", pinned),
("comments_count", comments_count),
Expand Down
61 changes: 46 additions & 15 deletions forum/views/flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
from rest_framework.response import Response
from rest_framework.views import APIView

from forum.models import Contents, Users
from forum.models import Comment, CommentThread, Users
from forum.models.model_utils import (
flag_as_abuse,
un_flag_all_as_abuse,
un_flag_as_abuse,
)
from forum.serializers.contents import ContentSerializer
from forum.serializers.comment import UserCommentSerializer
from forum.serializers.thread import UserThreadSerializer


class CommentFlagAPIView(APIView):
Expand All @@ -38,24 +39,39 @@ def put(self, request: Request, comment_id: str, action: str) -> Response:
"""
request_data = request.data
user = Users().get(request_data["user_id"])
content = Contents().get(comment_id)
if not (user and content):
comment = Comment().get(comment_id)
if not (user and comment):
return Response(
{"error": "User / Comment doesn't exist"},
status=status.HTTP_400_BAD_REQUEST,
)
if action == "flag":
comment = flag_as_abuse(user, content)
updated_comment = flag_as_abuse(user, comment)
elif action == "unflag":
if request_data.get("all") and request_data.get("all") is True:
comment = un_flag_all_as_abuse(content)
updated_comment = un_flag_all_as_abuse(comment)
else:
comment = un_flag_as_abuse(user, content)
updated_comment = un_flag_as_abuse(user, comment)
else:
return Response(
{"error": "Invalid action"}, status=status.HTTP_400_BAD_REQUEST
)
serializer = ContentSerializer(comment)

if updated_comment is None:
return Response(
{"error": "Failed to update comment"},
status=status.HTTP_400_BAD_REQUEST,
)

context = {
"id": str(updated_comment["_id"]),
**updated_comment,
"user_id": user["_id"],
"username": user["username"],
"type": "comment",
"thread_id": str(updated_comment.get("comment_thread_id", None)),
}
serializer = UserCommentSerializer(context)
return Response(serializer.data, status=status.HTTP_200_OK)


Expand All @@ -82,23 +98,38 @@ def put(self, request: Request, thread_id: str, action: str) -> Response:
"""
request_data = request.data
user = Users().get(request_data["user_id"])
content = Contents().get(thread_id)
if not (user and content):
thread = CommentThread().get(thread_id)
if not (user and thread):
return Response(
{"error": "User / Comment doesn't exist"},
{"error": "User / Thread doesn't exist"},
status=status.HTTP_400_BAD_REQUEST,
)
if action == "flag":
thread = flag_as_abuse(user, content)
updated_thread = flag_as_abuse(user, thread)
elif action == "unflag":
if request_data.get("all"):
thread = un_flag_all_as_abuse(content)
updated_thread = un_flag_all_as_abuse(thread)
else:
thread = un_flag_as_abuse(user, content)
updated_thread = un_flag_as_abuse(user, thread)
else:
return Response(
{"error": "Invalid action"},
status=status.HTTP_400_BAD_REQUEST,
)
serializer = ContentSerializer(thread)

if updated_thread is None:
return Response(
{"error": "Failed to update thread"},
status=status.HTTP_400_BAD_REQUEST,
)

context = {
"id": str(updated_thread["_id"]),
**updated_thread,
"user_id": user["_id"],
"username": user["username"],
"type": "thread",
"thread_id": str(updated_thread.get("comment_thread_id", None)),
}
serializer = UserThreadSerializer(context)
return Response(serializer.data, status=status.HTTP_200_OK)
Loading