Search in sources :

Example 1 with QuizExercise

use of de.tum.in.www1.artemis.domain.quiz.QuizExercise 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 QuizExercise

use of de.tum.in.www1.artemis.domain.quiz.QuizExercise 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 QuizExercise

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

the class QuizScheduleService method executeQuizStartNowTask.

/**
 * Internal method to start and send the {@link QuizExercise} to the clients when called
 */
void executeQuizStartNowTask(Long quizExerciseId) {
    quizCache.performCacheWriteIfPresent(quizExerciseId, quizExerciseCache -> {
        quizExerciseCache.getQuizStart().clear();
        log.debug("Removed quiz {} start tasks", quizExerciseId);
        return quizExerciseCache;
    });
    log.debug("Sending quiz {} start", quizExerciseId);
    QuizExercise quizExercise = quizExerciseRepository.findOneWithQuestionsAndStatistics(quizExerciseId);
    updateQuizExercise(quizExercise);
    quizMessagingService.sendQuizExerciseToSubscribedClients(quizExercise, "start-now");
}
Also used : QuizExercise(de.tum.in.www1.artemis.domain.quiz.QuizExercise)

Example 4 with QuizExercise

use of de.tum.in.www1.artemis.domain.quiz.QuizExercise 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 5 with QuizExercise

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

the class DatabaseUtilService method addExerciseGroupsAndExercisesToExam.

public Exam addExerciseGroupsAndExercisesToExam(Exam exam, boolean withProgrammingExercise) {
    // text
    ModelFactory.generateExerciseGroup(true, exam);
    // quiz
    ModelFactory.generateExerciseGroup(true, exam);
    // file upload
    ModelFactory.generateExerciseGroup(true, exam);
    // modeling
    ModelFactory.generateExerciseGroup(true, exam);
    // bonus text
    ModelFactory.generateExerciseGroup(true, exam);
    // not included text
    ModelFactory.generateExerciseGroup(true, exam);
    exam.setNumberOfExercisesInExam(6);
    exam.setMaxPoints(24);
    exam = examRepository.save(exam);
    // NOTE: we have to reassign, otherwise we get problems, because the objects have changed
    var exerciseGroup0 = exam.getExerciseGroups().get(0);
    var exerciseGroup1 = exam.getExerciseGroups().get(1);
    var exerciseGroup2 = exam.getExerciseGroups().get(2);
    var exerciseGroup3 = exam.getExerciseGroups().get(3);
    var exerciseGroup4 = exam.getExerciseGroups().get(4);
    var exerciseGroup5 = exam.getExerciseGroups().get(5);
    TextExercise textExercise1 = ModelFactory.generateTextExerciseForExam(exerciseGroup0);
    TextExercise textExercise2 = ModelFactory.generateTextExerciseForExam(exerciseGroup0);
    textExercise1.setKnowledge(textAssessmentKnowledgeService.createNewKnowledge());
    textExercise2.setKnowledge(textAssessmentKnowledgeService.createNewKnowledge());
    exerciseGroup0.setExercises(Set.of(textExercise1, textExercise2));
    exerciseRepo.save(textExercise1);
    exerciseRepo.save(textExercise2);
    QuizExercise quizExercise1 = createQuizForExam(exerciseGroup1);
    QuizExercise quizExercise2 = createQuizForExam(exerciseGroup1);
    exerciseGroup1.setExercises(Set.of(quizExercise1, quizExercise2));
    exerciseRepo.save(quizExercise1);
    exerciseRepo.save(quizExercise2);
    FileUploadExercise fileUploadExercise1 = ModelFactory.generateFileUploadExerciseForExam("pdf", exerciseGroup2);
    FileUploadExercise fileUploadExercise2 = ModelFactory.generateFileUploadExerciseForExam("pdf", exerciseGroup2);
    exerciseGroup2.setExercises(Set.of(fileUploadExercise1, fileUploadExercise2));
    exerciseRepo.save(fileUploadExercise1);
    exerciseRepo.save(fileUploadExercise2);
    ModelingExercise modelingExercise1 = ModelFactory.generateModelingExerciseForExam(DiagramType.ClassDiagram, exerciseGroup3);
    ModelingExercise modelingExercise2 = ModelFactory.generateModelingExerciseForExam(DiagramType.ClassDiagram, exerciseGroup3);
    modelingExercise1.setKnowledge(modelAssessmentKnowledgeService.createNewKnowledge());
    modelingExercise2.setKnowledge(modelAssessmentKnowledgeService.createNewKnowledge());
    exerciseGroup3.setExercises(Set.of(modelingExercise1, modelingExercise2));
    exerciseRepo.save(modelingExercise1);
    exerciseRepo.save(modelingExercise2);
    TextExercise bonusTextExercise = ModelFactory.generateTextExerciseForExam(exerciseGroup4);
    bonusTextExercise.setIncludedInOverallScore(IncludedInOverallScore.INCLUDED_AS_BONUS);
    bonusTextExercise.setKnowledge(textAssessmentKnowledgeService.createNewKnowledge());
    exerciseGroup4.setExercises(Set.of(bonusTextExercise));
    exerciseRepo.save(bonusTextExercise);
    TextExercise notIncludedTextExercise = ModelFactory.generateTextExerciseForExam(exerciseGroup5);
    notIncludedTextExercise.setIncludedInOverallScore(IncludedInOverallScore.NOT_INCLUDED);
    notIncludedTextExercise.setKnowledge(textAssessmentKnowledgeService.createNewKnowledge());
    exerciseGroup5.setExercises(Set.of(notIncludedTextExercise));
    exerciseRepo.save(notIncludedTextExercise);
    if (withProgrammingExercise) {
        // programming
        ModelFactory.generateExerciseGroup(true, exam);
        exam.setNumberOfExercisesInExam(7);
        exam.setMaxPoints(29);
        exam = examRepository.save(exam);
        var exerciseGroup6 = exam.getExerciseGroups().get(6);
        // Programming exercises need a proper setup for 'prepare exam start' to work
        ProgrammingExercise programmingExercise1 = ModelFactory.generateProgrammingExerciseForExam(exerciseGroup6);
        exerciseRepo.save(programmingExercise1);
        addTemplateParticipationForProgrammingExercise(programmingExercise1);
        addSolutionParticipationForProgrammingExercise(programmingExercise1);
        exerciseGroup6.setExercises(Set.of(programmingExercise1));
    }
    return exam;
}
Also used : ModelingExercise(de.tum.in.www1.artemis.domain.modeling.ModelingExercise)

Aggregations

QuizExercise (de.tum.in.www1.artemis.domain.quiz.QuizExercise)46 StudentParticipation (de.tum.in.www1.artemis.domain.participation.StudentParticipation)31 QuizSubmission (de.tum.in.www1.artemis.domain.quiz.QuizSubmission)26 WithMockUser (org.springframework.security.test.context.support.WithMockUser)24 Result (de.tum.in.www1.artemis.domain.Result)23 Test (org.junit.jupiter.api.Test)20 ModelingExercise (de.tum.in.www1.artemis.domain.modeling.ModelingExercise)18 StudentExam (de.tum.in.www1.artemis.domain.exam.StudentExam)16 EntityNotFoundException (de.tum.in.www1.artemis.web.rest.errors.EntityNotFoundException)14 ModelingSubmission (de.tum.in.www1.artemis.domain.modeling.ModelingSubmission)12 SubmittedAnswer (de.tum.in.www1.artemis.domain.quiz.SubmittedAnswer)12 ZonedDateTime (java.time.ZonedDateTime)12 AbstractSpringIntegrationBambooBitbucketJiraTest (de.tum.in.www1.artemis.AbstractSpringIntegrationBambooBitbucketJiraTest)10 User (de.tum.in.www1.artemis.domain.User)10 AssessmentType (de.tum.in.www1.artemis.domain.enumeration.AssessmentType)8 ExerciseGroup (de.tum.in.www1.artemis.domain.exam.ExerciseGroup)8 PreAuthorize (org.springframework.security.access.prepost.PreAuthorize)8 Exam (de.tum.in.www1.artemis.domain.exam.Exam)6 Participation (de.tum.in.www1.artemis.domain.participation.Participation)6 ModelingPlagiarismResult (de.tum.in.www1.artemis.domain.plagiarism.modeling.ModelingPlagiarismResult)6