use of de.tum.in.www1.artemis.domain.quiz.SubmittedAnswer in project Artemis by ls1intum.
the class QuizSubmissionService method saveSubmissionForLiveMode.
/**
* Saves a quiz submission into the hash maps for live quizzes. Submitted quizzes are marked to be saved into the database in the QuizScheduleService
*
* @param exerciseId the exerciseID to the corresponding QuizExercise
* @param quizSubmission the submission which should be saved
* @param userLogin the login of the user who has initiated the request
* @param submitted whether the user has pressed the submit button or not
*
* @return the updated quiz submission object
* @throws QuizSubmissionException handles errors, e.g. when the live quiz has already ended, or when the quiz was already submitted before
*/
public QuizSubmission saveSubmissionForLiveMode(Long exerciseId, QuizSubmission quizSubmission, String userLogin, boolean submitted) throws QuizSubmissionException {
// TODO: what happens if a user executes this call twice in the same moment (using 2 threads)
String logText = submitted ? "submit quiz in live mode:" : "save quiz in live mode:";
long start = System.nanoTime();
checkSubmissionForLiveModeOrThrow(exerciseId, userLogin, logText, start);
// recreate pointers back to submission in each submitted answer
for (SubmittedAnswer submittedAnswer : quizSubmission.getSubmittedAnswers()) {
submittedAnswer.setSubmission(quizSubmission);
}
// set submission date
quizSubmission.setSubmissionDate(ZonedDateTime.now());
// save submission to HashMap
quizScheduleService.updateSubmission(exerciseId, userLogin, quizSubmission);
log.info("{} Saved quiz submission for user {} in quiz {} after {} µs ", logText, userLogin, exerciseId, (System.nanoTime() - start) / 1000);
return quizSubmission;
}
use of de.tum.in.www1.artemis.domain.quiz.SubmittedAnswer in project Artemis by ls1intum.
the class QuizSubmissionResource method submitForPractice.
/**
* POST /exercises/:exerciseId/submissions/practice : Submit a new quizSubmission for practice mode.
*
* @param exerciseId the id of the exercise for which to init a participation
* @param quizSubmission the quizSubmission to submit
* @return the ResponseEntity with status 200 (OK) and the Result as its body, or with status 4xx if the request is invalid
*/
@PostMapping("/exercises/{exerciseId}/submissions/practice")
@PreAuthorize("hasRole('USER')")
public ResponseEntity<Result> submitForPractice(@PathVariable Long exerciseId, @RequestBody QuizSubmission quizSubmission) {
log.debug("REST request to submit QuizSubmission for practice : {}", quizSubmission);
// recreate pointers back to submission in each submitted answer
for (SubmittedAnswer submittedAnswer : quizSubmission.getSubmittedAnswers()) {
submittedAnswer.setSubmission(quizSubmission);
}
if (quizSubmission.getId() != null) {
return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert(applicationName, true, ENTITY_NAME, "idexists", "A new quizSubmission cannot already have an ID.")).body(null);
}
QuizExercise quizExercise = quizExerciseRepository.findByIdWithQuestionsElseThrow(exerciseId);
User user = userRepository.getUserWithGroupsAndAuthorities();
if (!authCheckService.isAllowedToSeeExercise(quizExercise, user)) {
return ResponseEntity.status(403).headers(HeaderUtil.createFailureAlert(applicationName, true, "submission", "Forbidden", "You are not allowed to participate in this exercise.")).body(null);
}
// Note that exam quiz exercises do not have an end date, so we need to check in that order
if (!Boolean.TRUE.equals(quizExercise.isIsOpenForPractice()) || !quizExercise.isQuizEnded()) {
return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert(applicationName, true, "submission", "exerciseNotOpenForPractice", "The exercise is not open for practice or hasn't ended yet.")).body(null);
}
// the following method either reuses an existing participation or creates a new one
StudentParticipation participation = participationService.startExercise(quizExercise, user, false);
// we set the exercise again to prevent issues with lazy loaded quiz questions
participation.setExercise(quizExercise);
// update and save submission
Result result = quizSubmissionService.submitForPractice(quizSubmission, quizExercise, participation);
// The quizScheduler is usually responsible for updating the participation to FINISHED in the database. If quizzes where the student did not participate are used for
// practice, the QuizScheduler does not update the participation, that's why we update it manually here
participation.setInitializationState(InitializationState.FINISHED);
studentParticipationRepository.saveAndFlush(participation);
// remove some redundant or unnecessary data that is not needed on client side
for (SubmittedAnswer answer : quizSubmission.getSubmittedAnswers()) {
answer.getQuizQuestion().setQuizQuestionStatistic(null);
}
quizExercise.setQuizPointStatistic(null);
quizExercise.setCourse(null);
messagingService.broadcastNewResult(result.getParticipation(), result);
// return result with quizSubmission, participation and quiz exercise (including the solution)
return ResponseEntity.ok(result);
}
use of de.tum.in.www1.artemis.domain.quiz.SubmittedAnswer in project Artemis by ls1intum.
the class QuizSubmissionResource method submitQuizForExam.
/**
* PUT /exercises/:exerciseId/submissions/exam : Update a QuizSubmission for exam mode
*
* @param exerciseId the id of the exercise for which to update the submission
* @param quizSubmission the quizSubmission to update
* @return the ResponseEntity with status 200 and body the result or the appropriate error code.
*/
@PutMapping("exercises/{exerciseId}/submissions/exam")
@PreAuthorize("hasRole('USER')")
public ResponseEntity<QuizSubmission> submitQuizForExam(@PathVariable Long exerciseId, @RequestBody QuizSubmission quizSubmission) {
long start = System.currentTimeMillis();
log.debug("REST request to submit QuizSubmission for exam : {}", quizSubmission);
// recreate pointers back to submission in each submitted answer
for (SubmittedAnswer submittedAnswer : quizSubmission.getSubmittedAnswers()) {
submittedAnswer.setSubmission(quizSubmission);
}
QuizExercise quizExercise = quizExerciseRepository.findByIdWithQuestionsElseThrow(exerciseId);
User user = userRepository.getUserWithGroupsAndAuthorities();
// Apply further checks if it is an exam submission
examSubmissionService.checkSubmissionAllowanceElseThrow(quizExercise, user);
// Prevent multiple submissions (currently only for exam submissions)
quizSubmission = (QuizSubmission) examSubmissionService.preventMultipleSubmissions(quizExercise, quizSubmission, user);
QuizSubmission updatedQuizSubmission = quizSubmissionService.saveSubmissionForExamMode(quizExercise, quizSubmission, user.getLogin());
long end = System.currentTimeMillis();
log.info("submitQuizForExam took {}ms for exercise {} and user {}", end - start, exerciseId, user.getLogin());
return ResponseEntity.ok(updatedQuizSubmission);
}
use of de.tum.in.www1.artemis.domain.quiz.SubmittedAnswer in project Artemis by ls1intum.
the class QuizScheduleService method removeUnnecessaryObjectsBeforeSendingToClient.
private void removeUnnecessaryObjectsBeforeSendingToClient(StudentParticipation participation) {
if (participation.getExercise() != null) {
var quizExercise = (QuizExercise) participation.getExercise();
// we do not need the course and lectures
quizExercise.setCourse(null);
// students should not see statistics
// TODO: this would be useful, but leads to problems when the quiz schedule service wants to access the statistics again later on
// quizExercise.setQuizPointStatistic(null);
// quizExercise.getQuizQuestions().forEach(quizQuestion -> quizQuestion.setQuizQuestionStatistic(null));
}
// submissions are part of results, so we do not need them twice
participation.setSubmissions(null);
participation.setParticipant(null);
if (participation.getResults() != null && !participation.getResults().isEmpty()) {
QuizSubmission quizSubmission = (QuizSubmission) participation.getResults().iterator().next().getSubmission();
if (quizSubmission != null && quizSubmission.getSubmittedAnswers() != null) {
for (SubmittedAnswer submittedAnswer : quizSubmission.getSubmittedAnswers()) {
if (submittedAnswer.getQuizQuestion() != null) {
// we do not need all information of the questions again, they are already stored in the exercise
var question = submittedAnswer.getQuizQuestion();
submittedAnswer.setQuizQuestion(question.copyQuestionId());
}
}
}
}
}
Aggregations