use of de.tum.in.www1.artemis.domain.participation.TutorParticipation in project Artemis by ls1intum.
the class TutorParticipationService method removeTutorParticipations.
/**
* This method removes the tutor participation for the example submission of an exercise
* @param exercise the exercise to which the example submission and tutor participation are linked to
* @param user the user for which the tutor participation should be removed
*/
public void removeTutorParticipations(Exercise exercise, User user) {
if (!tutorParticipationRepository.existsByAssessedExerciseIdAndTutorId(exercise.getId(), user.getId())) {
return;
}
Set<ExampleSubmission> exampleSubmissions = exampleSubmissionRepository.findAllByExerciseId(exercise.getId());
TutorParticipation tutorParticipation = tutorParticipationRepository.findWithEagerExampleSubmissionAndResultsByAssessedExerciseAndTutor(exercise, user);
for (ExampleSubmission exampleSubmission : exampleSubmissions) {
Optional<ExampleSubmission> exampleSubmissionWithTutorParticipation = exampleSubmissionRepository.findByIdWithResultsAndTutorParticipations(exampleSubmission.getId());
if (exampleSubmissionWithTutorParticipation.isPresent()) {
exampleSubmissionWithTutorParticipation.get().removeTutorParticipations(tutorParticipation);
tutorParticipationRepository.delete(tutorParticipation);
}
}
}
use of de.tum.in.www1.artemis.domain.participation.TutorParticipation in project Artemis by ls1intum.
the class AssessmentDashboardService method generateStatisticsForExercisesForAssessmentDashboard.
/**
* Prepares the exercises for the assessment dashboard by setting the tutor participations and statistics
* This is very slow as each iteration takes about 2.5 s
* @param exercises exercises to be prepared for the assessment dashboard
* @param tutorParticipations participations of the tutors
* @param examMode flag should be set for exam dashboard
*/
public void generateStatisticsForExercisesForAssessmentDashboard(Set<Exercise> exercises, List<TutorParticipation> tutorParticipations, boolean examMode) {
log.debug("generateStatisticsForExercisesForAssessmentDashboard invoked");
// start measures performance of each individual query, start2 measures performance of one loop iteration
long start = System.nanoTime();
long start2 = System.nanoTime();
long startComplete = System.nanoTime();
Set<Exercise> programmingExerciseIds = exercises.stream().filter(exercise -> exercise instanceof ProgrammingExercise).collect(Collectors.toSet());
Set<Exercise> nonProgrammingExerciseIds = exercises.stream().filter(exercise -> !(exercise instanceof ProgrammingExercise)).collect(Collectors.toSet());
complaintService.calculateNrOfOpenComplaints(exercises, examMode);
log.debug("Finished >> complaintService.calculateNrOfOpenComplaints all << in {}", TimeLogUtil.formatDurationFrom(start));
start = System.nanoTime();
calculateNumberOfSubmissions(programmingExerciseIds, nonProgrammingExerciseIds, examMode);
log.debug("Finished >> assessmentDashboardService.calculateNumberOfSubmissions all << in {}", TimeLogUtil.formatDurationFrom(start));
start = System.nanoTime();
// parts of this loop can possibly still be extracted
for (Exercise exercise : exercises) {
DueDateStat totalNumberOfAssessments;
if (exercise instanceof ProgrammingExercise) {
totalNumberOfAssessments = new DueDateStat(programmingExerciseRepository.countAssessmentsByExerciseIdSubmitted(exercise.getId(), examMode), 0L);
log.debug("Finished >> programmingExerciseRepository.countAssessmentsByExerciseIdSubmitted << call for exercise {} in {}", exercise.getId(), TimeLogUtil.formatDurationFrom(start));
} else {
totalNumberOfAssessments = resultRepository.countNumberOfFinishedAssessmentsForExercise(exercise.getId(), examMode);
log.debug("Finished >> resultRepository.countNumberOfFinishedAssessmentsForExercise << call for exercise {} in {}", exercise.getId(), TimeLogUtil.formatDurationFrom(start));
}
start = System.nanoTime();
final DueDateStat[] numberOfAssessmentsOfCorrectionRounds;
if (examMode) {
// set number of corrections specific to each correction round
int numberOfCorrectionRounds = exercise.getExerciseGroup().getExam().getNumberOfCorrectionRoundsInExam();
numberOfAssessmentsOfCorrectionRounds = resultRepository.countNumberOfFinishedAssessmentsForExamExerciseForCorrectionRounds(exercise, numberOfCorrectionRounds);
log.debug("Finished >> resultRepository.countNumberOfFinishedAssessmentsForExamExerciseForCorrectionRounds << call for exercise {} in {}", exercise.getId(), TimeLogUtil.formatDurationFrom(start));
} else {
// no examMode here, so correction rounds defaults to 1 and is the same as totalNumberOfAssessments
numberOfAssessmentsOfCorrectionRounds = new DueDateStat[] { totalNumberOfAssessments };
}
exercise.setNumberOfAssessmentsOfCorrectionRounds(numberOfAssessmentsOfCorrectionRounds);
exercise.setTotalNumberOfAssessments(numberOfAssessmentsOfCorrectionRounds[0]);
start = System.nanoTime();
Set<ExampleSubmission> exampleSubmissions = exampleSubmissionRepository.findAllWithResultByExerciseId(exercise.getId());
log.debug("Finished >> exampleSubmissionRepository.findAllWithResultByExerciseId << call for course {} in {}", exercise.getId(), TimeLogUtil.formatDurationFrom(start));
start = System.nanoTime();
// Do not provide example submissions without any assessment
exampleSubmissions.removeIf(exampleSubmission -> exampleSubmission.getSubmission() == null || exampleSubmission.getSubmission().getLatestResult() == null);
exercise.setExampleSubmissions(exampleSubmissions);
TutorParticipation tutorParticipation = tutorParticipations.stream().filter(participation -> participation.getAssessedExercise().getId().equals(exercise.getId())).findFirst().orElseGet(() -> {
TutorParticipation emptyTutorParticipation = new TutorParticipation();
emptyTutorParticipation.setStatus(TutorParticipationStatus.NOT_PARTICIPATED);
return emptyTutorParticipation;
});
exercise.setTutorParticipations(Collections.singleton(tutorParticipation));
var exerciseRating = ratingService.averageRatingByExerciseId(exercise.getId());
exercise.setAverageRating(exerciseRating.averageRating());
exercise.setNumberOfRatings(exerciseRating.numberOfRatings());
log.debug("Finished >> assessmentDashboardLoopIteration << call for exercise {} in {}", exercise.getId(), TimeLogUtil.formatDurationFrom(start2));
}
log.debug("Finished >> generateStatisticsForExercisesForAssessmentDashboard << call in {}", TimeLogUtil.formatDurationFrom(startComplete));
}
use of de.tum.in.www1.artemis.domain.participation.TutorParticipation in project Artemis by ls1intum.
the class TutorParticipationResource method assessExampleSubmissionForTutorParticipation.
/**
* POST /exercises/:exerciseId/assess-example-submission: Add an example submission to the tutor participation of the given exercise.
* If it is just for review (not used for tutorial), the method just records that the tutor has read it.
* If it is a tutorial, the method checks if the assessment given by the tutor matches the instructor one.
* If yes, then it returns the participation, if not, it returns an error.
*
* @param exerciseId the id of the exercise of the tutorParticipation
* @param exampleSubmission the example submission that will be added
* @return the ResponseEntity with status 200 (OK) and with body the exercise, or with status 404 (Not Found)
*/
@PostMapping(value = "/exercises/{exerciseId}/assess-example-submission")
@PreAuthorize("hasRole('TA')")
public ResponseEntity<TutorParticipation> assessExampleSubmissionForTutorParticipation(@PathVariable Long exerciseId, @RequestBody ExampleSubmission exampleSubmission) {
log.debug("REST request to add example submission to exercise id : {}", exerciseId);
Exercise exercise = this.exerciseRepository.findByIdElseThrow(exerciseId);
User user = userRepository.getUserWithGroupsAndAuthorities();
authorizationCheckService.checkHasAtLeastRoleForExerciseElseThrow(Role.TEACHING_ASSISTANT, exercise, user);
TutorParticipation resultTutorParticipation = tutorParticipationService.addExampleSubmission(exercise, exampleSubmission, user);
// Avoid infinite recursion for JSON
resultTutorParticipation.getTrainedExampleSubmissions().forEach(trainedExampleSubmission -> {
trainedExampleSubmission.setTutorParticipations(null);
trainedExampleSubmission.setExercise(null);
});
return ResponseEntity.ok().body(resultTutorParticipation);
}
use of de.tum.in.www1.artemis.domain.participation.TutorParticipation in project Artemis by ls1intum.
the class TutorParticipationResource method deleteTutorParticipationForGuidedTour.
/**
* DELETE /guided-tour/exercises/:exerciseId/example-submission: delete the tutor participation for example submissions of the "exerciseId" exercise for guided tutorials (e.g. when restarting a tutorial)
* Please note: all tutors can delete their own tutor participation for example submissions when it belongs to a guided tutorial
* @param exerciseId the exercise id which has example submissions and tutor participations
* @return the ResponseEntity with status 200 (OK) or 403 (FORBIDDEN)
*/
@DeleteMapping(value = "/guided-tour/exercises/{exerciseId}/example-submission")
@PreAuthorize("hasRole('TA')")
public ResponseEntity<TutorParticipation> deleteTutorParticipationForGuidedTour(@PathVariable Long exerciseId) {
log.debug("REST request to remove tutor participation of the example submission for exercise id : {}", exerciseId);
Exercise exercise = this.exerciseRepository.findByIdElseThrow(exerciseId);
User user = userRepository.getUserWithGroupsAndAuthorities();
// Allow all tutors to delete their own participation if it's for a tutorial
authorizationCheckService.checkHasAtLeastRoleForExerciseElseThrow(Role.TEACHING_ASSISTANT, exercise, user);
guidedTourConfiguration.checkExerciseForTutorialElseThrow(exercise);
tutorParticipationService.removeTutorParticipations(exercise, user);
return ResponseEntity.ok().headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, exerciseId.toString())).build();
}
use of de.tum.in.www1.artemis.domain.participation.TutorParticipation in project Artemis by ls1intum.
the class TutorParticipationResource method initTutorParticipation.
/**
* POST /exercises/:exerciseId/tutor-participations : start the "id" exercise for the current tutor. A tutor participation will be created and returned for the exercise given by
* the exercise id. The tutor participation status will be assigned based on which features are available for the exercise (e.g. grading instructions) The method is valid only
* for tutors, since it inits the tutor participation to the exercise, which is different from a standard participation
*
* @param exerciseId the id of the exercise for which to init a tutorParticipations
* @return the ResponseEntity with status 200 (OK) and with body the exercise, or with status 404 (Not Found)
* @throws URISyntaxException if URI path can't be created
*/
@PostMapping(value = "/exercises/{exerciseId}/tutor-participations")
@PreAuthorize("hasRole('TA')")
public ResponseEntity<TutorParticipation> initTutorParticipation(@PathVariable Long exerciseId) throws URISyntaxException {
log.debug("REST request to start tutor participation : {}", exerciseId);
Exercise exercise = exerciseRepository.findByIdElseThrow(exerciseId);
User user = userRepository.getUserWithGroupsAndAuthorities();
authorizationCheckService.checkHasAtLeastRoleForExerciseElseThrow(Role.TEACHING_ASSISTANT, exercise, user);
if (tutorParticipationRepository.existsByAssessedExerciseIdAndTutorId(exerciseId, user.getId())) {
// tutorParticipation already exists
return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert(applicationName, true, ENTITY_NAME, "tutorParticipationAlreadyExists", "There is already a tutorParticipations for the given exercise and user.")).body(null);
}
TutorParticipation tutorParticipation = tutorParticipationService.createNewParticipation(exercise, user);
return ResponseEntity.created(new URI("/api/exercises/" + exerciseId + "tutor-participations/" + tutorParticipation.getId())).body(tutorParticipation);
}
Aggregations