add upload multihint course to stepic

EDU-681 Multihints breaks json pushed to stepic
This commit is contained in:
Ekaterina Tuzova
2016-07-19 18:17:33 +03:00
parent b06b91096b
commit 31bf1a950a
5 changed files with 58 additions and 14 deletions
@@ -10,6 +10,7 @@ import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.hash.HashMap;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
import com.jetbrains.edu.learning.courseFormat.Course;
import com.jetbrains.edu.learning.courseFormat.StudyStatus;
import com.jetbrains.edu.learning.courseFormat.TaskFile;
@@ -29,6 +30,10 @@ public class StudySerializationUtils {
public static final String PLACEHOLDERS = "placeholders";
public static final String LINE = "line";
public static final String START = "start";
public static final String LENGTH = "length";
public static final String POSSIBLE_ANSWER = "possible_answer";
public static final String HINT = "hint";
public static final String HINTS = "hints";
public static final String OFFSET = "offset";
public static final String TEXT = "text";
public static final String LESSONS = "lessons";
@@ -378,6 +383,7 @@ public class StudySerializationUtils {
@Override
public TaskFile deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
final Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
JsonObject taskFileObject = json.getAsJsonObject();
JsonArray placeholders = taskFileObject.getAsJsonArray(PLACEHOLDERS);
for (JsonElement placeholder : placeholders) {
@@ -390,8 +396,46 @@ public class StudySerializationUtils {
Document document = EditorFactory.getInstance().createDocument(taskFileObject.getAsJsonPrimitive(TEXT).getAsString());
placeholderObject.addProperty(OFFSET, document.getLineStartOffset(line) + start);
}
final String hintString = placeholderObject.getAsJsonPrimitive(HINT).getAsString();
final JsonArray hintsArray = new JsonArray();
try {
final List<String> hints = gson.fromJson(hintString, List.class);
for (String hint : hints) {
hintsArray.add(hint);
}
}
catch (JsonParseException e) {
hintsArray.add(hintString);
}
placeholderObject.add(HINTS, hintsArray);
}
return new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create().fromJson(json, TaskFile.class);
return gson.fromJson(json, TaskFile.class);
}
}
public static class StepicAnswerPlaceholderAdapter implements JsonSerializer<AnswerPlaceholder> {
@Override
public JsonElement serialize(AnswerPlaceholder src, Type typeOfSrc, JsonSerializationContext context) {
final List<String> hints = src.getHints();
final int length = src.getLength();
final int start = src.getOffset();
final String possibleAnswer = src.getPossibleAnswer();
int line = -1;
final Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
final JsonObject answerPlaceholder = new JsonObject();
answerPlaceholder.addProperty(LINE, line);
answerPlaceholder.addProperty(START, start);
answerPlaceholder.addProperty(LENGTH, length);
answerPlaceholder.addProperty(POSSIBLE_ANSWER, possibleAnswer);
final String jsonHints = gson.toJson(hints);
answerPlaceholder.addProperty(HINT, jsonHints);
return answerPlaceholder;
}
}
}
@@ -15,6 +15,7 @@ import java.util.List;
public class AnswerPlaceholder {
@SerializedName("hints")
@Expose private List<String> myHints = new ArrayList<String>();
@SerializedName("possible_answer")
@@ -11,7 +11,7 @@ import java.util.ArrayList;
import java.util.List;
public class Lesson implements StudyItem {
@Expose private int myId;
@Expose @SerializedName("id") private int myId;
@Transient public List<Integer> steps;
@Transient public List<String> tags;
@Transient boolean is_public;
@@ -29,10 +29,7 @@ import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.StudyUtils;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.core.EduUtils;
import com.jetbrains.edu.learning.courseFormat.Course;
import com.jetbrains.edu.learning.courseFormat.Lesson;
import com.jetbrains.edu.learning.courseFormat.Task;
import com.jetbrains.edu.learning.courseFormat.TaskFile;
import com.jetbrains.edu.learning.courseFormat.*;
import com.jetbrains.edu.learning.statistics.EduUsagesCollector;
import com.jetbrains.edu.learning.stepic.CourseInfo;
import com.jetbrains.edu.learning.stepic.EduStepicConnector;
@@ -289,7 +286,9 @@ public class StudyProjectGenerator {
}
public static void flushCourseJson(@NotNull final Course course, @NotNull final File courseDirectory) {
final Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().create();
final Gson gson = new GsonBuilder().setPrettyPrinting().
registerTypeAdapter(AnswerPlaceholder.class, new StudySerializationUtils.Json.StepicAnswerPlaceholderAdapter()).
excludeFieldsWithoutExposeAnnotation().create();
final String json = gson.toJson(course);
final File courseJson = new File(courseDirectory, EduNames.COURSE_META_FILE);
final FileOutputStream fileOutputStream;
@@ -20,10 +20,7 @@ import com.jetbrains.edu.learning.StudySerializationUtils;
import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.core.EduNames;
import com.jetbrains.edu.learning.core.EduUtils;
import com.jetbrains.edu.learning.courseFormat.Course;
import com.jetbrains.edu.learning.courseFormat.Lesson;
import com.jetbrains.edu.learning.courseFormat.Task;
import com.jetbrains.edu.learning.courseFormat.TaskFile;
import com.jetbrains.edu.learning.courseFormat.*;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.*;
import org.apache.http.client.entity.UrlEncodedFormEntity;
@@ -237,10 +234,12 @@ public class EduStepicConnector {
if (statusLine.getStatusCode() != HttpStatus.SC_OK) {
throw new IOException("Stepic returned non 200 status code " + responseString);
}
Gson gson = new GsonBuilder().registerTypeAdapter(TaskFile.class, new StudySerializationUtils.Json.StepicTaskFileAdapter()).setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
Gson gson = new GsonBuilder().registerTypeAdapter(TaskFile.class, new StudySerializationUtils.Json.StepicTaskFileAdapter()).
registerTypeAdapter(AnswerPlaceholder.class, new StudySerializationUtils.Json.StepicAnswerPlaceholderAdapter()).
setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
return gson.fromJson(responseString, container);
}
@NotNull
public static CloseableHttpClient getHttpClient(@NotNull final Project project) {
if (ourClient == null) {
@@ -727,7 +726,8 @@ public class EduStepicConnector {
final HttpPost request = new HttpPost(EduStepicNames.STEPIC_API_URL + "/step-sources");
setHeaders(request, "application/json");
//TODO: register type adapter for task files here?
final Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().create();
final Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().
registerTypeAdapter(AnswerPlaceholder.class, new StudySerializationUtils.Json.StepicAnswerPlaceholderAdapter()).create();
ApplicationManager.getApplication().invokeLater(() -> {
final String requestBody = gson.toJson(new StepicWrappers.StepSourceWrapper(project, task, lessonId));
request.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));