From 22721e2cfa5771a8647295cf825b7e6d6959ac45 Mon Sep 17 00:00:00 2001 From: Luro02 <24826124+Luro02@users.noreply.github.com> Date: Fri, 19 Dec 2025 08:43:48 +0100 Subject: [PATCH] update artemis4j to 8.5.0 --- pom.xml | 2 +- .../kit/kastel/artemiscli/ArtemisUtil.java | 2 +- .../kit/kastel/artemiscli/CloneCommand.java | 26 ++++++++---- .../kastel/artemiscli/ListLocksCommand.java | 41 +++++++++---------- .../java/edu/kit/kastel/artemiscli/Main.java | 2 +- .../artemiscli/ShowRepositoryCommand.java | 18 ++++---- .../kit/kastel/artemiscli/UnlockCommand.java | 19 +++++---- 7 files changed, 62 insertions(+), 48 deletions(-) diff --git a/pom.xml b/pom.xml index 79a6a28..fc629f4 100644 --- a/pom.xml +++ b/pom.xml @@ -31,7 +31,7 @@ edu.kit.kastel.sdq artemis4j - 7.10.1 + 8.5.0 info.picocli diff --git a/src/main/java/edu/kit/kastel/artemiscli/ArtemisUtil.java b/src/main/java/edu/kit/kastel/artemiscli/ArtemisUtil.java index 439c6a1..8d11eae 100644 --- a/src/main/java/edu/kit/kastel/artemiscli/ArtemisUtil.java +++ b/src/main/java/edu/kit/kastel/artemiscli/ArtemisUtil.java @@ -30,7 +30,7 @@ public static ProgrammingExercise findExercise(Course course, String name) throw List availableExercises = new ArrayList<>(); for (var exercise : allProgrammingExercises(course).toList()) { - if (List.of(exercise.getShortName(), exercise.getTitle()).contains(name)) { + if (List.of(exercise.getShortName(), exercise.getTitle(), "" + exercise.getId()).contains(name.toLowerCase())) { return exercise; } availableExercises.add(exercise.getShortName()); diff --git a/src/main/java/edu/kit/kastel/artemiscli/CloneCommand.java b/src/main/java/edu/kit/kastel/artemiscli/CloneCommand.java index 83718ad..34dabc6 100644 --- a/src/main/java/edu/kit/kastel/artemiscli/CloneCommand.java +++ b/src/main/java/edu/kit/kastel/artemiscli/CloneCommand.java @@ -1,9 +1,10 @@ package edu.kit.kastel.artemiscli; import edu.kit.kastel.sdq.artemis4j.ArtemisClientException; -import edu.kit.kastel.sdq.artemis4j.grading.ClonedProgrammingSubmission; import edu.kit.kastel.sdq.artemis4j.grading.ProgrammingExercise; import edu.kit.kastel.sdq.artemis4j.grading.ProgrammingSubmission; +import edu.kit.kastel.sdq.artemis4j.grading.ProgrammingSubmissionWithResults; +import org.eclipse.jgit.dircache.InvalidPathException; import picocli.CommandLine; import java.nio.file.Path; @@ -65,19 +66,30 @@ public void execute() throws Exception { } private static void cloneSubmissions(ProgrammingExercise exercise, Path outputFolder, Predicate shouldClone) throws ArtemisClientException { - List submissions = exercise.fetchSubmissions(0, false); + List submissions = exercise.fetchAllSubmissions(); System.out.println("Found " + submissions.size() + " submissions"); - for (ProgrammingSubmission submission : submissions) { - if (!shouldClone.test(submission)) { + for (ProgrammingSubmissionWithResults submission : submissions) { + var actualSubmission = submission.getSubmission(); + if (!shouldClone.test(actualSubmission)) { continue; } - System.out.println("Submission " + submission.getId() + " is from " + submission.getRepositoryUrl()); - Path output = Path.of(outputFolder.toString(), extractFolderName(submission.getRepositoryUrl())); + System.out.println("Submission " + actualSubmission.getId() + " is from " + actualSubmission.getRepositoryUrl()); + Path output = Path.of(outputFolder.toString(), extractFolderName(actualSubmission.getRepositoryUrl())); + + if (output.toFile().exists()) { + System.out.println("Warning: The folder " + output + " already exists, skipping submission " + actualSubmission.getId()); + continue; + } // ignore the submission/do not close it, otherwise the folder will be deleted - ClonedProgrammingSubmission _cloned = submission.cloneViaVCSTokenInto(output, null); + try { + actualSubmission.cloneViaVCSTokenInto(output, null); + } catch (InvalidPathException e) { + // This happens when an invalid filename like `CON` on Windows is used + System.out.println("Error: Could not clone submission " + actualSubmission.getId() + " into " + output + ": " + e.getMessage()); + } } } diff --git a/src/main/java/edu/kit/kastel/artemiscli/ListLocksCommand.java b/src/main/java/edu/kit/kastel/artemiscli/ListLocksCommand.java index 7fac947..230913a 100644 --- a/src/main/java/edu/kit/kastel/artemiscli/ListLocksCommand.java +++ b/src/main/java/edu/kit/kastel/artemiscli/ListLocksCommand.java @@ -5,11 +5,10 @@ import edu.kit.kastel.sdq.artemis4j.client.GenericSubmissionDTO; import edu.kit.kastel.sdq.artemis4j.grading.Course; import edu.kit.kastel.sdq.artemis4j.grading.ProgrammingExercise; -import edu.kit.kastel.sdq.artemis4j.grading.ProgrammingSubmission; +import edu.kit.kastel.sdq.artemis4j.grading.ProgrammingSubmissionWithResults; import picocli.CommandLine; import java.util.ArrayList; -import java.util.Collection; import java.util.Deque; import java.util.LinkedList; import java.util.List; @@ -34,49 +33,49 @@ public void execute() throws Exception { for (ProgrammingExercise exercise : exercises) { for (var submission : listLockedSubmissions(this.parent.course(), exercise)) { + if (submission.getFirstRoundAssessment() == null) { + throw new IllegalStateException( + "Submission %s is locked, but has no first round assessment.".formatted(submission.getSubmission().getId()) + ); + } + System.out.printf( "The submission by %s with the id %s is currently locked by %s.%n", - submission.getStudent().map(Object::toString).orElse("???"), - submission.getId(), - submission.getAssessor().map(Object::toString).orElse("???") + submission.getSubmission().getStudent().map(Object::toString).orElse("???"), + submission.getSubmission().getId(), + submission.getFirstRoundAssessment().getAssessor() ); } } } - static List listLockedSubmissions(Course course, ProgrammingExercise exercise) throws ArtemisNetworkException { + static List listLockedSubmissions(Course course, ProgrammingExercise exercise) throws ArtemisNetworkException { Set allLockedSubmissions = CourseDTO.fetchLockedSubmissions(course.getConnection().getClient(), course.getId()) - .stream() - .map(GenericSubmissionDTO::id) - .collect(Collectors.toSet()); + .stream() + .map(GenericSubmissionDTO::id) + .collect(Collectors.toSet()); if (allLockedSubmissions.isEmpty()) { return List.of(); } if (exercise != null) { - List allSubmissions = exercise.fetchSubmissions(0, false); - if (exercise.hasSecondCorrectionRound()) { - allSubmissions.addAll(exercise.fetchSubmissions(1, false)); - } + List allSubmissions = exercise.fetchAllSubmissions(); return allSubmissions.stream() - .filter(submission -> allLockedSubmissions.contains(submission.getId())) - .toList(); + .filter(submission -> allLockedSubmissions.contains(submission.getSubmission().getId())) + .toList(); } - List result = new ArrayList<>(); + List result = new ArrayList<>(); Deque exercises = new LinkedList<>(course.getProgrammingExercises()); while (!allLockedSubmissions.isEmpty() && !exercises.isEmpty()) { ProgrammingExercise currentExercise = exercises.removeLast(); - Collection submissions = new ArrayList<>(currentExercise.fetchSubmissions(0, false)); - if (currentExercise.hasSecondCorrectionRound()) { - submissions.addAll(currentExercise.fetchSubmissions(1, false)); - } + List submissions = currentExercise.fetchAllSubmissions(); for (var submission : submissions) { - if (allLockedSubmissions.remove(submission.getId())) { + if (allLockedSubmissions.remove(submission.getSubmission().getId())) { result.add(submission); } } diff --git a/src/main/java/edu/kit/kastel/artemiscli/Main.java b/src/main/java/edu/kit/kastel/artemiscli/Main.java index 8390cfe..9a0b29e 100644 --- a/src/main/java/edu/kit/kastel/artemiscli/Main.java +++ b/src/main/java/edu/kit/kastel/artemiscli/Main.java @@ -22,7 +22,7 @@ public final class Main implements Runnable{ CommandLine.Model.CommandSpec specification; @CommandLine.Option(names = {"--url"}, description = "The URL of the Artemis instance. Note that the https:// prefix is required.") - private String artemisUrl = "https://artemis.praktomat.cs.kit.edu/"; + private String artemisUrl = "https://artemis.cs.kit.edu/"; //private String artemisUrl = "https://artemis-test.sdq.kastel.kit.edu/"; @CommandLine.Option(names = {"--username"}, description = "The username to use for authentication.", required = true) diff --git a/src/main/java/edu/kit/kastel/artemiscli/ShowRepositoryCommand.java b/src/main/java/edu/kit/kastel/artemiscli/ShowRepositoryCommand.java index 4b0ab14..ded49a4 100644 --- a/src/main/java/edu/kit/kastel/artemiscli/ShowRepositoryCommand.java +++ b/src/main/java/edu/kit/kastel/artemiscli/ShowRepositoryCommand.java @@ -7,9 +7,9 @@ import java.util.List; @CommandLine.Command(name = "show", mixinStandardHelpOptions = true, - description = "Shows the repository urls of the given submissions.") + description = "Shows the repository urls of the given submissions.") public class ShowRepositoryCommand implements Command { - private static final String REPOSITORY_URL = "https://artemis.praktomat.cs.kit.edu/courses/%d/exercises/%d/repository/%d"; + private static final String REPOSITORY_URL = "https://artemis.cs.kit.edu/courses/%d/exercises/%d/repository/%d"; @CommandLine.Spec private CommandLine.Model.CommandSpec specification; @@ -31,16 +31,18 @@ public void execute() throws Exception { } Collection remainingIds = new LinkedHashSet<>(List.of(this.submissionIds)); - outer: for (var exercise : ArtemisUtil.listAllApplyingExercises(this.parent.course(), this.exerciseName)) { - for (var submission : exercise.fetchSubmissions(0, false)) { + outer: + for (var exercise : ArtemisUtil.listAllApplyingExercises(this.parent.course(), this.exerciseName)) { + for (var submission : exercise.fetchAllSubmissions()) { + var actualSubmission = submission.getSubmission(); if (remainingIds.isEmpty()) { break outer; } - if (remainingIds.remove("" + submission.getId()) || submission.getStudent().isPresent() && remainingIds.contains(submission.getStudent().get().toString())) { - String prefix = "[%s][%s][%s]:".formatted(exercise.getTitle(), submission.getId(), submission.getStudent().get().toString()); - System.out.printf("%s git url to clone: %s%n".formatted(prefix, submission.getRepositoryUrl())); - System.out.printf("%s artemis url: %s%n".formatted(" ".repeat(prefix.length()), REPOSITORY_URL.formatted(this.parent.course().getId(), exercise.getId(), submission.getParticipationId()))); + if (remainingIds.remove("" + actualSubmission.getId()) || actualSubmission.getStudent().isPresent() && remainingIds.contains(actualSubmission.getStudent().get().toString())) { + String prefix = "[%s][%s][%s]:".formatted(exercise.getTitle(), actualSubmission.getId(), actualSubmission.getStudent().get().toString()); + System.out.printf("%s git url to clone: %s%n".formatted(prefix, actualSubmission.getRepositoryUrl())); + System.out.printf("%s artemis url: %s%n".formatted(" ".repeat(prefix.length()), REPOSITORY_URL.formatted(this.parent.course().getId(), exercise.getId(), actualSubmission.getParticipationId()))); } } } diff --git a/src/main/java/edu/kit/kastel/artemiscli/UnlockCommand.java b/src/main/java/edu/kit/kastel/artemiscli/UnlockCommand.java index fed10a9..9ea67b0 100644 --- a/src/main/java/edu/kit/kastel/artemiscli/UnlockCommand.java +++ b/src/main/java/edu/kit/kastel/artemiscli/UnlockCommand.java @@ -1,8 +1,9 @@ package edu.kit.kastel.artemiscli; import edu.kit.kastel.sdq.artemis4j.ArtemisNetworkException; +import edu.kit.kastel.sdq.artemis4j.client.ArtemisClient; import edu.kit.kastel.sdq.artemis4j.client.ProgrammingSubmissionDTO; -import edu.kit.kastel.sdq.artemis4j.grading.ProgrammingSubmission; +import edu.kit.kastel.sdq.artemis4j.grading.ProgrammingSubmissionWithResults; import picocli.CommandLine; import java.util.ArrayList; @@ -41,12 +42,12 @@ public void execute() throws Exception { var exercises = ArtemisUtil.listAllApplyingExercises(this.parent.course(), this.exerciseName); for (var exercise : exercises) { - List availableSubmissions = ListLocksCommand.listLockedSubmissions(this.parent.course(), exercise); + List availableSubmissions = ListLocksCommand.listLockedSubmissions(this.parent.course(), exercise); - Collection submissions = new ArrayList<>(); + Collection submissions = new ArrayList<>(); outer: for (long submissionId : this.submissionIds) { for (var submission : availableSubmissions) { - if (submission.getId() == submissionId) { + if (submission.getSubmission().getId() == submissionId) { submissions.add(submission); continue outer; } @@ -60,17 +61,17 @@ public void execute() throws Exception { } for (var submission : submissions) { - unlock(submission); - System.out.println("Unlocked submission " + submission.getId()); + unlock(this.parent.course().getConnection().getClient(), submission); + System.out.println("Unlocked submission " + submission.getSubmission().getId()); } } } - private static void unlock(ProgrammingSubmission submission) throws ArtemisNetworkException { - if (submission.isSubmitted()) { + private static void unlock(ArtemisClient client, ProgrammingSubmissionWithResults submission) throws ArtemisNetworkException { + if (submission.getFirstRoundAssessment().isSubmitted()) { throw new IllegalStateException("Submission has already been submitted"); } - ProgrammingSubmissionDTO.cancelAssessment(submission.getConnection().getClient(), submission.getId()); + ProgrammingSubmissionDTO.cancelAssessment(client, submission.getSubmission().getId()); } }