Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plagiarism checks: Add possibility for continuous daily plagiarism checks #6666

Merged
merged 97 commits into from
Aug 12, 2023
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
6156876
daily plagiarism checks
jakubriegel Jun 3, 2023
0060764
autoincrement plagiarism_checks_config id
jakubriegel Jun 5, 2023
67ce9fa
plagiarisms configuration form for text exercises
jakubriegel Jun 5, 2023
483589b
plagiarisms configuration form for modeling exercises
jakubriegel Jun 5, 2023
2b5510a
plagiarisms configuration form for programming exercises
jakubriegel Jun 5, 2023
b43670d
stored config for manual plagiarisms detection
jakubriegel Jun 6, 2023
4c63376
erge remote-tracking branch 'origin/develop' into automated-plagiaris…
jakubriegel Jun 6, 2023
b9f2132
fix broken flows and tests
jakubriegel Jun 8, 2023
d39dd75
add javadoc for cpc schedule
jakubriegel Jun 8, 2023
41318fa
make cpc exercise members optional in the client
jakubriegel Jun 8, 2023
806923f
fix FileUploadExerciseIntegrationTest
jakubriegel Jun 8, 2023
63d2eb4
fix null safe property access
jakubriegel Jun 8, 2023
ff2bd75
remove redundant empty constructor
jakubriegel Jun 8, 2023
2870563
Add javadoc
jakubriegel Jun 8, 2023
e0ab20a
Fix /100 for modelling exercises
jakubriegel Jun 10, 2023
d2eb8eb
Create unit test for ContinuousPlagiarismControlService
jakubriegel Jun 10, 2023
cf84bd5
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jun 10, 2023
88d22c9
Add default value for continuous_plagiarism_control_enabled
jakubriegel Jun 10, 2023
a122c00
Change Detection -> Plagiarism detection
jakubriegel Jun 10, 2023
f263939
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jun 11, 2023
321aeb4
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jun 12, 2023
6e395ff
change de caution msg
jakubriegel Jun 12, 2023
662d31f
add similarity threshold test for programming ex. form
jakubriegel Jun 13, 2023
52e76f0
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jun 13, 2023
d2e90d2
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jun 14, 2023
6e28701
fix loading existing plagiarism checks config in the client
jakubriegel Jun 17, 2023
7e25c6d
enable lazy loading of plagiarism checks config; separate PlagiarismC…
jakubriegel Jun 17, 2023
920becb
merge develop and fix tests
jakubriegel Jun 18, 2023
1e4b599
fix code style
jakubriegel Jun 18, 2023
94f4f36
fix code style
jakubriegel Jun 18, 2023
92f10fe
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jun 18, 2023
75f800f
revert debug code
jakubriegel Jun 18, 2023
dd32d03
add missing javadoc
jakubriegel Jun 18, 2023
00d5dcc
merge develop
jakubriegel Jun 24, 2023
9b5490c
fix generateJPlagReport always shown
jakubriegel Jun 24, 2023
74f9b88
fix codestyle (codacy)
jakubriegel Jun 26, 2023
cb379e4
Merge branch 'develop' into automated-plagiarism-checks
jakubriegel Jun 26, 2023
60c5d98
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jun 26, 2023
de32589
merge develop
jakubriegel Jun 30, 2023
6536f1f
merge develop
jakubriegel Jul 1, 2023
a7bce9d
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 1, 2023
e581f12
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 1, 2023
08e8127
remove unnecessary default value
jakubriegel Jul 1, 2023
4410402
rename type
jakubriegel Jul 1, 2023
d86bc85
fix german copy
jakubriegel Jul 1, 2023
0129c23
move continuousPlagiarismControlEnabled to PlagiarismChecksConfig
jakubriegel Jul 1, 2023
2dbb57a
make exercise.plagiarismChecksConfig non null
jakubriegel Jul 1, 2023
611bf50
remove unused import
jakubriegel Jul 1, 2023
aaef7a9
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 2, 2023
0af7ae3
fix german copy
jakubriegel Jul 2, 2023
395a37a
Merge branch 'develop' into automated-plagiarism-checks
jakubriegel Jul 3, 2023
a65d37e
fix tests
jakubriegel Jul 3, 2023
d3645ae
remove unnecessary assignment
jakubriegel Jul 4, 2023
cb13aef
assert that nothing is thrown
jakubriegel Jul 4, 2023
3b99e9f
add nullability to fix compiler issues
jakubriegel Jul 4, 2023
d445b99
replace junit with assertj
jakubriegel Jul 4, 2023
4eebe33
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 5, 2023
5c09ed3
add setting continuousPlagiarismControlEnabled on PlagiarismChecksCon…
jakubriegel Jul 5, 2023
bb18252
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 7, 2023
6a40dc9
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 8, 2023
0d8b61d
read cron expression from application.yml
jakubriegel Jul 8, 2023
7243d27
add beta badge to cpc enabled setting and move it below plagiarism co…
jakubriegel Jul 8, 2023
0c79470
add cpc tooltip on exercise form
jakubriegel Jul 8, 2023
65653e5
improve styling of plagiarism detection config
jakubriegel Jul 8, 2023
4faae2e
set cpc cron for 4am
jakubriegel Jul 8, 2023
44a90ad
fix german translation
jakubriegel Jul 8, 2023
16775d6
fix singular form
jakubriegel Jul 8, 2023
b79855b
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 8, 2023
9121863
Update src/main/webapp/i18n/en/plagiarism.json
jakubriegel Jul 9, 2023
01eb73e
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 12, 2023
2f665ab
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 13, 2023
66c0aea
fix input naming
jakubriegel Jul 16, 2023
b9e0ad1
merge develop
jakubriegel Jul 16, 2023
cf2066d
add colons to plagiarism configuration labels
jakubriegel Jul 16, 2023
e0b7ce0
add missing @Column
jakubriegel Jul 16, 2023
a534bda
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 20, 2023
22407a3
fix default value type
jakubriegel Jul 20, 2023
78f34a4
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 24, 2023
5b29dc3
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 25, 2023
215fd09
move migration to the end
jakubriegel Jul 25, 2023
90363ab
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 25, 2023
01e00fe
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Jul 26, 2023
0e268ca
Development: Explicitly state the actor of the performance reviewer's…
maximiliansoelch Jul 26, 2023
2516380
Development: Add hint for windows to local version control and contin…
laurenzfb Jul 26, 2023
852e6bd
Development: Delete old files properly when updating file submissions…
MarkusPaulsen Jul 26, 2023
51f1a8b
Development: Improve programming exercise file response (#6989)
pal03377 Jul 26, 2023
31ce700
Development: Use 1.0 instead of 1.0+ for sticky grade to avoid castin…
Jul 26, 2023
c4b47ba
Development: Fix an issue when catching exceptions during a quiz
Jul 26, 2023
719c4c5
Development: Bump version to 6.3.9
Jul 26, 2023
3c08a37
merge develop
jakubriegel Jul 30, 2023
8af4981
Merge branch 'develop' into automated-plagiarism-checks
jakubriegel Aug 2, 2023
c41d587
Merge remote-tracking branch 'origin/develop' into automated-plagiari…
jakubriegel Aug 4, 2023
f1edae4
disable scheduling for migration tests
jakubriegel Aug 4, 2023
d848265
fix continuous_plagiarism_control_enabled type
jakubriegel Aug 4, 2023
4f13f18
add localci to migration tests
jakubriegel Aug 4, 2023
63665bc
make programmingLanguageFeatureService optional
jakubriegel Aug 4, 2023
3af111d
revert migration check env
jakubriegel Aug 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/main/java/de/tum/in/www1/artemis/domain/Exercise.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import de.tum.in.www1.artemis.domain.participation.StudentParticipation;
import de.tum.in.www1.artemis.domain.participation.TutorParticipation;
import de.tum.in.www1.artemis.domain.plagiarism.PlagiarismCase;
import de.tum.in.www1.artemis.domain.plagiarism.PlagiarismChecksConfig;
import de.tum.in.www1.artemis.domain.quiz.QuizExercise;
import de.tum.in.www1.artemis.domain.view.QuizView;
import de.tum.in.www1.artemis.web.rest.dto.DueDateStat;
Expand Down Expand Up @@ -140,6 +141,13 @@ public abstract class Exercise extends BaseExercise implements LearningObject {
@JsonIncludeProperties({ "id" })
private Set<PlagiarismCase> plagiarismCases = new HashSet<>();

@Column(name = "continuous_plagiarism_control_enabled")
private boolean continuousPlagiarismControlEnabled = false;
julian-christl marked this conversation as resolved.
Show resolved Hide resolved

@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
jakubriegel marked this conversation as resolved.
Show resolved Hide resolved
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private PlagiarismChecksConfig plagiarismChecksConfig = new PlagiarismChecksConfig();
jakubriegel marked this conversation as resolved.
Show resolved Hide resolved

// NOTE: Helpers variable names must be different from Getter name, so that Jackson ignores the @Transient annotation, but Hibernate still respects it
@Transient
private DueDateStat numberOfSubmissionsTransient;
Expand Down Expand Up @@ -391,6 +399,22 @@ public void setPlagiarismCases(Set<PlagiarismCase> plagiarismCases) {
this.plagiarismCases = plagiarismCases;
}

public boolean isContinuousPlagiarismControlEnabled() {
return continuousPlagiarismControlEnabled;
}

public void setContinuousPlagiarismControlEnabled(boolean continuousPlagiarismControlEnabled) {
this.continuousPlagiarismControlEnabled = continuousPlagiarismControlEnabled;
}

public PlagiarismChecksConfig getPlagiarismChecksConfig() {
return plagiarismChecksConfig;
}

public void setPlagiarismChecksConfig(PlagiarismChecksConfig plagiarismChecksConfig) {
this.plagiarismChecksConfig = plagiarismChecksConfig;
}

// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove

public Set<Competency> getCompetencies() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package de.tum.in.www1.artemis.domain.plagiarism;

import javax.persistence.Entity;
import javax.persistence.Table;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import com.fasterxml.jackson.annotation.JsonInclude;

import de.tum.in.www1.artemis.domain.DomainObject;

/**
* Stores configuration for manual and continuous plagiarism control.
*/
@Entity
@Table(name = "plagiarism_checks_config")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class PlagiarismChecksConfig extends DomainObject {

private float similarityThreshold;

private int minimumScore;

private int minimumSize;

public float getSimilarityThreshold() {
return similarityThreshold;
}

public int getMinimumScore() {
return minimumScore;
}

public int getMinimumSize() {
return minimumSize;
}

public void setSimilarityThreshold(float similarityThreshold) {
this.similarityThreshold = similarityThreshold;
}

public void setMinimumScore(int minimumScore) {
this.minimumScore = minimumScore;
}

public void setMinimumSize(int minimumSize) {
this.minimumSize = minimumSize;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,15 @@ public interface ExerciseRepository extends JpaRepository<Exercise, Long> {
""")
Set<Exercise> findAllExercisesWithCurrentOrUpcomingDueDate(@Param("now") ZonedDateTime now);

@Query("""
SELECT e FROM Exercise e
WHERE e.course.testCourse = FALSE
AND e.dueDate >= :now
AND e.continuousPlagiarismControlEnabled = TRUE
ORDER BY e.dueDate ASC
""")
Set<Exercise> findAllExercisesWithCurrentOrUpcomingDueDateAndContinuousPlagiarismControlEnabledIsTrue(@Param("now") ZonedDateTime now);

@Query("""
SELECT e FROM Exercise e
WHERE e.course.testCourse = FALSE
Expand Down Expand Up @@ -474,6 +483,16 @@ default Set<Exercise> findAllExercisesWithCurrentOrUpcomingDueDate() {
return findAllExercisesWithCurrentOrUpcomingDueDate(ZonedDateTime.now().truncatedTo(ChronoUnit.DAYS));
}

/**
* Finds all exercises where the due date is today or in the future and continuos plagiarism control is enabled
* (does not return exercises belonging to test courses).
*
* @return set of exercises
*/
default Set<Exercise> findAllExercisesWithCurrentOrUpcomingDueDateAndContinuousPlagiarismControlEnabledIsTrue() {
return findAllExercisesWithCurrentOrUpcomingDueDateAndContinuousPlagiarismControlEnabledIsTrue(ZonedDateTime.now().truncatedTo(ChronoUnit.DAYS));
}

/**
* Find exercise by exerciseId and load participations in this exercise.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import de.tum.in.www1.artemis.domain.*;
import de.tum.in.www1.artemis.domain.enumeration.ExerciseMode;
import de.tum.in.www1.artemis.domain.plagiarism.PlagiarismChecksConfig;
import de.tum.in.www1.artemis.repository.*;

public abstract class ExerciseImportService {
Expand Down Expand Up @@ -59,6 +60,11 @@ void copyExerciseBasis(final Exercise newExercise, final Exercise importedExerci
newExercise.setTeamAssignmentConfig(importedExercise.getTeamAssignmentConfig().copyTeamAssignmentConfig());
}
}
var plagiarismChecksConfig = new PlagiarismChecksConfig();
plagiarismChecksConfig.setSimilarityThreshold(importedExercise.getPlagiarismChecksConfig().getSimilarityThreshold());
plagiarismChecksConfig.setMinimumSize(importedExercise.getPlagiarismChecksConfig().getMinimumSize());
plagiarismChecksConfig.setMinimumScore(importedExercise.getPlagiarismChecksConfig().getMinimumScore());
newExercise.setPlagiarismChecksConfig(plagiarismChecksConfig);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package de.tum.in.www1.artemis.service.plagiarism;

import org.jvnet.hk2.annotations.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import de.jplag.exceptions.ExitException;
import de.tum.in.www1.artemis.domain.Exercise;
import de.tum.in.www1.artemis.domain.ProgrammingExercise;
import de.tum.in.www1.artemis.domain.TextExercise;
import de.tum.in.www1.artemis.domain.modeling.ModelingExercise;
import de.tum.in.www1.artemis.repository.ExerciseRepository;
import de.tum.in.www1.artemis.repository.ModelingExerciseRepository;
import de.tum.in.www1.artemis.repository.ProgrammingExerciseRepository;
import de.tum.in.www1.artemis.repository.TextExerciseRepository;
import de.tum.in.www1.artemis.repository.plagiarism.PlagiarismResultRepository;
import de.tum.in.www1.artemis.service.programming.ProgrammingLanguageFeatureService;
import de.tum.in.www1.artemis.service.util.TimeLogUtil;

/**
* Manages continuous plagiarism control.
*/
@Service
@Component
@Profile("scheduling")
public class ContinuousPlagiarismControlService {

private static final Logger log = LoggerFactory.getLogger(ContinuousPlagiarismControlService.class);

private final ExerciseRepository exerciseRepository;

private final TextExerciseRepository textExerciseRepository;

private final TextPlagiarismDetectionService textPlagiarismDetectionService;

private final ProgrammingExerciseRepository programmingExerciseRepository;

private final ProgrammingLanguageFeatureService programmingLanguageFeatureService;

private final ProgrammingPlagiarismDetectionService programmingPlagiarismDetectionService;

private final ModelingExerciseRepository modelingExerciseRepository;

private final ModelingPlagiarismDetectionService modelingPlagiarismDetectionService;

private final PlagiarismResultRepository plagiarismResultRepository;

public ContinuousPlagiarismControlService(ExerciseRepository exerciseRepository, TextExerciseRepository textExerciseRepository,
TextPlagiarismDetectionService textPlagiarismDetectionService, ProgrammingExerciseRepository programmingExerciseRepository,
ProgrammingLanguageFeatureService programmingLanguageFeatureService, ProgrammingPlagiarismDetectionService programmingPlagiarismDetectionService,
ModelingExerciseRepository modelingExerciseRepository, ModelingPlagiarismDetectionService modelingPlagiarismDetectionService,
PlagiarismResultRepository plagiarismResultRepository) {
this.exerciseRepository = exerciseRepository;
this.textExerciseRepository = textExerciseRepository;
this.textPlagiarismDetectionService = textPlagiarismDetectionService;
this.programmingExerciseRepository = programmingExerciseRepository;
this.programmingLanguageFeatureService = programmingLanguageFeatureService;
this.programmingPlagiarismDetectionService = programmingPlagiarismDetectionService;
this.modelingExerciseRepository = modelingExerciseRepository;
this.modelingPlagiarismDetectionService = modelingPlagiarismDetectionService;
this.plagiarismResultRepository = plagiarismResultRepository;
}

/**
* Daily triggers plagiarism checks as a part of continuous plagiarism control.
*/
@Scheduled(cron = "0 0 4 * * *") // execute this every night at 4:00:00 am
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you considered making this configurable, similarly as it is done in #6630 for the cron expressions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's good point

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

before we merge this, we have to add the property to the ansible collection. https://github.com/ls1intum/artemis-ansible-collection. You can just open a PR there.

public void executeChecks() {
log.info("Starting continuous plagiarism control...");

var exercises = exerciseRepository.findAllExercisesWithCurrentOrUpcomingDueDateAndContinuousPlagiarismControlEnabledIsTrue();
exercises.forEach(exercise -> {
log.info("Started continuous plagiarism control for exercise: exerciseId={}, type={}.", exercise.getId(), exercise.getExerciseType());
final long startTime = System.nanoTime();

try {
executeChecksForExercise(exercise);
}
catch (ExitException e) {
log.error("Cannot check plagiarism due to Jplag error: exerciseId={}, type={}, error={}.", exercise.getId(), exercise.getExerciseType(), e.getMessage(), e);
}
catch (Exception e) {
log.error("Cannot check plagiarism due to unknown error: exerciseId={}, type={}, error={}.", exercise.getId(), exercise.getExerciseType(), e.getMessage(), e);
}

log.info("Finished continuous plagiarism control for exercise: exerciseId={}, elapsed={}.", exercise.getId(), TimeLogUtil.formatDurationFrom(startTime));
});

log.debug("Continuous plagiarism control done.");
}

private void executeChecksForExercise(Exercise exercise) throws Exception {
switch (exercise.getExerciseType()) {
case TEXT -> {
var textExercise = textExerciseRepository.findByIdWithStudentParticipationsAndSubmissionsElseThrow(exercise.getId());
executeChecksForTextExercise(textExercise);
}
case PROGRAMMING -> {
var programmingExercise = programmingExerciseRepository.findByIdWithStudentParticipationsAndLegalSubmissionsElseThrow(exercise.getId());
executeChecksForProgrammingExercise(programmingExercise);
}
case MODELING -> {
var modelingExercise = modelingExerciseRepository.findByIdWithStudentParticipationsSubmissionsResultsElseThrow(exercise.getId());
executeChecksForModelingExercise(modelingExercise);
}
case FILE_UPLOAD, QUIZ -> {
log.error("Cannot check plagiarism for exercise: type={}, id={}.", exercise.getExerciseType(), exercise.getId());
}
}
}

private void executeChecksForTextExercise(TextExercise exercise) throws Exception {
var plagiarismResult = textPlagiarismDetectionService.checkPlagiarism(exercise, exercise.getPlagiarismChecksConfig().getSimilarityThreshold(),
exercise.getPlagiarismChecksConfig().getMinimumScore(), exercise.getPlagiarismChecksConfig().getMinimumSize());
log.info("Finished textPlagiarismDetectionService.checkPlagiarism for exercise {} with {} comparisons,", exercise.getId(), plagiarismResult.getComparisons().size());

// TODO: limit the amount temporarily because of database issues
plagiarismResult.sortAndLimit(100);
plagiarismResultRepository.savePlagiarismResultAndRemovePrevious(plagiarismResult);

plagiarismResultRepository.prepareResultForClient(plagiarismResult);
}

private void executeChecksForProgrammingExercise(ProgrammingExercise exercise) throws Exception {
var language = exercise.getProgrammingLanguage();
var programmingLanguageFeature = programmingLanguageFeatureService.getProgrammingLanguageFeatures(language);
if (!programmingLanguageFeature.plagiarismCheckSupported()) {
log.error("Artemis does not support plagiarism checks for the programming language {}", language);
}

var plagiarismResult = programmingPlagiarismDetectionService.checkPlagiarism(exercise.getId(), exercise.getPlagiarismChecksConfig().getSimilarityThreshold(),
exercise.getPlagiarismChecksConfig().getMinimumScore());
log.info("Finished programmingExerciseExportService.checkPlagiarism call for {} comparisons", plagiarismResult.getComparisons().size());

plagiarismResultRepository.prepareResultForClient(plagiarismResult);
}

private void executeChecksForModelingExercise(ModelingExercise exercise) throws Exception {
var plagiarismResult = modelingPlagiarismDetectionService.checkPlagiarism(exercise, exercise.getPlagiarismChecksConfig().getSimilarityThreshold(),
exercise.getPlagiarismChecksConfig().getMinimumSize(), exercise.getPlagiarismChecksConfig().getMinimumScore());
log.info("Finished modelingPlagiarismDetectionService.checkPlagiarism call for {} comparisons", plagiarismResult.getComparisons().size());

// TODO: limit the amount temporarily because of database issues
plagiarismResult.sortAndLimit(100);
plagiarismResultRepository.savePlagiarismResultAndRemovePrevious(plagiarismResult);

plagiarismResultRepository.prepareResultForClient(plagiarismResult);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -353,22 +353,20 @@ public ResponseEntity<ModelingPlagiarismResult> getPlagiarismResult(@PathVariabl
* <p>
* Start the automated plagiarism detection for the given exercise and return its result.
*
* @param exerciseId for which all submission should be checked
* @param similarityThreshold ignore comparisons whose similarity is below this threshold (in % between 0 and 100)
* @param minimumScore consider only submissions whose score is greater or equal to this value
* @param minimumSize consider only submissions whose size is greater or equal to this value
* @param exerciseId for which all submission should be checked
* @return the ResponseEntity with status 200 (OK) and the list of at most 500 pair-wise submissions with a similarity above the given threshold (e.g. 50%).
*/
@GetMapping("modeling-exercises/{exerciseId}/check-plagiarism")
@FeatureToggle(Feature.PlagiarismChecks)
@PreAuthorize("hasRole('INSTRUCTOR')")
public ResponseEntity<ModelingPlagiarismResult> checkPlagiarism(@PathVariable long exerciseId, @RequestParam float similarityThreshold, @RequestParam int minimumScore,
@RequestParam int minimumSize) {
public ResponseEntity<ModelingPlagiarismResult> checkPlagiarism(@PathVariable long exerciseId) {
var modelingExercise = modelingExerciseRepository.findByIdWithStudentParticipationsSubmissionsResultsElseThrow(exerciseId);
authCheckService.checkHasAtLeastRoleForExerciseElseThrow(Role.INSTRUCTOR, modelingExercise, null);
long start = System.nanoTime();
log.info("Start modelingPlagiarismDetectionService.checkPlagiarism for exercise {}", exerciseId);
var plagiarismResult = modelingPlagiarismDetectionService.checkPlagiarism(modelingExercise, similarityThreshold / 100, minimumSize, minimumScore);
var plagiarismChecksConfig = modelingExerciseRepository.findByIdElseThrow(exerciseId).getPlagiarismChecksConfig();
var plagiarismResult = modelingPlagiarismDetectionService.checkPlagiarism(modelingExercise, plagiarismChecksConfig.getSimilarityThreshold(),
plagiarismChecksConfig.getMinimumSize(), plagiarismChecksConfig.getMinimumScore());
log.info("Finished modelingPlagiarismDetectionService.checkPlagiarism call for {} comparisons in {}", plagiarismResult.getComparisons().size(),
TimeLogUtil.formatDurationFrom(start));
// TODO: limit the amount temporarily because of database issues
Expand Down
Loading