Skip to content
This repository was archived by the owner on Jun 3, 2025. It is now read-only.

Commit 2432202

Browse files
author
Irene
committed
Handle submitting old exercises
Update end point URLs for exercises which were downloaded with the old client and thus had old submission URLs. Also handle showToUserException which may be tthrown by core
1 parent 20c8569 commit 2432202

File tree

5 files changed

+86
-23
lines changed

5 files changed

+86
-23
lines changed

src/main/java/fi/helsinki/cs/tmc/cli/backend/TmcUtil.java

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import fi.helsinki.cs.tmc.core.domain.submission.SubmissionResult;
1414
import fi.helsinki.cs.tmc.core.exceptions.FailedHttpResponseException;
1515
import fi.helsinki.cs.tmc.core.exceptions.ObsoleteClientException;
16+
import fi.helsinki.cs.tmc.core.exceptions.ShowToUserException;
1617
import fi.helsinki.cs.tmc.core.holders.TmcSettingsHolder;
1718
import fi.helsinki.cs.tmc.langs.abstraction.ValidationResult;
1819
import fi.helsinki.cs.tmc.langs.domain.RunResult;
@@ -199,7 +200,8 @@ public static ValidationResult runCheckStyle(CliContext ctx, Exercise exercise)
199200
}
200201
}
201202

202-
public static List<Exercise> getCourseExercises(CliContext ctx, Course course) {
203+
public static List<Exercise> getCourseExercises(CliContext ctx) {
204+
Course course = ctx.getCourseInfo().getCourse();
203205
try {
204206
TmcCore tmcCore = ctx.getTmcCore();
205207
Course updatedCourse = tmcCore.getCourseDetails(ProgressObserver.NULL_OBSERVER, course).call();
@@ -223,17 +225,6 @@ public static boolean sendFeedback(
223225
}
224226
}
225227

226-
public static Organization getOrganizationForCourse(CliContext ctx, Course course) {
227-
TmcCore tmcCore = ctx.getTmcCore();
228-
Callable<Organization> callable = tmcCore.getCourseOrganization(ProgressObserver.NULL_OBSERVER, course);
229-
try {
230-
return callable.call();
231-
} catch (Exception e) {
232-
logger.error("Could not get organization for course " + course.getName());
233-
return null;
234-
}
235-
}
236-
237228
private static void handleTmcExceptions(CliContext ctx, Exception exception) {
238229
Io io = ctx.getIo();
239230
Throwable cause = exception.getCause();
@@ -279,6 +270,12 @@ private static void handleTmcExceptions(CliContext ctx, Exception exception) {
279270
return;
280271
}
281272

273+
if (cause instanceof ShowToUserException) {
274+
logger.error(exception.getMessage());
275+
io.errorln(cause.getMessage());
276+
return;
277+
}
278+
282279
logger.error("Command failed in tmc-core", exception);
283280
io.errorln("Command failed, check tmc-cli.log file for more info");
284281
}

src/main/java/fi/helsinki/cs/tmc/cli/command/SubmitCommand.java

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.slf4j.LoggerFactory;
2929

3030
import java.net.URI;
31+
import java.net.URISyntaxException;
3132
import java.nio.file.Path;
3233
import java.util.ArrayList;
3334
import java.util.List;
@@ -42,6 +43,8 @@ public class SubmitCommand extends AbstractCommand {
4243
private boolean showAll;
4344
private boolean showDetails;
4445
private boolean filterUncompleted;
46+
private static int API_VERSION = 8;
47+
private Path courseInfoFile;
4548

4649
@Override
4750
public void getOptions(Options options) {
@@ -55,6 +58,7 @@ public void getOptions(Options options) {
5558
public void run(CliContext context, CommandLine args) {
5659
this.ctx = context;
5760
this.io = ctx.getIo();
61+
WorkDir workDir = ctx.getWorkDir();
5862

5963
String[] exercisesFromArgs = parseArgs(args);
6064
if (exercisesFromArgs == null) {
@@ -65,7 +69,6 @@ public void run(CliContext context, CommandLine args) {
6569
return;
6670
}
6771

68-
WorkDir workDir = ctx.getWorkDir();
6972
if (exercisesFromArgs.length == 0 && workDir.getExercises().size() != 1) {
7073
io.println("Please give exercise to submit as argument");
7174
return;
@@ -78,6 +81,18 @@ public void run(CliContext context, CommandLine args) {
7881
}
7982
}
8083

84+
CourseInfo info = ctx.getCourseInfo();
85+
Course currentCourse = info.getCourse();
86+
if (currentCourse == null) {
87+
return;
88+
}
89+
90+
courseInfoFile = workDir.getConfigFile();
91+
92+
if (apiUrlIsOutdated(currentCourse)) {
93+
updateCourseAndExercises();
94+
}
95+
8196
List<Exercise> exercises;
8297
if (filterUncompleted) {
8398
workDir.addPath(workDir.getCourseDirectory());
@@ -95,11 +110,6 @@ public void run(CliContext context, CommandLine args) {
95110
return;
96111
}
97112

98-
CourseInfo info = ctx.getCourseInfo();
99-
Course currentCourse = info.getCourse();
100-
if (currentCourse == null) {
101-
return;
102-
}
103113

104114
Color color1 = ctx.getColorProperty("testresults-left", ctx.getApp());
105115
Color color2 = ctx.getColorProperty("testresults-right", ctx.getApp());
@@ -148,7 +158,7 @@ public void run(CliContext context, CommandLine args) {
148158
resultPrinter.printTotalExerciseResults();
149159
}
150160

151-
updateCourseJson(submitExercises, info, workDir.getConfigFile());
161+
updateCourseJson(submitExercises, info);
152162
checkForExerciseUpdates(currentCourse);
153163
sendFeedbacks(feedbackLists, exercisesWithFeedback, feedbackUris);
154164
}
@@ -172,9 +182,9 @@ private void sendFeedbacks(List<List<FeedbackQuestion>> feedbackLists, List<Stri
172182
* Fetch updated exercise statuses from server and update course JSON file accordingly.
173183
*/
174184
private void updateCourseJson(
175-
List<Exercise> submittedExercises, CourseInfo courseInfo, Path courseInfoFile) {
185+
List<Exercise> submittedExercises, CourseInfo courseInfo) {
176186

177-
List<Exercise> exercises = TmcUtil.getCourseExercises(ctx, courseInfo.getCourse());
187+
List<Exercise> exercises = TmcUtil.getCourseExercises(ctx);
178188
if (exercises == null) {
179189
io.println(
180190
"Failed to update config file for course " + courseInfo.getCourseName());
@@ -227,6 +237,43 @@ private void checkForExerciseUpdates(Course course) {
227237
io.println(ColorUtil.colorString(msg, Color.YELLOW));
228238
}
229239

240+
private boolean apiUrlIsOutdated(Course course) {
241+
return !course.getDetailsUrl().toString().contains("v" + API_VERSION);
242+
}
243+
244+
private void updateCourseAndExercises() {
245+
// This is a patch to migrate away from api 7 urls
246+
// as some exercises have been downloaded before the new api
247+
String oldDetailsUrl = ctx.getCourseInfo().getCourse().getDetailsUrl().toString();
248+
String updatedUrl = getUpdatedDetailsUrl(oldDetailsUrl);
249+
try {
250+
ctx.getCourseInfo().getCourse().setDetailsUrl(new URI(updatedUrl));
251+
} catch (URISyntaxException e) {
252+
logger.error("Could not update details url for course " + ctx.getCourseInfo().getCourseName());
253+
return;
254+
}
255+
List<Exercise> exercises = TmcUtil.getCourseExercises(ctx);
256+
if (exercises == null) {
257+
io.println(
258+
"Failed to update urls for exercises of course " + ctx.getCourseInfo().getCourseName());
259+
return;
260+
}
261+
ctx.getCourseInfo().getCourse().setExercises(exercises);
262+
CourseInfoIo.save(ctx.getCourseInfo(), courseInfoFile);
263+
}
264+
265+
private static String getUpdatedDetailsUrl(String oldDetailsUrl) {
266+
if (!oldDetailsUrl.contains("/org")) {
267+
return oldDetailsUrl;
268+
}
269+
int iOrg = oldDetailsUrl.indexOf("/org");
270+
int iCourses = oldDetailsUrl.indexOf("/courses");
271+
String beginningPart = oldDetailsUrl.substring(0, iOrg);
272+
String endPart = oldDetailsUrl.substring(iCourses, oldDetailsUrl.length());
273+
return beginningPart + "/api/v" + API_VERSION + "/core" + endPart;
274+
}
275+
276+
230277
private String[] parseArgs(CommandLine args) {
231278
this.showAll = args.hasOption("a");
232279
this.showDetails = args.hasOption("d");

src/main/java/fi/helsinki/cs/tmc/cli/updater/AutoUpdater.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,13 @@ private byte[] fetchHttpEntity(String urlAddress) {
105105
InputStream inputStream;
106106
try {
107107
URLConnection connection = url.openConnection();
108+
connection.setConnectTimeout(10000);
108109
connection.setRequestProperty(
109110
"User-Agent", "tmc-cli (https://github.com/tmc-cli/tmc-cli)");
110111
inputStream = connection.getInputStream();
111112
} catch (IOException ex) {
112113
logger.warn("Failed to fetch page", ex);
113-
io.errorln("Failed to create https connection to github.");
114+
io.errorln("Failed to create a https connection.");
114115
return null;
115116
}
116117

src/test/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommandTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public void setUp() {
7777
AnalyticsFacade analyticsFacade = new AnalyticsFacade(new Settings(), eventSendBuffer);
7878
ctx = new CliContext(io, mockCore, workDir, new Settings(), analyticsFacade);
7979
app = new Application(ctx);
80-
Account account = new Account("user", "password", testOrganization);
80+
Account account = new Account("user", testOrganization);
8181
ctx.useAccount(account);
8282
accountList = new AccountList();
8383
accountList.addAccount(account);

src/test/java/fi/helsinki/cs/tmc/cli/command/SubmitCommandTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,11 @@
3232
import org.powermock.core.classloader.annotations.PrepareForTest;
3333
import org.powermock.modules.junit4.PowerMockRunner;
3434

35+
import java.net.URI;
36+
import java.net.URISyntaxException;
3537
import java.nio.file.Path;
3638
import java.nio.file.Paths;
39+
import java.util.ArrayList;
3740
import java.util.Collections;
3841
import java.util.List;
3942

@@ -250,6 +253,21 @@ public void sendAnalyticsIsCalledOnSubmit() {
250253
verify(analyticsFacade).sendAnalytics();
251254
}
252255

256+
@Test
257+
public void updateAllExercisesIfCourseApiUrlIsOutDated() {
258+
workDir.setWorkdir(pathToDummyExercise);
259+
ArrayList<Exercise> exercises = new ArrayList<>();
260+
Exercise test = new Exercise("test");
261+
try {
262+
test.setReturnUrl(new URI("test"));
263+
} catch (URISyntaxException e) {
264+
}
265+
exercises.add(test);
266+
when(TmcUtil.getCourseExercises(ctx)).thenReturn(exercises);
267+
app.run(new String[] {"submit"});
268+
assertEquals(ctx.getCourseInfo().getCourse().getExercises(), exercises);
269+
}
270+
253271
private static int countSubstring(String subStr, String str) {
254272
return (str.length() - str.replace(subStr, "").length()) / subStr.length();
255273
}

0 commit comments

Comments
 (0)