🚧 Nearly finished excel-import
This commit is contained in:
@@ -5,11 +5,15 @@
|
||||
|
||||
import asyncio
|
||||
import uuid
|
||||
from typing import Optional
|
||||
from datetime import datetime
|
||||
from typing import Optional, BinaryIO
|
||||
|
||||
from fastapi import HTTPException
|
||||
from openpyxl import load_workbook
|
||||
|
||||
import ormar.exceptions
|
||||
|
||||
from classquiz.db.models import Quiz, User, InstanceData
|
||||
from classquiz.db.models import Quiz, User, InstanceData, QuizQuestion, ABCDQuizAnswer
|
||||
import xlsxwriter
|
||||
from aiohttp import ClientSession
|
||||
from io import BytesIO
|
||||
@@ -107,6 +111,51 @@ async def generate_spreadsheet(quiz_results: dict, quiz: Quiz, player_fields: di
|
||||
return storage
|
||||
|
||||
|
||||
async def handle_import_from_excel(data: BinaryIO, user: User):
|
||||
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] = []
|
||||
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
|
||||
question = row[0]
|
||||
if len(question) > 200:
|
||||
raise HTTPException(status_code=400, detail=f"Question {i + 1} is longer than 200")
|
||||
try:
|
||||
time = int(row[5])
|
||||
except (ValueError, TypeError):
|
||||
raise HTTPException(status_code=400, detail=f"Time in q {i + 1} isn't a valid int")
|
||||
if time > 120:
|
||||
raise HTTPException(status_code=400, detail=f"Time in q {i + 1} is greater than 120")
|
||||
answers = [row[1], row[2], row[3], row[4]]
|
||||
for a, answer in enumerate(answers):
|
||||
if answer is None:
|
||||
answers.pop(a)
|
||||
continue
|
||||
if len(answer) > 150:
|
||||
raise HTTPException(status_code=400, detail=f"Answer {a + 1} in Question {i + 1} is longer than 150")
|
||||
if len(answers) < 2:
|
||||
raise HTTPException(status_code=400, detail=f"Less than 2 answers in Question {i + 1}")
|
||||
correct_answers: str = str(row[6])
|
||||
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)))
|
||||
quiz = Quiz(
|
||||
id=uuid.uuid4(),
|
||||
created_at=datetime.now(),
|
||||
updated_at=datetime.now(),
|
||||
user_id=user,
|
||||
questions=questions,
|
||||
imported_from_kahoot=False,
|
||||
)
|
||||
return quiz
|
||||
|
||||
|
||||
async def meilisearch_init():
|
||||
classquiz_index_found = False
|
||||
try:
|
||||
|
||||
@@ -12,8 +12,8 @@ from random import randint
|
||||
|
||||
import ormar.exceptions
|
||||
|
||||
from classquiz.helpers import generate_spreadsheet
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from classquiz.helpers import generate_spreadsheet, handle_import_from_excel
|
||||
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File
|
||||
from fastapi.responses import JSONResponse, StreamingResponse
|
||||
from pydantic import ValidationError, BaseModel
|
||||
|
||||
@@ -246,3 +246,8 @@ async def export_quiz_answers(export_token: str, game_pin: str):
|
||||
"Content-Disposition": f"attachment;filename=ClassQuiz-{urllib.parse.quote(quiz.title)}-{datetime.now().strftime('%m-%d-%Y')}.xlsx" # noqa: E501
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@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)
|
||||
|
||||
Reference in New Issue
Block a user