Created the InteractiveSpeaking exercise
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import {Evaluation, Exam, SpeakingExercise, UserSolution, WritingExercise} from "@/interfaces/exam";
|
||||
import {Evaluation, Exam, InteractiveSpeakingExercise, SpeakingExercise, UserSolution, WritingExercise} from "@/interfaces/exam";
|
||||
import axios from "axios";
|
||||
import {speakingReverseMarking, writingReverseMarking} from "./score";
|
||||
|
||||
@@ -30,16 +30,23 @@ export const evaluateSpeakingAnswer = async (exams: Exam[], examId: string, exer
|
||||
const speakingExam = exams.find((x) => x.id === examId)!;
|
||||
const exercise = speakingExam.exercises.find((x) => x.id === exerciseId);
|
||||
|
||||
if (exercise?.type === "speaking") {
|
||||
return await evaluateSpeakingExercise(exercise, exerciseId, solution);
|
||||
switch (exercise?.type) {
|
||||
case "speaking":
|
||||
return await evaluateSpeakingExercise(exercise, exerciseId, solution);
|
||||
case "interactiveSpeaking":
|
||||
return await evaluateInteractiveSpeakingExercise(exerciseId, solution);
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
return undefined;
|
||||
const downloadBlob = async (url: string): Promise<Buffer> => {
|
||||
const blobResponse = await axios.get(url, {responseType: "arraybuffer"});
|
||||
return Buffer.from(blobResponse.data, "binary");
|
||||
};
|
||||
|
||||
const evaluateSpeakingExercise = async (exercise: SpeakingExercise, exerciseId: string, solution: UserSolution) => {
|
||||
const blobResponse = await axios.get(solution.solutions[0].solution.trim(), {responseType: "arraybuffer"});
|
||||
const audioBlob = Buffer.from(blobResponse.data, "binary");
|
||||
const audioBlob = await downloadBlob(solution.solutions[0].solution.trim());
|
||||
const audioFile = new File([audioBlob], "audio.wav", {type: "audio/wav"});
|
||||
|
||||
const formData = new FormData();
|
||||
@@ -68,3 +75,43 @@ const evaluateSpeakingExercise = async (exercise: SpeakingExercise, exerciseId:
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const evaluateInteractiveSpeakingExercise = async (exerciseId: string, solution: UserSolution) => {
|
||||
const promiseParts = solution.solutions.map(async (x: {prompt: string; blob: string}) => ({
|
||||
question: x.prompt,
|
||||
answer: await downloadBlob(x.blob),
|
||||
}));
|
||||
const body = await Promise.all(promiseParts);
|
||||
|
||||
const formData = new FormData();
|
||||
body.forEach(({question, answer}) => {
|
||||
const seed = Math.random().toString().replace("0.", "");
|
||||
|
||||
const audioFile = new File([answer], `${seed}.wav`, {type: "audio/wav"});
|
||||
|
||||
formData.append(`question_${seed}`, question);
|
||||
formData.append(`answer_${seed}`, audioFile, `${seed}.wav`);
|
||||
});
|
||||
|
||||
const config = {
|
||||
headers: {
|
||||
"Content-Type": "audio/mp3",
|
||||
},
|
||||
};
|
||||
|
||||
const response = await axios.post("/api/evaluate/interactiveSpeaking", formData, config);
|
||||
|
||||
if (response.status === 200) {
|
||||
return {
|
||||
...solution,
|
||||
score: {
|
||||
correct: speakingReverseMarking[response.data.overall] || 0,
|
||||
missing: 0,
|
||||
total: 100,
|
||||
},
|
||||
solutions: [{id: exerciseId, solution: response.data.answer, evaluation: response.data}],
|
||||
};
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user