Writing and speaking rework, some changes to module upload

This commit is contained in:
Carlos-Mesquita
2024-11-25 16:41:38 +00:00
parent a54dfad43a
commit a7da187ec6
20 changed files with 495 additions and 195 deletions

View File

@@ -1,15 +1,27 @@
from abc import ABC, abstractmethod
from typing import Dict, List
from typing import Dict, List, Union
from fastapi import BackgroundTasks
from fastapi.datastructures import FormData
class IGradeController(ABC):
@abstractmethod
async def grade_writing_task(self, task: int, data):
async def grade_writing_task(
self, session_id: str, exercise_id: str,
task: int, dto: any,
background_tasks: BackgroundTasks
):
pass
@abstractmethod
async def grade_speaking_task(self, task: int, answers: List[Dict]) -> Dict:
async def grade_speaking_task(
self, task: int, form: FormData, background_tasks: BackgroundTasks
):
pass
@abstractmethod
async def get_evaluations(self, session_id: str, status: str):
pass
@abstractmethod

View File

@@ -1,34 +1,96 @@
import logging
from typing import Dict, List
from typing import Dict, List, Union
from uuid import uuid4
from fastapi import BackgroundTasks, Response, HTTPException
from fastapi.datastructures import FormData
from app.configs.constants import FilePaths
from app.controllers.abc import IGradeController
from app.dtos.evaluation import EvaluationType
from app.dtos.speaking import GradeSpeakingItem
from app.dtos.writing import WritingGradeTaskDTO
from app.helpers import FileHelper
from app.services.abc import ISpeakingService, IWritingService, IGradeService
from app.utils import handle_exception
from app.services.abc import IGradeService, IEvaluationService
class GradeController(IGradeController):
def __init__(
self,
grade_service: IGradeService,
speaking_service: ISpeakingService,
writing_service: IWritingService
evaluation_service: IEvaluationService,
):
self._service = grade_service
self._speaking_service = speaking_service
self._writing_service = writing_service
self._evaluation_service = evaluation_service
self._logger = logging.getLogger(__name__)
async def grade_writing_task(self, task: int, data: WritingGradeTaskDTO):
return await self._writing_service.grade_writing_task(task, data.question, data.answer)
async def grade_writing_task(
self, session_id: str, exercise_id: str,
task: int, dto: WritingGradeTaskDTO, background_tasks: BackgroundTasks
):
await self._evaluation_service.create_or_update_evaluation(
dto.sessionId, dto.exercise_id, EvaluationType.WRITING, task
)
@handle_exception(400)
async def grade_speaking_task(self, task: int, answers: List[Dict]) -> Dict:
FileHelper.delete_files_older_than_one_day(FilePaths.AUDIO_FILES_PATH)
return await self._speaking_service.grade_speaking_task(task, answers)
await self._evaluation_service.begin_evaluation(
session_id, task, exercise_id, EvaluationType.WRITING, dto, background_tasks
)
return Response(status_code=200)
async def grade_speaking_task(self, task: int, form: FormData, background_tasks: BackgroundTasks):
answers: Dict[int, Dict] = {}
session_id = form.get("sessionId")
exercise_id = form.get("exerciseId")
if not session_id or not exercise_id:
raise HTTPException(
status_code=400,
detail="Fields sessionId and exerciseId are required!"
)
for key, value in form.items():
if '_' not in key:
continue
field_name, index = key.rsplit('_', 1)
index = int(index)
if index not in answers:
answers[index] = {}
if field_name == 'question':
answers[index]['question'] = value
elif field_name == 'audio':
answers[index]['answer'] = value
for i, answer in answers.items():
if 'question' not in answer or 'answer' not in answer:
raise HTTPException(
status_code=400,
detail=f"Incomplete data for answer {i}. Both question and audio required."
)
items = [
GradeSpeakingItem(
question=answers[i]['question'],
answer=answers[i]['answer']
)
for i in sorted(answers.keys())
]
ex_type = EvaluationType.SPEAKING if task == 2 else EvaluationType.SPEAKING_INTERACTIVE
await self._evaluation_service.create_or_update_evaluation(
session_id, exercise_id, ex_type, task
)
await self._evaluation_service.begin_evaluation(
session_id, task, exercise_id, ex_type, items, background_tasks
)
return Response(status_code=200)
async def get_evaluations(self, session_id: str, status: str):
return await self._evaluation_service.get_evaluations(session_id, status)
async def grade_short_answers(self, data: Dict):
return await self._service.grade_short_answers(data)