diff --git a/classquiz/helpers/__init__.py b/classquiz/helpers/__init__.py index b0154da..cf2387b 100644 --- a/classquiz/helpers/__init__.py +++ b/classquiz/helpers/__init__.py @@ -111,14 +111,23 @@ async def generate_spreadsheet(quiz_results: dict, quiz: Quiz, player_fields: di return storage -async def handle_import_from_excel(data: BinaryIO, user: User): +def handle_import_from_excel(data: BinaryIO, user: User) -> Quiz: try: wb = load_workbook(filename=data) except KeyError: raise HTTPException(status_code=400, detail="File not in excel format") - print(wb) ws = wb.active - questions: list[QuizQuestion] = [] + questions: list[dict] = [] + title = ws["C5"].value + description = ws["C6"].value + if title is None: + raise HTTPException(status_code=400, detail="Title missing") + if description is None: + raise HTTPException(status_code=400, detail="Description missing") + if not 3 <= len(description) <= 500: + raise HTTPException(status_code=400, detail="Description doesn't have the correct length") + if not 3 <= len(title) <= 500: + raise HTTPException(status_code=400, detail="Title doesn't have the correct length") for i, row in enumerate(ws.iter_rows(min_row=14, min_col=2, max_row=100, max_col=8, values_only=True)): if row[0] is None: continue @@ -144,8 +153,10 @@ async def handle_import_from_excel(data: BinaryIO, user: User): answers_list: list[ABCDQuizAnswer] = [] for a, answer in enumerate(answers): answers_list.append(ABCDQuizAnswer(answer=answer, right=str(a + 1) in correct_answers)) - questions.append(QuizQuestion(question=question, answers=answers_list, time=str(time))) + questions.append(QuizQuestion(question=question, answers=answers_list, time=str(time)).dict()) quiz = Quiz( + title=title, + description=description, id=uuid.uuid4(), created_at=datetime.now(), updated_at=datetime.now(), diff --git a/classquiz/routers/quiz.py b/classquiz/routers/quiz.py index 5cd62d0..8df0e47 100644 --- a/classquiz/routers/quiz.py +++ b/classquiz/routers/quiz.py @@ -249,5 +249,6 @@ async def export_quiz_answers(export_token: str, game_pin: str): @router.post("/excel-import") -async def import_from_excel(data: UploadFile = File(), user: User = Depends(get_current_user)): - await handle_import_from_excel(data.file, user) +async def import_from_excel(file: UploadFile = File(), user: User = Depends(get_current_user)) -> Quiz: + quiz = handle_import_from_excel(file.file, user) + return Quiz.parse_obj((await quiz.save()).dict(exclude={"user_id": ...})) diff --git a/frontend/src/lib/i18n/locales/en.json b/frontend/src/lib/i18n/locales/en.json index ad0196d..5e51ac8 100644 --- a/frontend/src/lib/i18n/locales/en.json +++ b/frontend/src/lib/i18n/locales/en.json @@ -226,8 +226,10 @@ "url_should_look_like_this": "The URL should look like this: https://create.kahoot.it/details/...", "side_import_kahoot": "On this side you can import quizzes, which live on Kahoot!.", "classquiz_quiz": "A ClassQuiz-Quiz", - "upload_file_ending": "Upload the file ending in .cqa", - "this_side_classquiz": "On this side you can import quizzes, which were exported from ClassQuiz." + "upload_file_ending": "Upload the file ending in .cqa or .xlsx", + "this_side_classquiz": "On this side you can import quizzes, which were exported from ClassQuiz.", + "this_side_classquiz_excel": "You can also upload excel files, if you've filled out the following template.", + "download_template_here": "Download the template" }, "admin_page": { "already_registered_as_admin": "There is already an admin registered for this game.", diff --git a/frontend/src/routes/import/+page.svelte b/frontend/src/routes/import/+page.svelte index ff42aa9..ba8f990 100644 --- a/frontend/src/routes/import/+page.svelte +++ b/frontend/src/routes/import/+page.svelte @@ -14,7 +14,7 @@ SPDX-License-Identifier: MPL-2.0 const { t } = getLocalization(); let url_input = ''; - let file_input; + let file_input: File[]; let url_valid = false; let kahoot_regex = /^https:\/\/create\.kahoot\.it\/details\/([a-zA-Z-\d]{36})\/?$/; @@ -61,10 +61,23 @@ SPDX-License-Identifier: MPL-2.0 is_loading = true; const formdata = new FormData(); formdata.append('file', file_input[0]); - const res = await fetch('/api/v1/eximport/', { - method: 'POST', - body: formdata - }); + let res; + if (file_input[0].name.includes('.xlsx')) { + res = await fetch('/api/v1/quiz/excel-import', { + method: 'POST', + body: formdata + }); + } else if (file_input[0].name.includes('.cqa')) { + res = await fetch('/api/v1/eximport/', { + method: 'POST', + body: formdata + }); + } else { + alert('Wrong file type'); + is_loading = false; + return; + } + if (res.status === 200) { window.location.href = '/dashboard'; } else { @@ -199,7 +212,7 @@ SPDX-License-Identifier: MPL-2.0 bind:files={file_input} name="file" type="file" - accept=".cqa" + accept=".cqa,.xlsx" class="w-full peer bg-transparent h-10 rounded-lg py-1.5 text-gray-700 dark:text-white placeholder-transparent ring-2 px-2 ring-gray-500 focus:ring-sky-600 focus:outline-none focus:border-rose-600" class:ring-red-700={!file_input} class:ring-green-600={file_input} @@ -208,7 +221,15 @@ SPDX-License-Identifier: MPL-2.0
{$t('import_page.this_side_classquiz')}
+
+ {$t('import_page.this_side_classquiz_excel')}