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 super ProgrammingSubmission> 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());
}
}