Game results can now be saved in db

This commit is contained in:
Mawoka
2023-01-29 18:16:05 +01:00
parent 3e61ecc8d4
commit a980c70d85
6 changed files with 256 additions and 21 deletions
+48 -19
View File
@@ -12,7 +12,17 @@ import socketio
from cryptography.fernet import Fernet
from classquiz.config import redis, settings
from classquiz.db.models import PlayGame, QuizQuestionType, GameSession, GamePlayer, QuizQuestion, VotingQuizAnswer
from classquiz.db.models import (
PlayGame,
QuizQuestionType,
GameSession,
GamePlayer,
QuizQuestion,
VotingQuizAnswer,
AnswerDataList,
AnswerData,
GameResults,
)
from pydantic import BaseModel, ValidationError, validator
from datetime import datetime
@@ -272,19 +282,6 @@ class _SubmitAnswerData(BaseModel):
complex_answer: list[_SubmitAnswerDataOrderType] | None
class _AnswerData(BaseModel):
username: str
answer: str
right: bool
time_taken: float # In milliseconds
score: int
class _AnswerDataList(BaseModel):
# Just a method to make a top-level list
__root__: list[_AnswerData]
@sio.event
async def submit_answer(sid: str, data: dict):
now = datetime.now()
@@ -360,9 +357,9 @@ async def submit_answer(sid: str, data: dict):
if answers is None:
await redis.set(
f"game_session:{session['game_pin']}:{data.question_index}",
_AnswerDataList(
AnswerDataList(
__root__=[
_AnswerData(
AnswerData(
username=session["username"],
answer=data.answer,
right=answer_right,
@@ -374,9 +371,9 @@ async def submit_answer(sid: str, data: dict):
ex=7200,
)
else:
answers = _AnswerDataList.parse_raw(answers)
answers = AnswerDataList.parse_raw(answers)
answers.__root__.append(
_AnswerData(
AnswerData(
username=session["username"],
answer=data.answer,
right=answer_right,
@@ -389,7 +386,7 @@ async def submit_answer(sid: str, data: dict):
answers.json(),
ex=7200,
)
answers = _AnswerDataList.parse_raw(await redis.get(f"game_session:{session['game_pin']}:{data.question_index}"))
answers = AnswerDataList.parse_raw(await redis.get(f"game_session:{session['game_pin']}:{data.question_index}"))
player_count = await redis.scard(f"game_session:{session['game_pin']}:players")
if len(answers.__root__) == player_count:
# await sio.emit(
@@ -510,3 +507,35 @@ async def set_control_visibility(sid: str, data: dict):
return
session: dict = await sio.get_session(sid)
await sio.emit("control_visibility", {"visible": data.visible}, room=f"admin:{session['game_pin']}")
@sio.event
async def save_quiz(sid: str):
session: dict = await sio.get_session(sid)
if not session["admin"]:
return
game_pin = session["game_pin"]
game = PlayGame.parse_raw(await redis.get(f"game:{game_pin}"))
player_count = await redis.scard(f"game_session:{game_pin}:players")
answers = []
for i in range(len(game.questions)):
print("hiqq", i)
redis_res = await redis.get(f"game_session:{game_pin}:{i}")
try:
answers.append(AnswerDataList.parse_raw(redis_res).dict())
except ValidationError:
answers.append([])
player_scores = await redis.hgetall(f"game_session:{game_pin}:player_scores")
custom_field_data = await redis.hgetall(f"game:{game_pin}:players:custom_fields")
print(custom_field_data)
data = GameResults(
id=game.game_id,
quiz_id=game.quiz_id,
user_id=game.user_id,
timestamp=datetime.now(),
player_count=player_count,
answers=json.dumps(answers),
player_scores=json.dumps(player_scores),
custom_field_data=json.dumps(custom_field_data),
)
await data.save()