Added new range-answer type

This commit is contained in:
Mawoka
2022-07-09 23:02:59 +02:00
parent 10a2adb57e
commit 54e13077f7
24 changed files with 566 additions and 206 deletions
+24 -3
View File
@@ -7,7 +7,7 @@ from datetime import datetime
from typing import Optional
import ormar
from pydantic import BaseModel, Json
from pydantic import BaseModel, Json, validator
from enum import Enum
from . import metadata, database
@@ -62,17 +62,38 @@ class UserSession(ormar.Model):
database = database
class QuizAnswer(BaseModel):
class ABCDQuizAnswer(BaseModel):
right: bool
answer: str
class RangeQuizAnswer(BaseModel):
min: int
max: int
min_correct: int
max_correct: int
class QuizQuestionType(str, Enum):
ABCD = "ABCD"
RANGE = "RANGE"
class QuizQuestion(BaseModel):
question: str
time: str # in Secs
answers: list[QuizAnswer]
type: None | QuizQuestionType = QuizQuestionType.ABCD
answers: list[ABCDQuizAnswer] | RangeQuizAnswer
image: str | None = None
@validator("answers")
def answers_not_none_if_abcd_type(cls, v, values):
if values["type"] == QuizQuestionType.ABCD and len(v) == 0:
raise ValueError("Answers can't be none if type is ABCD")
if values["type"] == QuizQuestionType.RANGE and type(v) != RangeQuizAnswer:
raise ValueError("Answer must be from type RangeQuizAnswer if type is RANGE")
return v
class QuizInput(BaseModel):
public: bool = False
+3 -3
View File
@@ -10,7 +10,7 @@ from datetime import datetime
from aiohttp import ClientSession
from classquiz.config import settings, storage, meilisearch
from classquiz.db.models import Quiz, QuizAnswer, QuizQuestion, User
from classquiz.db.models import Quiz, ABCDQuizAnswer, QuizQuestion, User
from classquiz.kahoot_importer.get import get as get_quiz
from classquiz.helpers import get_meili_data
@@ -38,7 +38,7 @@ async def import_quiz(quiz_id: str, user: User) -> Quiz | str:
meilisearch.create_index(settings.meilisearch_index)
for q in quiz.kahoot.questions:
answers: list[QuizAnswer] = []
answers: list[ABCDQuizAnswer] = []
image = None
if q.image is not None and q.image != "":
image_bytes = await _download_image(q.image)
@@ -46,7 +46,7 @@ async def import_quiz(quiz_id: str, user: User) -> Quiz | str:
image = await storage.upload(file_name=image_name, file_data=image_bytes)
image = f"{settings.root_address}/api/v1/storage/download/{image_name}"
for a in q.choices:
answers.append((QuizAnswer(right=a.correct, answer=html.unescape(a.answer))))
answers.append((ABCDQuizAnswer(right=a.correct, answer=html.unescape(a.answer))))
quiz_questions.append(
QuizQuestion(
question=q.question,
+2 -2
View File
@@ -96,9 +96,9 @@ async def upload_image(edit_id: str, pow_data: str, file: UploadFile = File()):
if session_data is None:
raise HTTPException(status_code=401, detail="Edit ID not found!")
if uploaded_images == 0 and not check_hashcash(pow_data, pow_data_server, "16"):
if uploaded_images == 0 and not check_hashcash(pow_data, pow_data_server, "8"):
raise HTTPException(status_code=401, detail="Edit ID not found!")
if uploaded_images != 0 and not check_hashcash(pow_data, pow_data_server, "16"):
if uploaded_images != 0 and not check_hashcash(pow_data, pow_data_server, "8"):
raise HTTPException(status_code=401, detail="Edit ID not found!")
file_bytes = await file.read()
if len(file_bytes) < 2000:
+14 -4
View File
@@ -10,7 +10,7 @@ import socketio
from typing import Any
from classquiz.config import redis, settings
from classquiz.db.models import PlayGame
from classquiz.db.models import PlayGame, QuizQuestionType
from pydantic import BaseModel, ValidationError
sio = socketio.AsyncServer(async_mode="asgi", cors_allowed_origins=[])
@@ -188,10 +188,20 @@ async def submit_answer(sid: str, data: dict):
session = await sio.get_session(sid)
game_data = PlayGame.parse_raw(await redis.get(f"game:{session['game_pin']}"))
answer_right = False
for answer in game_data.questions[int(data.question_index)].answers:
if answer.answer == data.answer and answer.right:
if game_data.questions[int(data.question_index)].type == QuizQuestionType.ABCD:
for answer in game_data.questions[int(data.question_index)].answers:
if answer.answer == data.answer and answer.right:
answer_right = True
break
elif game_data.questions[int(data.question_index)].type == QuizQuestionType.RANGE:
if (
game_data.questions[int(data.question_index)].answers.min_correct
<= int(data.answer)
<= game_data.questions[int(data.question_index)].answers.max_correct
):
answer_right = True
break
else:
raise NotImplementedError
answers = await redis.get(f"game_session:{session['game_pin']}:{data.question_index}")
if answers is None:
await redis.set(