7f7d9d6892d73ff05bef21546116ca25429badd5
[idea/community.git] / python / educational-core / student / src / com / jetbrains / edu / learning / stepic / StepicWrappers.java
1 package com.jetbrains.edu.learning.stepic;
2
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;
19
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.util.*;
23
24 public class StepicWrappers {
25   private static final Logger LOG = Logger.getInstance(StepOptions.class);
26
27   static class StepContainer {
28     List<StepSource> steps;
29   }
30
31   public static class Step {
32     @Expose StepOptions options;
33     @Expose String text;
34     @Expose String name = "pycharm";
35     @Expose StepOptions source;
36
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);
41       return step;
42     }
43   }
44
45   public static class StepOptions {
46     @Expose List<TestFileWrapper> test;
47     @Expose String title;
48     @Expose List<TaskFile> files;
49     @Expose String text;
50     @Expose List<List<String>> samples;
51     @Expose Integer executionMemoryLimit;
52     @Expose Integer executionTimeLimit;
53     @Expose CodeTemplatesWrapper codeTemplates;
54
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);
69           if (pair == null) {
70             return;
71           }
72           VirtualFile virtualFile = pair.getFirst();
73           TaskFile taskFile = pair.getSecond();
74           try {
75             InputStream stream = virtualFile.getInputStream();
76             taskFile.text =
77               EduUtils.isImage(name) ? Base64.encodeBase64URLSafeString(FileUtil.loadBytes(stream)) : FileUtil.loadTextAndClose(stream);
78           }
79           catch (IOException e) {
80             LOG.error("Can't find file " + virtualFile.getPath());
81           }
82           source.files.add(taskFile);
83         });
84       }
85       return source;
86     }
87
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)));
93         });
94       }
95       else {
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()));
99         }
100       }
101     }
102   }
103
104   static class CodeTemplatesWrapper {
105     String python3;
106     String python27;
107
108     @Nullable
109     public String getTemplateForLanguage(@NotNull final String langauge) {
110       if (langauge.equals(EduAdaptiveStepicConnector.PYTHON27)) {
111         return python27;
112       }
113
114       if (langauge.equals(EduAdaptiveStepicConnector.PYTHON3)) {
115         return python3;
116       }
117
118       return null;
119     }
120   }
121
122   static class CoursesContainer {
123     public List<CourseInfo> courses;
124     public Map meta;
125   }
126
127   static class StepSourceWrapper {
128     @Expose
129     StepSource stepSource;
130
131     public StepSourceWrapper(Project project, Task task, int lessonId) {
132       stepSource = new StepSource(project, task, lessonId);
133     }
134   }
135
136   static class CourseWrapper {
137     CourseInfo course;
138
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());
144     }
145   }
146
147   static class LessonWrapper {
148     Lesson lesson;
149
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>();
155     }
156   }
157
158   static class LessonContainer {
159     List<Lesson> lessons;
160   }
161
162   static class StepSource {
163     @Expose Step block;
164     @Expose int position = 0;
165     @Expose int lesson = 0;
166     Date update_date;
167
168     public StepSource(Project project, Task task, int lesson) {
169       this.lesson = lesson;
170       position = task.getIndex();
171       block = Step.fromTask(project, task);
172     }
173   }
174
175   static class TestFileWrapper {
176     @Expose public final String name;
177     @Expose public final String text;
178
179     public TestFileWrapper(String name, String text) {
180       this.name = name;
181       this.text = text;
182     }
183   }
184
185   static class Section {
186     List<Integer> units;
187     int course;
188     String title;
189     int position;
190     int id;
191   }
192
193   static class SectionWrapper {
194     Section section;
195   }
196
197   static class SectionContainer {
198     List<Section> sections;
199     List<Lesson> lessons;
200
201     List<Unit> units;
202   }
203
204   static class Unit {
205     int id;
206     int section;
207     int lesson;
208     int position;
209     List<Integer> assignments;
210   }
211
212   static class UnitContainer {
213
214     List<Unit> units;
215   }
216
217   static class UnitWrapper {
218     Unit unit;
219   }
220
221   static class AttemptWrapper {
222     static class Attempt {
223       public Attempt(int step) {
224         this.step = step;
225       }
226
227       int step;
228       int id;
229     }
230
231     public AttemptWrapper(int step) {
232       attempt = new Attempt(step);
233     }
234
235     Attempt attempt;
236   }
237
238   static class AttemptToPostWrapper {
239     static class Attempt {
240       int step;
241       String dataset_url;
242       String status;
243       String time;
244       String time_left;
245       String user;
246       String user_id;
247
248       public Attempt(int step) {
249         this.step = step;
250       }
251     }
252
253     public AttemptToPostWrapper(int step) {
254       attempt = new Attempt(step);
255     }
256
257     Attempt attempt;
258   }
259
260   static class AttemptContainer {
261     List<AttemptWrapper.Attempt> attempts;
262   }
263
264   static class SolutionFile {
265     String name;
266     String text;
267
268     public SolutionFile(String name, String text) {
269       this.name = name;
270       this.text = text;
271     }
272   }
273
274   static class AuthorWrapper {
275     List<StepicUser> users;
276   }
277
278   static class SubmissionWrapper {
279     Submission submission;
280
281
282     public SubmissionWrapper(int attempt, String score, ArrayList<SolutionFile> files) {
283       submission = new Submission(score, attempt, files);
284     }
285
286     static class Submission {
287       int attempt;
288       private final Reply reply;
289
290       public Submission(String score, int attempt, ArrayList<SolutionFile> files) {
291         reply = new Reply(files, score);
292         this.attempt = attempt;
293       }
294
295       static class Reply {
296         String score;
297         List<SolutionFile> solution;
298
299         public Reply(ArrayList<SolutionFile> files, String score) {
300           this.score = score;
301           solution = files;
302         }
303       }
304     }
305   }
306
307   static class UserWrapper {
308     StepicUser user;
309
310     public UserWrapper(String user, String password) {
311       this.user = new StepicUser(user, password);
312     }
313   }
314
315   static class RecommendationReaction {
316     int reaction;
317     String user;
318     String lesson;
319
320     public RecommendationReaction(int reaction, String user, String lesson) {
321       this.reaction = reaction;
322       this.user = user;
323       this.lesson = lesson;
324     }
325   }
326
327   static class RecommendationReactionWrapper {
328     RecommendationReaction recommendationReaction;
329
330     public RecommendationReactionWrapper(RecommendationReaction recommendationReaction) {
331       this.recommendationReaction = recommendationReaction;
332     }
333   }
334
335   static class RecommendationWrapper {
336     Recommendation[] recommendations;
337   }
338
339   static class Recommendation {
340     String id;
341     String lesson;
342   }
343
344
345   static class SubmissionToPostWrapper {
346     Submission submission;
347
348     public SubmissionToPostWrapper(@NotNull String attemptId, @NotNull String language, @NotNull String code) {
349       submission = new Submission(attemptId, new Submission.Reply(language, code));
350     }
351
352     static class Submission {
353       String attempt;
354       Reply reply;
355
356       public Submission(String attempt, Reply reply) {
357         this.attempt = attempt;
358         this.reply = reply;
359       }
360
361       static class Reply {
362         String language;
363         String code;
364
365         public Reply(String language, String code) {
366           this.language = language;
367           this.code = code;
368         }
369       }
370     }
371   }
372
373   static class ResultSubmissionWrapper {
374     ResultSubmission[] submissions;
375
376     static class ResultSubmission {
377       int id;
378       String status;
379       String hint;
380     }
381   }
382
383   static class AssignmentsWrapper {
384     List<Assignment> assignments;
385   }
386
387   static class Assignment {
388     int id;
389     int step;
390   }
391
392   static class ViewsWrapper {
393     View view;
394
395     public ViewsWrapper(final int assignment, final int step) {
396       this.view = new View(assignment, step);
397     }
398   }
399
400   static class View {
401     int assignment;
402     int step;
403
404     public View(int assignment, int step) {
405       this.assignment = assignment;
406       this.step = step;
407     }
408   }
409
410   static class Enrollment {
411     String course;
412
413     public Enrollment(String courseId) {
414       course = courseId;
415     }
416   }
417
418   static class EnrollmentWrapper {
419     Enrollment enrollment;
420
421     public EnrollmentWrapper(@NotNull final String courseId) {
422       enrollment = new Enrollment(courseId);
423     }
424   }
425 }