Skip to content
Open
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
3 changes: 2 additions & 1 deletion resources/consts.py → backend/consts.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""
# Resources / Consts

Constants used within the server, used to avoid buggy code
Constants used within the server, used to avoid buggy code when we refactor
things.
"""

MAIN_QUEUE = "Main"
Expand Down
55 changes: 40 additions & 15 deletions backend/models/post.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
# Backend / Models / Post
"""
from .tables import TComment, TPost, TPostReacts, TPostTags
from .tables import TComment, TPost, TPostReacts, TPostTags, TReport
from .user import User
from .tag import Tag
from .comment import Comment
Expand Down Expand Up @@ -178,13 +178,6 @@ def deleted(self) -> bool:
"""
return self.queue == Queue.get_deleted_queue()

@property
def reported(self) -> bool:
"""
Whether this post is reported or not
"""
return self.queue == Queue.get_reported_queue()

def _get(self) -> TPost:
"""
Return a reference to the underlying database row
Expand Down Expand Up @@ -425,13 +418,44 @@ def can_view_op(self, user: User) -> bool:
else:
return True

def reported_perspective(self, user: User) -> bool:
def report(self, user: User):
"""
Toggle whether the given user has reported the post
"""
if self.user_reported(user):
TReport.delete().where(
TReport.user == user.id
& TReport.post == self.id
).run_sync()
else:
TReport(user=user.id, post=self.id).save().run_sync()

def unreport(self):
"""
Returns whether the post should view as reported from the given user's
perspective. Only mods and admins should be able to view reported posts
by default.
Remove all reports of this post
"""
return self.reported and user.permissions.can(Permission.ViewReports)
TReport.delete().where(TReport.post == self.id).run_sync()

def user_reported(self, user: User) -> bool:
"""
Returns whether this user has reported the post
"""
return TReport.exists().where(
TReport.user == user.id
& TReport.post == self.id
).run_sync()

def report_count(self, user: User) -> int:
"""
Returns the report count, or zero if the given user doesn't have
permission to view reports
"""
if not user.permissions.can(Permission.ViewReports):
return 0
else:
return TReport.count().where(
TReport.post.id == self.id
).run_sync()

def basic_info(self, user: User) -> IPostBasicInfo:
"""
Expand All @@ -449,7 +473,7 @@ def basic_info(self, user: User) -> IPostBasicInfo:
"private": self.private,
"closed": self.closed,
"deleted": self.deleted,
"reported": self.reported_perspective(user),
"reported": self.report_count(user) > 0,
"anonymous": self.anonymous,
"answered": self.answered is not None,
}
Expand All @@ -474,7 +498,8 @@ def full_info(self, user: User) -> IPostFullInfo:
"anonymous": self.anonymous,
"closed": self.closed,
"deleted": self.deleted,
"reported": self.reported_perspective(user),
"report_count": self.report_count(user),
"user_reported": self.user_reported(user),
"user_reacted": self.has_reacted(user),
"answered": self.answered.id if self.answered else None,
"queue": self.queue.name
Expand Down
2 changes: 1 addition & 1 deletion backend/models/post_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from backend.util.validators import assert_valid_str_field
from backend.util import http_errors
from backend.types.queue import IQueueFullInfo, IQueueBasicInfo
from resources import consts
from backend import consts
from typing import cast, TYPE_CHECKING
from .user import User
if TYPE_CHECKING:
Expand Down
12 changes: 12 additions & 0 deletions backend/models/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,18 @@ class TNotification(_BaseTable):
"""Queue the notification is related to"""


class TReport(_BaseTable):
"""
Table mapping users to post reports
"""

user = ForeignKey(TUser)
"""User who made the report"""

post = ForeignKey(TPost)
"""Post that was reported"""


class TExamMode(_BaseTable):
"""
Table storing whether exam mode is on or off
Expand Down
7 changes: 2 additions & 5 deletions backend/routes/browse/post.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def report_post(user: User, *_):
user.permissions.assert_can(Permission.ReportPosts)
data = json.loads(request.data)
post = Post(data["post_id"])
post.queue = Queue.get_reported_queue()
post.report(user)

for u in User.all_where(
lambda u: u.permissions.can(Permission.ViewReports)
Expand All @@ -179,9 +179,6 @@ def unreport_post(user: User, *_):
user.permissions.assert_can(Permission.ViewReports)
data = json.loads(request.data)
post = Post(data["post_id"])
if post.answered is not None:
post.queue = Queue.get_answered_queue()
else:
post.queue = Queue.get_main_queue()
post.unreport()

return {}
8 changes: 6 additions & 2 deletions backend/types/post.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@ class IPostFullInfo(TypedDict):
* `anonymous` (`bool`):
* `closed` (`bool`):
* `deleted` (`bool`):
* `reported` (`bool`):
* `report_count` (`int`): the number of people who have reported the post,
or zero if the viewer doesn't have permission to view reports
* `user_reported` (`bool`): whether the user viewing the post has clicked
report
* `user_reacted` (`bool`):
* `answered` (`Optional[CommentId]`): ID of chosen answer if answered else
none
Expand All @@ -92,7 +95,8 @@ class IPostFullInfo(TypedDict):
anonymous: bool
closed: bool
deleted: bool
reported: bool
report_count: int
user_reported: bool
answered: Optional[CommentId]
queue: str

Expand Down
2 changes: 1 addition & 1 deletion backend/util/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

Code used to initialise the server
"""
from resources import consts
from backend import consts
from backend.types.auth import IAuthInfo
from backend.models.auth_config import AuthConfig
from backend.models.permissions import PermissionGroup, Permission
Expand Down
6 changes: 3 additions & 3 deletions ensemble_request/browse/post.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ def report(
"""
# PUT `/browse/post/report`

Report a post
Toggle whether a post has been reported

## Header
* `Authorization` (`str`): JWT of the user
Expand Down Expand Up @@ -368,8 +368,8 @@ def unreport(
"""
# PUT `/browse/post/unreport`

Un-report a post. This action should be taken by moderators if they find
that a report is invalid.
Remove all reports on a post. This action should be taken by moderators if
they find that a report is invalid.

## Header
* `Authorization` (`str`): JWT of the user
Expand Down
Empty file removed resources/__init__.py
Empty file.
2 changes: 1 addition & 1 deletion tests/integration/browse/comment/accept_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import pytest
from backend.util import http_errors
from ensemble_request import browse
from resources import consts
from backend import consts
from ensemble_request.taskboard import queue_post_list, queue_list
from tests.integration.helpers import get_queue
from tests.integration.conftest import IAllUsers, ISimpleUsers, IMakePosts
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/browse/comment/delete_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
post,
comment,
)
from resources import consts
from backend import consts
from ensemble_request.taskboard import queue_post_list, queue_list
from tests.integration.helpers import get_queue
from tests.integration.conftest import ISimpleUsers, IMakePosts
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/browse/post/close_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
un-closing sends it back to main queue
"""
import pytest
from resources import consts
from backend import consts
from backend.util import http_errors
from tests.integration.conftest import (
ISimpleUsers,
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/browse/post/report_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"""
import pytest
from backend.util import http_errors
from resources import consts
from backend import consts
from tests.integration.conftest import (
ISimpleUsers,
IBasicServerSetup,
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""
import pytest
from typing import TypedDict
from resources import consts
from backend import consts
from backend.types.identifiers import PostId, QueueId
from backend.types.permissions import IPermissionGroup
from backend.types.auth import IAuthInfo
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/taskboard/default_queue_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* All new posts are added to the default queue
"""
import pytest
from resources import consts
from backend import consts
from backend.util.http_errors import BadRequest
from tests.integration.helpers import get_queue
from ensemble_request.taskboard import (
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/taskboard/queue_post_add_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
IMakeQueues,
IMakePosts
)
from resources import consts
from backend import consts


def test_no_permission(
Expand Down