✨ Added Ratins, Plays and Views to Quizzes
This commit is contained in:
@@ -180,6 +180,10 @@ class Quiz(ormar.Model):
|
||||
background_color: str | None = ormar.Text(nullable=True, unique=False)
|
||||
background_image: str | None = ormar.Text(nullable=True, unique=False)
|
||||
kahoot_id: uuid.UUID | None = ormar.UUID(nullable=True, default=None)
|
||||
likes: int = ormar.Integer(nullable=False, default=0, server_default="0")
|
||||
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")
|
||||
|
||||
class Meta:
|
||||
tablename = "quiz"
|
||||
@@ -472,3 +476,16 @@ class Controller(ormar.Model):
|
||||
tablename = "controller"
|
||||
metadata = metadata
|
||||
database = database
|
||||
|
||||
|
||||
class Rating(ormar.Model):
|
||||
id: uuid.UUID = ormar.UUID(primary_key=True)
|
||||
user: uuid.UUID | User = ormar.ForeignKey(User)
|
||||
positive: bool = ormar.Boolean(nullable=False)
|
||||
created_at: datetime = ormar.DateTime(nullable=False, server_default=func.now())
|
||||
quiz: uuid.UUID | Quiz = ormar.ForeignKey(Quiz)
|
||||
|
||||
class Meta:
|
||||
tablename = "rating"
|
||||
metadata = metadata
|
||||
database = database
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
# SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
|
||||
#
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
import enum
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from fastapi import APIRouter, HTTPException, Depends
|
||||
from uuid import UUID
|
||||
|
||||
from classquiz.db.models import User, Quiz
|
||||
from pydantic import BaseModel
|
||||
|
||||
from classquiz.auth import get_current_user
|
||||
from classquiz.db.models import User, Quiz, Rating
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@@ -35,3 +40,38 @@ async def get_quizzes_from_user(user_id: UUID, imported: bool | None = None):
|
||||
raise HTTPException(status_code=404, detail="no quizzes found")
|
||||
else:
|
||||
return quizzes
|
||||
|
||||
|
||||
class RateQuizInputType(str, enum.Enum):
|
||||
LIKE = "LIKE"
|
||||
DISLIKE = "DISLIKE"
|
||||
|
||||
|
||||
class RateQuizInput(BaseModel):
|
||||
type: RateQuizInputType
|
||||
|
||||
|
||||
@router.post("/rate/{quiz_id}")
|
||||
async def rate_quiz(data: RateQuizInput, quiz_id: uuid.UUID, user: User = Depends(get_current_user)):
|
||||
quiz = await Quiz.objects.get_or_none(id=quiz_id, public=True)
|
||||
if quiz is None:
|
||||
raise HTTPException(status_code=404, detail="Quiz not found")
|
||||
rating = await Rating.objects.get_or_none(quiz=quiz, user=user)
|
||||
positive = True
|
||||
if data.type == RateQuizInputType.DISLIKE:
|
||||
positive = False
|
||||
if rating is not None and rating.positive == positive:
|
||||
raise HTTPException(status_code=409, detail="Rating already submitted")
|
||||
elif rating.positive != positive:
|
||||
await rating.delete()
|
||||
if rating.positive:
|
||||
quiz.likes -= 1
|
||||
else:
|
||||
quiz.dislikes -= 1
|
||||
rating = Rating(id=uuid.uuid4(), user=user, positive=positive, quiz=quiz, created_at=datetime.now())
|
||||
await rating.save()
|
||||
if positive:
|
||||
quiz.likes += 1
|
||||
else:
|
||||
quiz.dislikes += 1
|
||||
await quiz.update()
|
||||
|
||||
@@ -56,18 +56,20 @@ class PublicQuizResponseUser(BaseModel):
|
||||
class PublicQuizResponse(Quiz.get_pydantic()):
|
||||
user_id: PublicQuizResponseUser
|
||||
questions: list[QuizQuestion]
|
||||
likes: int
|
||||
dislikes: int
|
||||
views: int
|
||||
plays: int
|
||||
|
||||
|
||||
@router.get("/get/public/{quiz_id}")
|
||||
async def get_public_quiz(quiz_id: str):
|
||||
try:
|
||||
quiz_id = uuid.UUID(quiz_id)
|
||||
except ValueError:
|
||||
raise HTTPException(status_code=400, detail="badly formed quiz id")
|
||||
async def get_public_quiz(quiz_id: uuid.UUID):
|
||||
quiz = await Quiz.objects.select_related("user_id").get_or_none(id=quiz_id)
|
||||
if quiz is None:
|
||||
return JSONResponse(status_code=404, content={"detail": "quiz not found"})
|
||||
else:
|
||||
quiz.views += 1
|
||||
await quiz.update()
|
||||
return PublicQuizResponse(**quiz.dict())
|
||||
|
||||
|
||||
@@ -89,6 +91,8 @@ async def start_quiz(
|
||||
quiz = await Quiz.objects.get_or_none(id=quiz_id, public=True)
|
||||
if quiz is None:
|
||||
return JSONResponse(status_code=404, content={"detail": "quiz not found"})
|
||||
quiz.plays += 1
|
||||
await quiz.update()
|
||||
game_pin = randint(100000, 999999)
|
||||
if custom_field == "":
|
||||
custom_field = None
|
||||
|
||||
Reference in New Issue
Block a user