Added Ratins, Plays and Views to Quizzes

This commit is contained in:
Mawoka
2023-06-30 20:40:18 +02:00
parent deac567e19
commit 99232b442d
11 changed files with 603 additions and 31 deletions
+17
View File
@@ -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
+43 -3
View File
@@ -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()
+9 -5
View File
@@ -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