Search in sources :

Example 1 with QuizSubmission

use of de.tum.in.www1.artemis.domain.QuizSubmission in project Artemis by ls1intum.

the class QuizSubmissionWebsocketService method saveSubmission.

// TODO it would be nice to have some kind of startQuiz call that creates the participation with an initialization date. This should happen when the quiz is first shown
// to the user. Then we also could find out how long students work on the quiz on average
/**
 * Saves a quiz submission into the hash maps. 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 principal      refers to the user who initiated the request
 */
@MessageMapping("/topic/quizExercise/{exerciseId}/submission")
public void saveSubmission(@DestinationVariable Long exerciseId, @Payload QuizSubmission quizSubmission, Principal principal) {
    // Without this, custom jpa repository methods don't work in websocket channel.
    SecurityUtils.setAuthorizationObject();
    String username = principal.getName();
    try {
        QuizSubmission updatedQuizSubmission = quizSubmissionService.saveSubmissionForLiveMode(exerciseId, quizSubmission, username, false);
    // send updated submission over websocket (use a thread to prevent that the outbound channel blocks the inbound channel (e.g. due a slow client))
    // to improve the performance, this is currently deactivated: slow clients might lead to bottlenecks so that more important messages can not be distributed any more
    // new Thread(() -> sendSubmissionToUser(username, exerciseId, quizSubmission)).start();
    // log.info("WS.Inbound: Sent quiz submission (async) back to user {} in quiz {} after {} µs ", principal.getName(), exerciseId, (System.nanoTime() - start) / 1000);
    } catch (QuizSubmissionException ex) {
        // send error message over websocket (use a thread to prevent that the outbound channel blocks the inbound channel (e.g. due a slow client))
        new Thread(() -> messagingTemplate.convertAndSendToUser(username, "/topic/quizExercise/" + exerciseId + "/submission", new WebsocketError(ex.getMessage()))).start();
    }
}
Also used : QuizSubmission(de.tum.in.www1.artemis.domain.quiz.QuizSubmission) QuizSubmissionException(de.tum.in.www1.artemis.exception.QuizSubmissionException) MessageMapping(org.springframework.messaging.handler.annotation.MessageMapping)

Example 2 with QuizSubmission

use of de.tum.in.www1.artemis.domain.QuizSubmission 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().size() > 0) {
        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());
                }
            }
        }
    }
}
Also used : QuizSubmission(de.tum.in.www1.artemis.domain.quiz.QuizSubmission) SubmittedAnswer(de.tum.in.www1.artemis.domain.quiz.SubmittedAnswer) QuizExercise(de.tum.in.www1.artemis.domain.quiz.QuizExercise)

Example 3 with QuizSubmission

use of de.tum.in.www1.artemis.domain.QuizSubmission in project Artemis by ls1intum.

the class DatabaseUtilService method createSubmissionAndResult.

public Result createSubmissionAndResult(StudentParticipation studentParticipation, long scoreAwarded, boolean rated) {
    Exercise exercise = studentParticipation.getExercise();
    Submission submission;
    if (exercise instanceof ProgrammingExercise) {
        submission = new ProgrammingSubmission();
    } else if (exercise instanceof ModelingExercise) {
        submission = new ModelingSubmission();
    } else if (exercise instanceof TextExercise) {
        submission = new TextSubmission();
    } else if (exercise instanceof FileUploadExercise) {
        submission = new FileUploadSubmission();
    } else if (exercise instanceof QuizExercise) {
        submission = new QuizSubmission();
    } else {
        throw new RuntimeException("Unsupported exercise type: " + exercise);
    }
    submission.setType(SubmissionType.MANUAL);
    submission.setParticipation(studentParticipation);
    submission = submissionRepository.saveAndFlush(submission);
    Result result = ModelFactory.generateResult(rated, scoreAwarded);
    result.setParticipation(studentParticipation);
    result.setSubmission(submission);
    result.completionDate(ZonedDateTime.now());
    submission.addResult(result);
    submission = submissionRepository.saveAndFlush(submission);
    return submission.getResults().get(0);
}
Also used : ModelingSubmission(de.tum.in.www1.artemis.domain.modeling.ModelingSubmission) ModelingSubmission(de.tum.in.www1.artemis.domain.modeling.ModelingSubmission) ModelingExercise(de.tum.in.www1.artemis.domain.modeling.ModelingExercise) TextPlagiarismResult(de.tum.in.www1.artemis.domain.plagiarism.text.TextPlagiarismResult) ModelingPlagiarismResult(de.tum.in.www1.artemis.domain.plagiarism.modeling.ModelingPlagiarismResult) ModelingExercise(de.tum.in.www1.artemis.domain.modeling.ModelingExercise)

Example 4 with QuizSubmission

use of de.tum.in.www1.artemis.domain.QuizSubmission in project Artemis by ls1intum.

the class DatabaseUtilService method createCourseWithAllExerciseTypesAndParticipationsAndSubmissionsAndResults.

public Course createCourseWithAllExerciseTypesAndParticipationsAndSubmissionsAndResults(boolean hasAssessmentDueDatePassed) {
    Course course = ModelFactory.generateCourse(null, pastTimestamp, futureTimestamp, new HashSet<>(), "tumuser", "tutor", "editor", "instructor");
    ModelingExercise modelingExercise = ModelFactory.generateModelingExercise(pastTimestamp, futureTimestamp, futureFutureTimestamp, DiagramType.ClassDiagram, course);
    TextExercise textExercise = ModelFactory.generateTextExercise(pastTimestamp, futureTimestamp, futureFutureTimestamp, course);
    FileUploadExercise fileUploadExercise = ModelFactory.generateFileUploadExercise(pastTimestamp, futureTimestamp, futureFutureTimestamp, "png", course);
    ProgrammingExercise programmingExercise = ModelFactory.generateProgrammingExercise(pastTimestamp, futureTimestamp, course);
    QuizExercise quizExercise = ModelFactory.generateQuizExercise(pastTimestamp, futureTimestamp, course);
    // Set assessment due dates
    if (hasAssessmentDueDatePassed) {
        modelingExercise.setAssessmentDueDate(ZonedDateTime.now().minusMinutes(10L));
        textExercise.setAssessmentDueDate(ZonedDateTime.now().minusMinutes(10L));
        fileUploadExercise.setAssessmentDueDate(ZonedDateTime.now().minusMinutes(10L));
        programmingExercise.setAssessmentDueDate(ZonedDateTime.now().minusMinutes(10L));
        quizExercise.setAssessmentDueDate(ZonedDateTime.now().minusMinutes(10L));
    } else {
        modelingExercise.setAssessmentDueDate(ZonedDateTime.now().plusMinutes(10L));
        textExercise.setAssessmentDueDate(ZonedDateTime.now().plusMinutes(10L));
        fileUploadExercise.setAssessmentDueDate(ZonedDateTime.now().plusMinutes(10L));
        programmingExercise.setAssessmentDueDate(ZonedDateTime.now().plusMinutes(10L));
        quizExercise.setAssessmentDueDate(ZonedDateTime.now().plusMinutes(10L));
    }
    // Add exercises to course
    course.addExercises(modelingExercise);
    course.addExercises(textExercise);
    course.addExercises(fileUploadExercise);
    course.addExercises(programmingExercise);
    course.addExercises(quizExercise);
    // Save course and exercises to database
    Course courseSaved = courseRepo.save(course);
    modelingExercise = exerciseRepo.save(modelingExercise);
    textExercise = exerciseRepo.save(textExercise);
    fileUploadExercise = exerciseRepo.save(fileUploadExercise);
    programmingExercise = exerciseRepo.save(programmingExercise);
    quizExercise = exerciseRepo.save(quizExercise);
    // Get user and setup participations
    User user = (userRepo.findOneByLogin("student1")).get();
    StudentParticipation participationModeling = ModelFactory.generateStudentParticipation(InitializationState.FINISHED, modelingExercise, user);
    StudentParticipation participationText = ModelFactory.generateStudentParticipation(InitializationState.FINISHED, textExercise, user);
    StudentParticipation participationFileUpload = ModelFactory.generateStudentParticipation(InitializationState.FINISHED, fileUploadExercise, user);
    StudentParticipation participationQuiz = ModelFactory.generateStudentParticipation(InitializationState.FINISHED, quizExercise, user);
    StudentParticipation participationProgramming = ModelFactory.generateStudentParticipation(InitializationState.INITIALIZED, programmingExercise, user);
    // Save participations
    participationModeling = studentParticipationRepo.save(participationModeling);
    participationText = studentParticipationRepo.save(participationText);
    participationFileUpload = studentParticipationRepo.save(participationFileUpload);
    participationQuiz = studentParticipationRepo.save(participationQuiz);
    participationProgramming = studentParticipationRepo.save(participationProgramming);
    // Setup results
    Result resultModeling = ModelFactory.generateResult(true, 10D);
    resultModeling.setAssessmentType(AssessmentType.MANUAL);
    resultModeling.setCompletionDate(ZonedDateTime.now());
    Result resultText = ModelFactory.generateResult(true, 12D);
    resultText.setAssessmentType(AssessmentType.MANUAL);
    resultText.setCompletionDate(ZonedDateTime.now());
    Result resultFileUpload = ModelFactory.generateResult(true, 0D);
    resultFileUpload.setAssessmentType(AssessmentType.MANUAL);
    resultFileUpload.setCompletionDate(ZonedDateTime.now());
    Result resultQuiz = ModelFactory.generateResult(true, 0D);
    resultQuiz.setAssessmentType(AssessmentType.AUTOMATIC);
    resultQuiz.setCompletionDate(ZonedDateTime.now());
    Result resultProgramming = ModelFactory.generateResult(true, 20D);
    resultProgramming.setAssessmentType(AssessmentType.AUTOMATIC);
    resultProgramming.setCompletionDate(ZonedDateTime.now());
    // Connect participations to results and vice versa
    resultModeling.setParticipation(participationModeling);
    resultText.setParticipation(participationText);
    resultFileUpload.setParticipation(participationFileUpload);
    resultQuiz.setParticipation(participationQuiz);
    resultProgramming.setParticipation(participationProgramming);
    participationModeling.addResult(resultModeling);
    participationText.addResult(resultText);
    participationFileUpload.addResult(resultFileUpload);
    participationQuiz.addResult(resultQuiz);
    participationProgramming.addResult(resultProgramming);
    // Save results and participations
    resultModeling = resultRepo.save(resultModeling);
    resultText = resultRepo.save(resultText);
    resultFileUpload = resultRepo.save(resultFileUpload);
    resultQuiz = resultRepo.save(resultQuiz);
    resultProgramming = resultRepo.save(resultProgramming);
    participationModeling = studentParticipationRepo.save(participationModeling);
    participationText = studentParticipationRepo.save(participationText);
    participationFileUpload = studentParticipationRepo.save(participationFileUpload);
    participationQuiz = studentParticipationRepo.save(participationQuiz);
    participationProgramming = studentParticipationRepo.save(participationProgramming);
    // Connect exercises with participations
    modelingExercise.addParticipation(participationModeling);
    textExercise.addParticipation(participationText);
    fileUploadExercise.addParticipation(participationFileUpload);
    quizExercise.addParticipation(participationQuiz);
    programmingExercise.addParticipation(participationProgramming);
    // Setup submissions and connect with participations
    ModelingSubmission modelingSubmission = ModelFactory.generateModelingSubmission("model1", true);
    TextSubmission textSubmission = ModelFactory.generateTextSubmission("text of text submission", Language.ENGLISH, true);
    FileUploadSubmission fileUploadSubmission = ModelFactory.generateFileUploadSubmission(true);
    QuizSubmission quizSubmission = ModelFactory.generateQuizSubmission(true);
    ProgrammingSubmission programmingSubmission = ModelFactory.generateProgrammingSubmission(true);
    // Save submissions
    modelingSubmission = submissionRepository.save(modelingSubmission);
    textSubmission = submissionRepository.save(textSubmission);
    fileUploadSubmission = submissionRepository.save(fileUploadSubmission);
    quizSubmission = submissionRepository.save(quizSubmission);
    programmingSubmission = submissionRepository.save(programmingSubmission);
    modelingSubmission.setParticipation(participationModeling);
    modelingSubmission.addResult(resultModeling);
    textSubmission.setParticipation(participationText);
    textSubmission.addResult(resultText);
    fileUploadSubmission.setParticipation(participationFileUpload);
    fileUploadSubmission.addResult(resultFileUpload);
    quizSubmission.setParticipation(participationQuiz);
    quizSubmission.addResult(resultQuiz);
    programmingSubmission.setParticipation(participationProgramming);
    programmingSubmission.addResult(resultProgramming);
    // Save submissions
    modelingSubmission = submissionRepository.save(modelingSubmission);
    textSubmission = submissionRepository.save(textSubmission);
    fileUploadSubmission = submissionRepository.save(fileUploadSubmission);
    quizSubmission = submissionRepository.save(quizSubmission);
    programmingSubmission = submissionRepository.save(programmingSubmission);
    // Save exercises
    exerciseRepo.save(modelingExercise);
    exerciseRepo.save(textExercise);
    exerciseRepo.save(fileUploadExercise);
    exerciseRepo.save(programmingExercise);
    exerciseRepo.save(quizExercise);
    // Connect participations with submissions
    participationModeling.setSubmissions(Set.of(modelingSubmission));
    participationText.setSubmissions(Set.of(textSubmission));
    participationFileUpload.setSubmissions(Set.of(fileUploadSubmission));
    participationQuiz.setSubmissions(Set.of(quizSubmission));
    participationProgramming.setSubmissions(Set.of(programmingSubmission));
    // Save participations
    studentParticipationRepo.save(participationModeling);
    studentParticipationRepo.save(participationText);
    studentParticipationRepo.save(participationFileUpload);
    studentParticipationRepo.save(participationQuiz);
    studentParticipationRepo.save(participationProgramming);
    return courseSaved;
}
Also used : ModelingSubmission(de.tum.in.www1.artemis.domain.modeling.ModelingSubmission) ModelingExercise(de.tum.in.www1.artemis.domain.modeling.ModelingExercise) TextPlagiarismResult(de.tum.in.www1.artemis.domain.plagiarism.text.TextPlagiarismResult) ModelingPlagiarismResult(de.tum.in.www1.artemis.domain.plagiarism.modeling.ModelingPlagiarismResult)

Example 5 with QuizSubmission

use of de.tum.in.www1.artemis.domain.QuizSubmission in project ArTEMiS by ls1intum.

the class QuizSubmissionWebsocketService method saveSubmission.

// TODO it would be nice to have some kind of startQuiz call that creates the participation with an initialization date. This should happen when the quiz is first shown
// to the user. Then we also could find out how long students work on the quiz on average
/**
 * Saves a quiz submission into the hash maps. 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 principal      refers to the user who initiated the request
 */
@MessageMapping("/topic/quizExercise/{exerciseId}/submission")
public void saveSubmission(@DestinationVariable Long exerciseId, @Payload QuizSubmission quizSubmission, Principal principal) {
    // Without this, custom jpa repository methods don't work in websocket channel.
    SecurityUtils.setAuthorizationObject();
    String username = principal.getName();
    try {
        QuizSubmission updatedQuizSubmission = quizSubmissionService.saveSubmissionForLiveMode(exerciseId, quizSubmission, username, false);
    // send updated submission over websocket (use a thread to prevent that the outbound channel blocks the inbound channel (e.g. due a slow client))
    // to improve the performance, this is currently deactivated: slow clients might lead to bottlenecks so that more important messages can not be distributed any more
    // new Thread(() -> sendSubmissionToUser(username, exerciseId, quizSubmission)).start();
    // log.info("WS.Inbound: Sent quiz submission (async) back to user {} in quiz {} after {} µs ", principal.getName(), exerciseId, (System.nanoTime() - start) / 1000);
    } catch (QuizSubmissionException ex) {
        // send error message over websocket (use a thread to prevent that the outbound channel blocks the inbound channel (e.g. due a slow client))
        new Thread(() -> messagingTemplate.convertAndSendToUser(username, "/topic/quizExercise/" + exerciseId + "/submission", new WebsocketError(ex.getMessage()))).start();
    }
}
Also used : QuizSubmission(de.tum.in.www1.artemis.domain.quiz.QuizSubmission) QuizSubmissionException(de.tum.in.www1.artemis.exception.QuizSubmissionException) MessageMapping(org.springframework.messaging.handler.annotation.MessageMapping)

Aggregations

QuizSubmission (de.tum.in.www1.artemis.domain.quiz.QuizSubmission)28 QuizExercise (de.tum.in.www1.artemis.domain.quiz.QuizExercise)20 StudentParticipation (de.tum.in.www1.artemis.domain.participation.StudentParticipation)19 Result (de.tum.in.www1.artemis.domain.Result)17 SubmittedAnswer (de.tum.in.www1.artemis.domain.quiz.SubmittedAnswer)11 User (de.tum.in.www1.artemis.domain.User)10 PreAuthorize (org.springframework.security.access.prepost.PreAuthorize)10 StudentExam (de.tum.in.www1.artemis.domain.exam.StudentExam)8 QuizSubmissionException (de.tum.in.www1.artemis.exception.QuizSubmissionException)8 WithMockUser (org.springframework.security.test.context.support.WithMockUser)8 AbstractSpringIntegrationBambooBitbucketJiraTest (de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest)6 ModelingExercise (de.tum.in.www1.artemis.domain.modeling.ModelingExercise)6 ModelingSubmission (de.tum.in.www1.artemis.domain.modeling.ModelingSubmission)6 EntityNotFoundException (de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException)6 Test (org.junit.jupiter.api.Test)6 Submission (de.tum.in.www1.artemis.domain.Submission)4 AssessmentType (de.tum.in.www1.artemis.domain.enumeration.AssessmentType)4 InitializationState (de.tum.in.www1.artemis.domain.enumeration.InitializationState)4 ModelingPlagiarismResult (de.tum.in.www1.artemis.domain.plagiarism.modeling.ModelingPlagiarismResult)4 TextPlagiarismResult (de.tum.in.www1.artemis.domain.plagiarism.text.TextPlagiarismResult)4