From 6d0b88b56a7f6d5f1d606cb9d56292c8d68c7cb7 Mon Sep 17 00:00:00 2001
From: Mawoka
Date: Tue, 4 Oct 2022 20:04:08 +0200
Subject: [PATCH] :sparkles: Done!
---
classquiz/db/models.py | 1 +
classquiz/helpers/__init__.py | 11 ++++++-
classquiz/routers/quiz.py | 21 ++++++++++---
classquiz/socket_server/__init__.py | 7 ++++-
frontend/src/lib/dashboard/start_game.svelte | 9 ++++--
frontend/src/lib/play/join.svelte | 33 +++++++++++++++-----
6 files changed, 65 insertions(+), 17 deletions(-)
diff --git a/classquiz/db/models.py b/classquiz/db/models.py
index 829f867..496a46c 100644
--- a/classquiz/db/models.py
+++ b/classquiz/db/models.py
@@ -183,6 +183,7 @@ class PlayGame(BaseModel):
game_mode: str | None
current_question: int = -1
background_color: str | None
+ custom_field: str | None
class GamePlayer(BaseModel):
diff --git a/classquiz/helpers/__init__.py b/classquiz/helpers/__init__.py
index 28f9eb8..4474484 100644
--- a/classquiz/helpers/__init__.py
+++ b/classquiz/helpers/__init__.py
@@ -29,9 +29,18 @@ async def get_meili_data(quiz: Quiz) -> dict:
}
-async def generate_spreadsheet(quiz_results: dict, quiz: Quiz) -> BytesIO:
+async def generate_spreadsheet(quiz_results: dict, quiz: Quiz, player_fields: dict) -> BytesIO:
storage = BytesIO()
workbook = xlsxwriter.Workbook(storage, {"in_memory": True})
+ player_worksheet = workbook.add_worksheet()
+ player_worksheet.name = "Players"
+ player_worksheet.write(0, 0, "Username")
+ player_worksheet.write(0, 1, "Score")
+ player_worksheet.write(0, 2, "Custom-Field")
+ for i, player in enumerate(player_fields.keys()):
+ player_worksheet.write(i + 1, 0, player)
+ player_worksheet.write(i + 1, 2, player_fields[player])
+
worksheet = workbook.add_worksheet()
worksheet.name = "Questions"
worksheet.write(0, 0, "Question")
diff --git a/classquiz/routers/quiz.py b/classquiz/routers/quiz.py
index d63044a..24dd009 100644
--- a/classquiz/routers/quiz.py
+++ b/classquiz/routers/quiz.py
@@ -89,7 +89,11 @@ async def get_public_quiz(quiz_id: str):
@router.post("/start/{quiz_id}")
async def start_quiz(
- quiz_id: str, game_mode: str, captcha_enabled: bool = True, user: User = Depends(get_current_user)
+ quiz_id: str,
+ game_mode: str,
+ captcha_enabled: bool = True,
+ custom_field: str | None = None,
+ user: User = Depends(get_current_user),
):
try:
quiz_id = uuid.UUID(quiz_id)
@@ -101,6 +105,8 @@ async def start_quiz(
if quiz is None:
return JSONResponse(status_code=404, content={"detail": "quiz not found"})
game_pin = randint(10000000, 99999999)
+ if custom_field == "":
+ custom_field = None
game = PlayGame(
quiz_id=quiz_id,
game_pin=str(game_pin),
@@ -113,6 +119,7 @@ async def start_quiz(
game_mode=game_mode,
user_id=user.id,
background_color=quiz.background_color,
+ custom_field=custom_field,
)
await redis.set(f"game:{str(game.game_pin)}", game.json(), ex=18000)
await redis.set(f"game_pin:{user.id}:{quiz_id}", game_pin, ex=18000)
@@ -122,6 +129,7 @@ async def start_quiz(
class CheckIfCaptchaEnabledResponse(BaseModel):
enabled: bool
game_mode: str | None
+ custom_field: str | None
@router.get("/play/check_captcha/{game_pin}", response_model=CheckIfCaptchaEnabledResponse)
@@ -131,9 +139,9 @@ async def check_if_captcha_enabled(game_pin: str):
return JSONResponse(status_code=404, content={"detail": "game not found"})
game = PlayGame.parse_raw(game)
if game.captcha_enabled:
- return CheckIfCaptchaEnabledResponse(enabled=True, game_mode=game.game_mode)
+ return CheckIfCaptchaEnabledResponse(enabled=True, game_mode=game.game_mode, custom_field=game.custom_field)
else:
- return CheckIfCaptchaEnabledResponse(enabled=False, game_mode=game.game_mode)
+ return CheckIfCaptchaEnabledResponse(enabled=False, game_mode=game.game_mode, custom_field=game.custom_field)
@router.get("/join/{game_pin}", deprecated=True)
@@ -238,11 +246,14 @@ async def export_quiz_answers(export_token: str, game_pin: str):
if data is None:
raise HTTPException(status_code=404, detail="export token not found")
data = json.loads(data)
- game_data = PlayGame(**json.loads(await redis.get(f"game:{game_pin}")))
+ data2 = await redis.get(f"game:{game_pin}")
+ game_data = PlayGame.parse_raw(data2)
quiz = await Quiz.objects.get_or_none(id=game_data.quiz_id)
if quiz is None:
raise HTTPException(status_code=404, detail="quiz not found")
- spreadsheet = await generate_spreadsheet(quiz=quiz, quiz_results=data)
+
+ player_fields = await redis.hgetall(f"game:{game_pin}:player:custom_fields")
+ spreadsheet = await generate_spreadsheet(quiz=quiz, quiz_results=data, player_fields=player_fields)
def iter_file():
yield from spreadsheet
diff --git a/classquiz/socket_server/__init__.py b/classquiz/socket_server/__init__.py
index 7691daa..c73d21f 100644
--- a/classquiz/socket_server/__init__.py
+++ b/classquiz/socket_server/__init__.py
@@ -43,6 +43,7 @@ class _JoinGameData(BaseModel):
username: str
game_pin: str
captcha: str | None
+ custom_field: str | None
@sio.event
@@ -104,7 +105,11 @@ async def join_game(sid: str, data: dict):
redis_res = GameSession.parse_raw(redis_res)
await redis.set(f"game_session:{data.game_pin}:players:{data.username}", sid, ex=18000)
await redis.sadd(f"game_session:{data.game_pin}:players", GamePlayer(username=data.username, sid=sid).json())
- print(GamePlayer(username=data.username, sid=sid).json())
+ if data.custom_field == "":
+ data.custom_field = None
+ print(data.custom_field)
+ if data.custom_field is not None:
+ await redis.hset(f"game:{data.game_pin}:player:custom_fields", data.username, data.custom_field)
# await redis.set(
# f"game_session:{data.game_pin}",
# GameSession(admin=redis_res.admin, game_id=redis_res.game_id, answers=[]).json(),
diff --git a/frontend/src/lib/dashboard/start_game.svelte b/frontend/src/lib/dashboard/start_game.svelte
index 5521f8d..978ab14 100644
--- a/frontend/src/lib/dashboard/start_game.svelte
+++ b/frontend/src/lib/dashboard/start_game.svelte
@@ -14,26 +14,26 @@
let captcha_selected = false;
let selected_game_mode = 'kahoot';
let loading = false;
+ let custom_field = '';
const start_game = async (id: string) => {
let res;
loading = true;
if (captcha_enabled && captcha_selected) {
res = await fetch(
- `/api/v1/quiz/start/${id}?captcha_enabled=True&game_mode=${selected_game_mode}`,
+ `/api/v1/quiz/start/${id}?captcha_enabled=True&game_mode=${selected_game_mode}&custom_field=${custom_field}`,
{
method: 'POST'
}
);
} else {
res = await fetch(
- `/api/v1/quiz/start/${id}?captcha_enabled=False&game_mode=${selected_game_mode}`,
+ `/api/v1/quiz/start/${id}?captcha_enabled=False&game_mode=${selected_game_mode}&custom_field=${custom_field}`,
{
method: 'POST'
}
);
}
-
if (res.status !== 200) {
alertModal.set({
open: true,
@@ -111,6 +111,9 @@
+
+
+