Added Moderation ratings

This commit is contained in:
Mawoka
2023-08-01 17:44:30 +02:00
parent b5d5dab2f4
commit 6a277cdf9f
14 changed files with 353 additions and 101 deletions
+2
View File
@@ -33,6 +33,7 @@ from classquiz.routers import (
box_controller,
quiztivity,
pixabay,
moderation,
)
from classquiz.socket_server import sio
from classquiz.helpers import meilisearch_init, telemetry_ping
@@ -77,6 +78,7 @@ async def auth_middleware_wrapper(request: Request, call_next):
return await rememberme_middleware(request, call_next)
app.include_router(moderation.router, tags=["moderation"], prefix="/api/v1/moderation", include_in_schema=True)
app.include_router(pixabay.router, tags=["pixabay"], prefix="/api/v1/pixabay", include_in_schema=True)
app.include_router(quiztivity.router, tags=["quiztivity"], prefix="/api/v1/quiztivity", include_in_schema=True)
+17
View File
@@ -128,6 +128,23 @@ async def get_current_user(token: str = Depends(oauth2_scheme)):
return user
async def get_current_moderator(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, settings.secret_key, algorithms=[ALGORITHM])
email: str = payload.get("sub")
if email is None:
raise credentials_exception
token_data = TokenData(email=email)
except JWTError:
raise credentials_exception
user = await get_user_from_mail(email=token_data.email)
if user is None:
raise credentials_exception
if user.username not in settings.mods:
raise credentials_exception
return user
async def get_admin_user(token: str = Depends(oauth2_scheme)) -> User:
user = await get_current_user(token)
admin_user = await User.objects.order_by(User.created_at.asc()).get()
+1
View File
@@ -53,6 +53,7 @@ class Settings(BaseSettings):
telemetry_enabled: bool = True
free_storage_limit: int = 1074000000
pixabay_api_key: str | None = None
mods: list[str] = []
# storage_backend
storage_backend: str | None = "local"
+1
View File
@@ -184,6 +184,7 @@ class Quiz(ormar.Model):
dislikes: int = ormar.Integer(nullable=False, default=0, server_default="0")
plays: int = ormar.Integer(nullable=False, default=0, server_default="0")
views: int = ormar.Integer(nullable=False, default=0, server_default="0")
mod_rating: int | None = ormar.SmallInteger(nullable=True)
class Meta:
tablename = "quiz"
+1
View File
@@ -170,6 +170,7 @@ async def handle_import_from_excel(data: BinaryIO, user: User) -> Quiz:
else:
existing_quiz.questions = [*existing_quiz.questions, *questions]
existing_quiz.updated_at = datetime.now()
existing_quiz.mod_rating = None
await existing_quiz.update()
quiz = existing_quiz
return quiz
+1
View File
@@ -129,6 +129,7 @@ async def finish_edit(edit_id: str, quiz_input: QuizInput):
quiz.cover_image = quiz_input.cover_image
quiz.background_color = quiz_input.background_color
quiz.background_image = quiz_input.background_image
quiz.mod_rating = None
for image in images_to_delete:
if image is not None:
try:
+1
View File
@@ -128,5 +128,6 @@ async def import_quiz(file: UploadFile = File(), user: User = Depends(get_curren
quiz = Quiz.parse_obj(quiz_dict)
quiz.user_id = user.id
quiz.imported_from_kahoot = None
quiz.mod_rating = None
await quiz.save()
return quiz
+61
View File
@@ -0,0 +1,61 @@
# SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
#
# SPDX-License-Identifier: MPL-2.0
import uuid
from fastapi import APIRouter, Depends, Response, HTTPException
from pydantic import BaseModel
from classquiz.auth import get_current_moderator
from classquiz.db.models import User, Quiz
router = APIRouter()
@router.get("/status")
async def get_mod_status(resp: Response, user: User = Depends(get_current_moderator)):
resp.status_code = 200
resp.set_cookie("moderator", "yes", path="/")
resp.headers.update({"Content-Type": "application/json"})
resp.body = '{"status": "ok"}'
return resp
@router.get("/quizzes")
async def get_newest_quizzes(
page: int = 1, all: bool = False, user: User = Depends(get_current_moderator)
) -> list[Quiz]:
if page < 1:
raise HTTPException(status_code=400, detail="page 1 is the first")
if all:
quizzes = (
await Quiz.objects.paginate(page=page)
.order_by(Quiz.updated_at.desc())
.filter(Quiz.public == True) # noqa: E712
.all()
)
else:
# noinspection PyComparisonWithNone
quizzes = (
await Quiz.objects.paginate(page=page)
.order_by(Quiz.updated_at.desc())
.filter(Quiz.public == True) # noqa: E712
.filter(Quiz.mod_rating == None) # noqa: E711
.all()
)
return quizzes
class SetModRatingForQuizInput(BaseModel):
rating: int | None
@router.post("/rating/set/{quiz_id}")
async def set_mod_rating_for_quiz(
data: SetModRatingForQuizInput, quiz_id: uuid.UUID, user: User = Depends(get_current_moderator)
) -> Quiz:
quiz = await Quiz.objects.get_or_none(public=True, id=quiz_id)
if quiz is None:
raise HTTPException(status_code=404, detail="Quiz not found")
quiz.mod_rating = data.rating
return await quiz.update()