1 package com.jetbrains.edu.learning.stepic;
3 import com.google.gson.annotations.Expose;
4 import com.intellij.openapi.application.ApplicationManager;
5 import com.intellij.openapi.diagnostic.Logger;
6 import com.intellij.openapi.project.Project;
7 import com.intellij.openapi.util.Pair;
8 import com.intellij.openapi.util.io.FileUtil;
9 import com.intellij.openapi.vfs.VirtualFile;
10 import com.jetbrains.edu.learning.core.EduNames;
11 import com.jetbrains.edu.learning.core.EduUtils;
12 import com.jetbrains.edu.learning.courseFormat.Course;
13 import com.jetbrains.edu.learning.courseFormat.Lesson;
14 import com.jetbrains.edu.learning.courseFormat.Task;
15 import com.jetbrains.edu.learning.courseFormat.TaskFile;
16 import org.apache.commons.codec.binary.Base64;
17 import org.jetbrains.annotations.NotNull;
18 import org.jetbrains.annotations.Nullable;
20 import java.io.IOException;
21 import java.io.InputStream;
24 public class StepicWrappers {
25 private static final Logger LOG = Logger.getInstance(StepOptions.class);
27 static class StepContainer {
28 List<StepSource> steps;
31 public static class Step {
32 @Expose StepOptions options;
34 @Expose String name = "pycharm";
35 @Expose StepOptions source;
37 public static Step fromTask(Project project, @NotNull final Task task) {
38 final Step step = new Step();
39 step.text = task.getTaskText(project);
40 step.source = StepOptions.fromTask(project, task);
45 public static class StepOptions {
46 @Expose List<TestFileWrapper> test;
48 @Expose List<TaskFile> files;
50 @Expose List<List<String>> samples;
51 @Expose Integer executionMemoryLimit;
52 @Expose Integer executionTimeLimit;
53 @Expose CodeTemplatesWrapper codeTemplates;
55 public static StepOptions fromTask(final Project project, @NotNull final Task task) {
56 final StepOptions source = new StepOptions();
57 setTests(task, source, project);
58 source.files = new ArrayList<TaskFile>();
59 source.title = task.getName();
60 for (final Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
61 ApplicationManager.getApplication().runWriteAction(() -> {
62 final VirtualFile taskDir = task.getTaskDir(project);
63 assert taskDir != null;
64 VirtualFile ideaDir = project.getBaseDir().findChild(".idea");
65 assert ideaDir != null;
66 String name = entry.getKey();
67 VirtualFile answerFile = taskDir.findChild(name);
68 Pair<VirtualFile, TaskFile> pair = EduUtils.createStudentFile(StepicWrappers.class, project, answerFile, ideaDir, null);
72 VirtualFile virtualFile = pair.getFirst();
73 TaskFile taskFile = pair.getSecond();
75 InputStream stream = virtualFile.getInputStream();
77 EduUtils.isImage(name) ? Base64.encodeBase64URLSafeString(FileUtil.loadBytes(stream)) : FileUtil.loadTextAndClose(stream);
79 catch (IOException e) {
80 LOG.error("Can't find file " + virtualFile.getPath());
82 source.files.add(taskFile);
88 private static void setTests(@NotNull final Task task, @NotNull final StepOptions source, @NotNull final Project project) {
89 final Map<String, String> testsText = task.getTestsText();
90 if (testsText.isEmpty()) {
91 ApplicationManager.getApplication().runReadAction(() -> {
92 source.test = Collections.singletonList(new TestFileWrapper(EduNames.TESTS_FILE, task.getTestsText(project)));
96 source.test = new ArrayList<TestFileWrapper>();
97 for (Map.Entry<String, String> entry : testsText.entrySet()) {
98 source.test.add(new TestFileWrapper(entry.getKey(), entry.getValue()));
104 static class CodeTemplatesWrapper {
109 public String getTemplateForLanguage(@NotNull final String langauge) {
110 if (langauge.equals(EduAdaptiveStepicConnector.PYTHON27)) {
114 if (langauge.equals(EduAdaptiveStepicConnector.PYTHON3)) {
122 static class CoursesContainer {
123 public List<CourseInfo> courses;
127 static class StepSourceWrapper {
129 StepSource stepSource;
131 public StepSourceWrapper(Project project, Task task, int lessonId) {
132 stepSource = new StepSource(project, task, lessonId);
136 static class CourseWrapper {
139 public CourseWrapper(Course course) {
140 this.course = new CourseInfo();
141 this.course.setName(course.getName());
142 this.course.setDescription(course.getDescription());
143 this.course.setAuthors(course.getAuthors());
147 static class LessonWrapper {
150 public LessonWrapper(Lesson lesson) {
151 this.lesson = new Lesson();
152 this.lesson.setName(lesson.getName());
153 this.lesson.setId(lesson.getId());
154 this.lesson.steps = new ArrayList<Integer>();
158 static class LessonContainer {
159 List<Lesson> lessons;
162 static class StepSource {
164 @Expose int position = 0;
165 @Expose int lesson = 0;
168 public StepSource(Project project, Task task, int lesson) {
169 this.lesson = lesson;
170 position = task.getIndex();
171 block = Step.fromTask(project, task);
175 static class TestFileWrapper {
176 @Expose public final String name;
177 @Expose public final String text;
179 public TestFileWrapper(String name, String text) {
185 static class Section {
193 static class SectionWrapper {
197 static class SectionContainer {
198 List<Section> sections;
199 List<Lesson> lessons;
209 List<Integer> assignments;
212 static class UnitContainer {
217 static class UnitWrapper {
221 static class AttemptWrapper {
222 static class Attempt {
223 public Attempt(int step) {
231 public AttemptWrapper(int step) {
232 attempt = new Attempt(step);
238 static class AttemptToPostWrapper {
239 static class Attempt {
248 public Attempt(int step) {
253 public AttemptToPostWrapper(int step) {
254 attempt = new Attempt(step);
260 static class AttemptContainer {
261 List<AttemptWrapper.Attempt> attempts;
264 static class SolutionFile {
268 public SolutionFile(String name, String text) {
274 static class AuthorWrapper {
275 List<StepicUser> users;
278 static class SubmissionWrapper {
279 Submission submission;
282 public SubmissionWrapper(int attempt, String score, ArrayList<SolutionFile> files) {
283 submission = new Submission(score, attempt, files);
286 static class Submission {
288 private final Reply reply;
290 public Submission(String score, int attempt, ArrayList<SolutionFile> files) {
291 reply = new Reply(files, score);
292 this.attempt = attempt;
297 List<SolutionFile> solution;
299 public Reply(ArrayList<SolutionFile> files, String score) {
307 static class UserWrapper {
310 public UserWrapper(String user, String password) {
311 this.user = new StepicUser(user, password);
315 static class RecommendationReaction {
320 public RecommendationReaction(int reaction, String user, String lesson) {
321 this.reaction = reaction;
323 this.lesson = lesson;
327 static class RecommendationReactionWrapper {
328 RecommendationReaction recommendationReaction;
330 public RecommendationReactionWrapper(RecommendationReaction recommendationReaction) {
331 this.recommendationReaction = recommendationReaction;
335 static class RecommendationWrapper {
336 Recommendation[] recommendations;
339 static class Recommendation {
345 static class SubmissionToPostWrapper {
346 Submission submission;
348 public SubmissionToPostWrapper(@NotNull String attemptId, @NotNull String language, @NotNull String code) {
349 submission = new Submission(attemptId, new Submission.Reply(language, code));
352 static class Submission {
356 public Submission(String attempt, Reply reply) {
357 this.attempt = attempt;
365 public Reply(String language, String code) {
366 this.language = language;
373 static class ResultSubmissionWrapper {
374 ResultSubmission[] submissions;
376 static class ResultSubmission {
383 static class AssignmentsWrapper {
384 List<Assignment> assignments;
387 static class Assignment {
392 static class ViewsWrapper {
395 public ViewsWrapper(final int assignment, final int step) {
396 this.view = new View(assignment, step);
404 public View(int assignment, int step) {
405 this.assignment = assignment;
410 static class Enrollment {
413 public Enrollment(String courseId) {
418 static class EnrollmentWrapper {
419 Enrollment enrollment;
421 public EnrollmentWrapper(@NotNull final String courseId) {
422 enrollment = new Enrollment(courseId);