use of de.tum.in.www1.artemis.domain.participation.Participation 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();
}
}
use of de.tum.in.www1.artemis.domain.participation.Participation in project ArTEMiS by ls1intum.
the class LearningGoalService method calculateLearningGoalCourseProgress.
/**
* Calculate the progress in a learning goal for a whole course
*
* @param useParticipantScoreTable use the participant score table instead of going through participation -> submission -> result
* @param learningGoal learning goal to get the progress for
* @return progress of the course in the learning goal
*/
public CourseLearningGoalProgress calculateLearningGoalCourseProgress(LearningGoal learningGoal, boolean useParticipantScoreTable) {
CourseLearningGoalProgress courseLearningGoalProgress = new CourseLearningGoalProgress();
courseLearningGoalProgress.courseId = learningGoal.getCourse().getId();
courseLearningGoalProgress.learningGoalId = learningGoal.getId();
courseLearningGoalProgress.learningGoalTitle = learningGoal.getTitle();
courseLearningGoalProgress.totalPointsAchievableByStudentsInLearningGoal = 0.0;
courseLearningGoalProgress.averagePointsAchievedByStudentInLearningGoal = 0.0;
// The progress will be calculated from a subset of the connected lecture units (currently only from released exerciseUnits)
List<ExerciseUnit> exerciseUnitsUsableForProgressCalculation = learningGoal.getLectureUnits().parallelStream().filter(LectureUnit::isVisibleToStudents).filter(lectureUnit -> lectureUnit instanceof ExerciseUnit).map(lectureUnit -> (ExerciseUnit) lectureUnit).collect(Collectors.toList());
Set<CourseLearningGoalProgress.CourseLectureUnitProgress> progressInLectureUnits = this.calculateExerciseUnitsProgressForCourse(exerciseUnitsUsableForProgressCalculation, useParticipantScoreTable);
// updating learningGoalPerformance by summing up the points of the individual lecture unit progress
courseLearningGoalProgress.totalPointsAchievableByStudentsInLearningGoal = progressInLectureUnits.stream().map(lectureUnitProgress -> lectureUnitProgress.totalPointsAchievableByStudentsInLectureUnit).reduce(0.0, Double::sum);
courseLearningGoalProgress.averagePointsAchievedByStudentInLearningGoal = progressInLectureUnits.stream().map(lectureUnitProgress -> (lectureUnitProgress.averageScoreAchievedByStudentInLectureUnit / 100.0) * lectureUnitProgress.totalPointsAchievableByStudentsInLectureUnit).reduce(0.0, Double::sum);
courseLearningGoalProgress.progressInLectureUnits = new ArrayList<>(progressInLectureUnits);
return courseLearningGoalProgress;
}
use of de.tum.in.www1.artemis.domain.participation.Participation in project ArTEMiS by ls1intum.
the class JenkinsService method onBuildCompleted.
@Override
public Result onBuildCompleted(ProgrammingExerciseParticipation participation, Object requestBody) {
final var buildResult = TestResultsDTO.convert(requestBody);
var newResult = createResultFromBuildResult(buildResult, participation);
// Fetch submission or create a fallback
var latestSubmission = super.getSubmissionForBuildResult(participation.getId(), buildResult).orElseGet(() -> createAndSaveFallbackSubmission(participation, buildResult));
latestSubmission.setBuildFailed("No tests found".equals(newResult.getResultString()));
// Parse, filter, and save the build logs if they exist
if (buildResult.getLogs() != null) {
ProgrammingLanguage programmingLanguage = participation.getProgrammingExercise().getProgrammingLanguage();
List<BuildLogEntry> buildLogEntries = JenkinsBuildLogParseUtils.parseBuildLogsFromJenkinsLogs(buildResult.getLogs());
buildLogEntries = filterUnnecessaryLogs(buildLogEntries, programmingLanguage);
buildLogEntries = buildLogService.saveBuildLogs(buildLogEntries, latestSubmission);
// Set the received logs in order to avoid duplicate entries (this removes existing logs)
latestSubmission.setBuildLogEntries(buildLogEntries);
}
// Note: we only set one side of the relationship because we don't know yet whether the result will actually be saved
newResult.setSubmission(latestSubmission);
newResult.setRatedIfNotExceeded(exerciseDateService.getDueDate(participation).orElse(null), latestSubmission);
return newResult;
}
use of de.tum.in.www1.artemis.domain.participation.Participation in project ArTEMiS by ls1intum.
the class DatabaseUtilService method addResultToParticipation.
public Result addResultToParticipation(Participation participation, Submission submission) {
Result result = new Result().participation(participation).resultString("x of y passed").successful(true).score(100D);
result = resultRepo.save(result);
result.setSubmission(submission);
submission.addResult(result);
submission.setParticipation(participation);
submissionRepository.save(submission);
return result;
}
use of de.tum.in.www1.artemis.domain.participation.Participation in project ArTEMiS by ls1intum.
the class DatabaseUtilService method addProgrammingSubmissionWithResult.
/**
* Add a submission with a result to the given programming exercise. The submission will be assigned to the corresponding participation of the given login (if exists or create a new participation).
* The method will make sure that all necessary entities are connected.
*
* @param exercise for which to create the submission/participation/result combination.
* @param submission to use for adding to the exercise/participation/result.
* @param login of the user to identify the corresponding student participation.
*/
public void addProgrammingSubmissionWithResult(ProgrammingExercise exercise, ProgrammingSubmission submission, String login) {
StudentParticipation participation = addStudentParticipationForProgrammingExercise(exercise, login);
submission = programmingSubmissionRepo.save(submission);
Result result = resultRepo.save(new Result().participation(participation));
participation.addSubmission(submission);
submission.setParticipation(participation);
submission.addResult(result);
submission = programmingSubmissionRepo.save(submission);
result.setSubmission(submission);
result = resultRepo.save(result);
participation.addResult(result);
studentParticipationRepo.save(participation);
}
Aggregations