Skip to content

Commit

Permalink
Merge branch 'develop' into chore/plagiarism-checks/add-navigation-ca…
Browse files Browse the repository at this point in the history
…se-view
  • Loading branch information
AjayvirS authored Feb 24, 2025
2 parents 44ce01b + 59066cc commit 4730710
Show file tree
Hide file tree
Showing 22 changed files with 40 additions and 109 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ Refer to [Using JHipster in production](http://www.jhipster.tech/production) for
The following command can automate the deployment to a server. The example shows the deployment to the main Artemis test server (which runs a virtual machine):

```shell
./artemis-server-cli deploy username@artemis-test0.artemis.in.tum.de -w build/libs/Artemis-7.10.3.war
./artemis-server-cli deploy username@artemis-test0.artemis.in.tum.de -w build/libs/Artemis-8.0.0.war
```

## Architecture
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ plugins {
}

group = "de.tum.cit.aet.artemis"
version = "7.10.3"
version = "8.0.0"
description = "Interactive Learning with Individual Feedback"

java {
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "artemis",
"version": "7.10.3",
"version": "8.0.0",
"description": "Interactive Learning with Individual Feedback",
"private": true,
"license": "MIT",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,6 @@ public String getCreatedBy() {
return createdBy;
}

public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}

public Instant getCreatedDate() {
return createdDate;
}
Expand All @@ -62,15 +58,7 @@ public String getLastModifiedBy() {
return lastModifiedBy;
}

public void setLastModifiedBy(String lastModifiedBy) {
this.lastModifiedBy = lastModifiedBy;
}

public Instant getLastModifiedDate() {
return lastModifiedDate;
}

public void setLastModifiedDate(Instant lastModifiedDate) {
this.lastModifiedDate = lastModifiedDate;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1044,9 +1044,6 @@ public ResponseEntity<Set<User>> getAllUsersInGroup(Course course, String groupN
user.setActivationKey(null);
user.setLangKey(null);
user.setLastNotificationRead(null);
user.setLastModifiedBy(null);
user.setLastModifiedDate(null);
user.setCreatedBy(null);
user.setCreatedDate(null);
});
removeUserVariables(usersInGroup);
Expand Down Expand Up @@ -1201,9 +1198,6 @@ private void removeUserVariables(Iterable<User> usersInGroup) {
user.setActivationKey(null);
user.setLangKey(null);
user.setLastNotificationRead(null);
user.setLastModifiedBy(null);
user.setLastModifiedDate(null);
user.setCreatedBy(null);
user.setCreatedDate(null);
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

Expand All @@ -36,6 +37,7 @@
@EntityListeners(AuditingEntityListener.class)
public abstract class ExamLiveEvent extends DomainObject {

@CreatedBy
@Column(name = "created_by", nullable = false, length = 50, updatable = false)
private String createdBy;

Expand All @@ -53,18 +55,10 @@ public String getCreatedBy() {
return createdBy;
}

public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}

public Instant getCreatedDate() {
return createdDate;
}

public void setCreatedDate(Instant createdDate) {
this.createdDate = createdDate;
}

public Long getExamId() {
return examId;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import org.springframework.stereotype.Service;

import de.tum.cit.aet.artemis.communication.service.WebsocketMessagingService;
import de.tum.cit.aet.artemis.core.domain.User;
import de.tum.cit.aet.artemis.exam.domain.Exam;
import de.tum.cit.aet.artemis.exam.domain.StudentExam;
import de.tum.cit.aet.artemis.exam.domain.event.ExamAttendanceCheckEvent;
Expand Down Expand Up @@ -66,15 +65,13 @@ public ExamLiveEventsService(WebsocketMessagingService websocketMessagingService
*
* @param exam the exam to send the announcement to.
* @param message The message to send.
* @param sentBy The user who sent the message.
* @return The created event.
*/
public ExamWideAnnouncementEvent createAndDistributeExamAnnouncementEvent(Exam exam, String message, User sentBy) {
public ExamWideAnnouncementEvent createAndDistributeExamAnnouncementEvent(Exam exam, String message) {
var event = new ExamWideAnnouncementEvent();

// Common fields
event.setExamId(exam.getId());
event.setCreatedBy(sentBy.getName());

// Specific fields
event.setTextContent(message);
Expand All @@ -87,16 +84,14 @@ public ExamWideAnnouncementEvent createAndDistributeExamAnnouncementEvent(Exam e
*
* @param studentExam The student exam the where the popup should be shown
* @param message The message to send.
* @param sentBy The user who sent the message.
* @return The created event.
*/
public ExamAttendanceCheckEvent createAndSendExamAttendanceCheckEvent(StudentExam studentExam, String message, User sentBy) {
public ExamAttendanceCheckEvent createAndSendExamAttendanceCheckEvent(StudentExam studentExam, String message) {
var event = new ExamAttendanceCheckEvent();

// Common fields
event.setExamId(studentExam.getExam().getId());
event.setStudentExamId(studentExam.getId());
event.setCreatedBy(sentBy.getName());

// specific fields
event.setTextContent(message);
Expand All @@ -111,15 +106,13 @@ public ExamAttendanceCheckEvent createAndSendExamAttendanceCheckEvent(StudentExa
* @param newWorkingTime The new working time in seconds
* @param oldWorkingTime The old working time in seconds
* @param courseWide set to true if this event is caused by a course wide update that affects all students; false otherwise
* @param sentBy The user who performed the update
*/
public void createAndSendWorkingTimeUpdateEvent(StudentExam studentExam, int newWorkingTime, int oldWorkingTime, boolean courseWide, User sentBy) {
public void createAndSendWorkingTimeUpdateEvent(StudentExam studentExam, int newWorkingTime, int oldWorkingTime, boolean courseWide) {
var event = new WorkingTimeUpdateEvent();

// Common fields
event.setExamId(studentExam.getExam().getId());
event.setStudentExamId(studentExam.getId());
event.setCreatedBy(sentBy.getName());

// Specific fields
event.setNewWorkingTime(newWorkingTime);
Expand All @@ -132,15 +125,14 @@ public void createAndSendWorkingTimeUpdateEvent(StudentExam studentExam, int new
/**
* Send a problem statement update to all affected students.
*
* @param exercise The exam exercise the problem statement was updated for
* @param message The message to send
* @param instructor The user who performed the update
* @param exercise The exam exercise the problem statement was updated for
* @param message The message to send
*/
@Async
public void createAndSendProblemStatementUpdateEvent(Exercise exercise, String message, User instructor) {
public void createAndSendProblemStatementUpdateEvent(Exercise exercise, String message) {
Exam exam = exercise.getExam();
studentExamRepository.findAllWithExercisesByExamId(exam.getId()).stream().filter(studentExam -> studentExam.getExercises().contains(exercise))
.forEach(studentExam -> this.createAndSendProblemStatementUpdateEvent(studentExam, exercise, message, instructor));
.forEach(studentExam -> this.createAndSendProblemStatementUpdateEvent(studentExam, exercise, message));
}

/**
Expand All @@ -149,15 +141,13 @@ public void createAndSendProblemStatementUpdateEvent(Exercise exercise, String m
* @param studentExam The student exam containing the exercise with updated problem statement
* @param exercise The updated exercise
* @param message The message to send
* @param sentBy The user who performed the update
*/
public void createAndSendProblemStatementUpdateEvent(StudentExam studentExam, Exercise exercise, String message, User sentBy) {
public void createAndSendProblemStatementUpdateEvent(StudentExam studentExam, Exercise exercise, String message) {
var event = new ProblemStatementUpdateEvent();

// Common fields
event.setExamId(studentExam.getExam().getId());
event.setStudentExamId(studentExam.getId());
event.setCreatedBy(sentBy.getName());

// Specific fields
event.setTextContent(message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1447,7 +1447,7 @@ public void updateStudentExamsAndRescheduleExercises(Exam exam, int originalExam

// NOTE: if the exam is already visible, notify the student about the working time change
if (now.isAfter(exam.getVisibleDate())) {
examLiveEventsService.createAndSendWorkingTimeUpdateEvent(studentExam, studentExam.getWorkingTime(), originalStudentWorkingTime, true, instructor);
examLiveEventsService.createAndSendWorkingTimeUpdateEvent(studentExam, studentExam.getWorkingTime(), originalStudentWorkingTime, true);
}
}
studentExamRepository.saveAll(studentExams);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@
import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastInstructor;
import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastStudent;
import de.tum.cit.aet.artemis.core.security.annotations.EnforceAtLeastTutor;
import de.tum.cit.aet.artemis.core.security.annotations.enforceRoleInCourse.EnforceAtLeastInstructorInCourse;
import de.tum.cit.aet.artemis.core.service.AuthorizationCheckService;
import de.tum.cit.aet.artemis.core.service.feature.Feature;
import de.tum.cit.aet.artemis.core.service.feature.FeatureToggle;
Expand Down Expand Up @@ -361,7 +360,7 @@ public ResponseEntity<ExamWideAnnouncementEventDTO> createExamAnnouncement(@Path
throw new BadRequestAlertException("Exam is not visible to students", "exam", "examNotVisible");
}

var event = examLiveEventsService.createAndDistributeExamAnnouncementEvent(exam, message, userRepository.getUser());
var event = examLiveEventsService.createAndDistributeExamAnnouncementEvent(exam, message);
log.debug("createExamAnnouncement took {} for exam {}", TimeLogUtil.formatDurationFrom(start), examId);
return ResponseEntity.ok(event.asDTO());
}
Expand Down Expand Up @@ -1335,8 +1334,9 @@ public ResponseEntity<Set<SuspiciousExamSessionsDTO>> getAllSuspiciousExamSessio
* @return the ResponseEntity with status 200 (OK) and with body a summary of the deletion of the exam
*/
@GetMapping("courses/{courseId}/exams/{examId}/deletion-summary")
@EnforceAtLeastInstructorInCourse
@EnforceAtLeastInstructor
public ResponseEntity<ExamDeletionSummaryDTO> getDeletionSummary(@PathVariable long courseId, @PathVariable long examId) {
examAccessService.checkCourseAndExamAccessForInstructorElseThrow(courseId, examId);
log.debug("REST request to get deletion summary for exam : {}", examId);
return ResponseEntity.ok(examDeletionService.getExamDeletionSummary(examId));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,6 @@ public class StudentExamResource {

private final ExamLiveEventRepository examLiveEventRepository;

private static final boolean IS_TEST_RUN = false;

@Value("${info.student-exam-store-session-data:#{true}}")
private boolean storeSessionDataInStudentExamSession;

Expand Down Expand Up @@ -251,7 +249,7 @@ public ResponseEntity<StudentExam> updateWorkingTime(@PathVariable Long courseId
Exam exam = examService.findByIdWithExerciseGroupsAndExercisesElseThrow(examId, false);
if (now.isAfter(exam.getVisibleDate())) {
instanceMessageSendService.sendStudentExamIndividualWorkingTimeChangeDuringConduction(studentExamId);
examLiveEventsService.createAndSendWorkingTimeUpdateEvent(savedStudentExam, workingTime, originalWorkingTime, false, userRepository.getUser());
examLiveEventsService.createAndSendWorkingTimeUpdateEvent(savedStudentExam, workingTime, originalWorkingTime, false);
}
if (now.isBefore(examDateService.getLatestIndividualExamEndDate(exam))) {
// potentially re-schedule clustering of modeling submissions (in case Compass is active)
Expand Down Expand Up @@ -279,7 +277,7 @@ public ResponseEntity<ExamAttendanceCheckEventDTO> attendanceCheck(@PathVariable

var student = userRepository.getUserByLoginElseThrow(studentLogin);

StudentExam studentExam = studentExamRepository.findWithExercisesByUserIdAndExamId(student.getId(), examId, IS_TEST_RUN).orElseThrow();
StudentExam studentExam = studentExamRepository.findWithExercisesByUserIdAndExamId(student.getId(), examId, false).orElseThrow();

examAccessService.checkCourseAndExamAndStudentExamAccessElseThrow(courseId, examId, studentExam.getId());

Expand All @@ -288,8 +286,7 @@ public ResponseEntity<ExamAttendanceCheckEventDTO> attendanceCheck(@PathVariable
throw new BadRequestAlertException("Exam is not visible to students", "exam", "examNotVisible");
}

User currentUser = userRepository.getUser();
var event = examLiveEventsService.createAndSendExamAttendanceCheckEvent(studentExam, message, currentUser);
var event = examLiveEventsService.createAndSendExamAttendanceCheckEvent(studentExam, message);

return ResponseEntity.ok(event.asDTO());
}
Expand Down Expand Up @@ -364,7 +361,7 @@ public ResponseEntity<StudentExam> getStudentExamForConduction(@PathVariable Lon
HttpServletRequest request) {
long start = System.currentTimeMillis();
User currentUser = userRepository.getUserWithGroupsAndAuthorities();
log.debug("REST request to get the student exam of user {} for exam {}", currentUser.getLogin(), examId);
log.debug("REST request to get the student exam of user {} for exam {} for conduction", currentUser.getLogin(), examId);

StudentExam studentExam = studentExamRepository.findByIdWithExercisesElseThrow(studentExamId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;
import static org.springframework.data.jpa.repository.EntityGraph.EntityGraphType.LOAD;

import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
Expand Down Expand Up @@ -139,11 +138,6 @@ default Team save(Exercise exercise, Team team) {
if (!conflicts.isEmpty()) {
throw new StudentsAlreadyAssignedException(conflicts);
}
// audit information is normally updated automatically but since changes in the many-to-many relationships are not registered,
// we need to trigger the audit explicitly by modifying a column of the team entity itself
if (team.getId() != null) {
team.setLastModifiedDate(Instant.now());
}
team.setExercise(exercise);
team = save(team);
return findWithStudentsByIdElseThrow(team.getId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -796,7 +796,7 @@ public void notifyAboutExerciseChanges(Exercise originalExercise, Exercise updat
else if (now().plusMinutes(EXAM_START_WAIT_TIME_MINUTES).isAfter(originalExercise.getExam().getStartDate()) && originalExercise.isExamExercise()
&& !StringUtils.equals(originalExercise.getProblemStatement(), updatedExercise.getProblemStatement())) {
User instructor = userRepository.getUser();
this.examLiveEventsService.createAndSendProblemStatementUpdateEvent(updatedExercise, notificationText, instructor);
this.examLiveEventsService.createAndSendProblemStatementUpdateEvent(updatedExercise, notificationText);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package de.tum.cit.aet.artemis.plagiarism.web;

import static de.tum.cit.aet.artemis.core.config.Constants.SYSTEM_ACCOUNT;

import java.util.Objects;
import java.util.stream.DoubleStream;
import java.util.stream.Stream;

Expand All @@ -19,8 +16,6 @@
*/
public class PlagiarismResultResponseBuilder {

private static final String CONTINUOUS_PLAGIARISM_CONTROL_CREATED_BY_VALUE = "CPC";

private PlagiarismResultResponseBuilder() {
}

Expand All @@ -41,22 +36,12 @@ public static <E extends PlagiarismResult<? extends PlagiarismSubmissionElement>
.flatMap(comparison -> Stream.of(comparison.getSubmissionA().getSubmissionId(), comparison.getSubmissionB().getSubmissionId())).distinct().count();
double averageSimilarity = getSimilarities(plagiarismResult).average().orElse(0.0);
double maximalSimilarity = getSimilarities(plagiarismResult).max().orElse(0.0);
var createdBy = getCreatedBy(plagiarismResult);
var stats = new PlagiarismResultStats(numberOfDetectedSubmissions, averageSimilarity, maximalSimilarity, createdBy);
var stats = new PlagiarismResultStats(numberOfDetectedSubmissions, averageSimilarity, maximalSimilarity, plagiarismResult.getCreatedBy());

return ResponseEntity.ok(new PlagiarismResultDTO<>(plagiarismResult, stats));
}

private static DoubleStream getSimilarities(PlagiarismResult<?> plagiarismResult) {
return plagiarismResult.getComparisons().stream().mapToDouble(PlagiarismComparison::getSimilarity);
}

private static String getCreatedBy(PlagiarismResult<?> result) {
if (Objects.equals(result.getCreatedBy(), SYSTEM_ACCOUNT)) {
return CONTINUOUS_PLAGIARISM_CONTROL_CREATED_BY_VALUE;
}
else {
return result.getCreatedBy();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -866,7 +866,7 @@ void testExamAnnouncementSent() throws Exception {

assertThat(result.id()).isGreaterThan(0L);
assertThat(result.text()).isEqualTo(testMessage);
assertThat(result.createdBy()).isEqualTo(userUtilService.getUserByLogin(TEST_PREFIX + "instructor1").getName());
assertThat(result.createdBy()).isEqualTo(userUtilService.getUserByLogin(TEST_PREFIX + "instructor1").getLogin());
assertThat(result.createdDate()).isCloseTo(Instant.now(), within(5, ChronoUnit.SECONDS));

var event = captureExamLiveEventForId(exam1.getId(), true);
Expand Down Expand Up @@ -897,7 +897,7 @@ void testExamAttendanceCheck() throws Exception {

assertThat(result.id()).isGreaterThan(0L);
assertThat(result.text()).isEqualTo(testMessage);
assertThat(result.createdBy()).isEqualTo(userUtilService.getUserByLogin(TEST_PREFIX + "instructor1").getName());
assertThat(result.createdBy()).isEqualTo(userUtilService.getUserByLogin(TEST_PREFIX + "instructor1").getLogin());
assertThat(result.createdDate()).isCloseTo(Instant.now(), within(5, ChronoUnit.SECONDS));

}
Expand Down
Loading

0 comments on commit 4730710

Please sign in to comment.