edae1ae80acb450411bf6563bb2a2901b6207224
[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<>();
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 stepic = "stepic";
67           VirtualFile stepicDir = ideaDir.findChild(stepic);
68           if (stepicDir == null) {
69             try {
70               stepicDir = ideaDir.createChildDirectory(StepicWrappers.class, stepic);
71             }
72             catch (IOException e) {
73               LOG.info("Failed to create idea/stepic directory", e);
74             }
75           }
76           if (stepicDir == null) {
77             return;
78           }
79           String name = entry.getKey();
80           VirtualFile answerFile = taskDir.findChild(name);
81           Pair<VirtualFile, TaskFile> pair = EduUtils.createStudentFile(StepicWrappers.class, project, answerFile, stepicDir, null, 0);
82           if (pair == null) {
83             return;
84           }
85           VirtualFile virtualFile = pair.getFirst();
86           TaskFile taskFile = pair.getSecond();
87           try {
88             InputStream stream = virtualFile.getInputStream();
89             taskFile.text =
90               EduUtils.isImage(name) ? Base64.encodeBase64URLSafeString(FileUtil.loadBytes(stream)) : FileUtil.loadTextAndClose(stream);
91           }
92           catch (IOException e) {
93             LOG.error("Can't find file " + virtualFile.getPath());
94           }
95           source.files.add(taskFile);
96         });
97       }
98       return source;
99     }
100
101     private static void setTests(@NotNull final Task task, @NotNull final StepOptions source, @NotNull final Project project) {
102       final Map<String, String> testsText = task.getTestsText();
103       if (testsText.isEmpty()) {
104         ApplicationManager.getApplication().runReadAction(() -> {
105           source.test = Collections.singletonList(new TestFileWrapper(EduNames.TESTS_FILE, task.getTestsText(project)));
106         });
107       }
108       else {
109         source.test = new ArrayList<>();
110         for (Map.Entry<String, String> entry : testsText.entrySet()) {
111           source.test.add(new TestFileWrapper(entry.getKey(), entry.getValue()));
112         }
113       }
114     }
115   }
116
117   static class CodeTemplatesWrapper {
118     String python3;
119     String python27;
120
121     @Nullable
122     public String getTemplateForLanguage(@NotNull final String language) {
123       if (language.equals(EduAdaptiveStepicConnector.PYTHON2)) {
124         return python27;
125       }
126
127       if (language.equals(EduAdaptiveStepicConnector.PYTHON3)) {
128         return python3;
129       }
130
131       return null;
132     }
133   }
134
135   static class CoursesContainer {
136     public List<CourseInfo> courses;
137     public Map meta;
138   }
139
140   static class StepSourceWrapper {
141     @Expose
142     StepSource stepSource;
143
144     public StepSourceWrapper(Project project, Task task, int lessonId) {
145       stepSource = new StepSource(project, task, lessonId);
146     }
147   }
148
149   static class CourseWrapper {
150     CourseInfo course;
151
152     public CourseWrapper(Course course) {
153       this.course = new CourseInfo();
154       this.course.setName(course.getName());
155       this.course.setDescription(course.getDescription());
156       this.course.setAuthors(course.getAuthors());
157     }
158   }
159
160   static class LessonWrapper {
161     Lesson lesson;
162
163     public LessonWrapper(Lesson lesson) {
164       this.lesson = new Lesson();
165       this.lesson.setName(lesson.getName());
166       this.lesson.setId(lesson.getId());
167       this.lesson.steps = new ArrayList<>();
168     }
169   }
170
171   static class LessonContainer {
172     List<Lesson> lessons;
173   }
174
175   static class StepSource {
176     @Expose Step block;
177     @Expose int position = 0;
178     @Expose int lesson = 0;
179     Date update_date;
180
181     public StepSource(Project project, Task task, int lesson) {
182       this.lesson = lesson;
183       position = task.getIndex();
184       block = Step.fromTask(project, task);
185     }
186   }
187
188   static class TestFileWrapper {
189     @Expose public final String name;
190     @Expose public final String text;
191
192     public TestFileWrapper(String name, String text) {
193       this.name = name;
194       this.text = text;
195     }
196   }
197
198   static class Section {
199     List<Integer> units;
200     int course;
201     String title;
202     int position;
203     int id;
204   }
205
206   static class SectionWrapper {
207     Section section;
208   }
209
210   static class SectionContainer {
211     List<Section> sections;
212     List<Lesson> lessons;
213
214     List<Unit> units;
215   }
216
217   static class Unit {
218     int id;
219     int section;
220     int lesson;
221     int position;
222     List<Integer> assignments;
223   }
224
225   static class UnitContainer {
226
227     List<Unit> units;
228   }
229
230   static class UnitWrapper {
231     Unit unit;
232   }
233
234   static class AttemptWrapper {
235     static class Attempt {
236       public Attempt(int step) {
237         this.step = step;
238       }
239
240       int step;
241       int id;
242     }
243
244     public AttemptWrapper(int step) {
245       attempt = new Attempt(step);
246     }
247
248     Attempt attempt;
249   }
250
251   static class AttemptToPostWrapper {
252     static class Attempt {
253       int step;
254       String dataset_url;
255       String status;
256       String time;
257       String time_left;
258       String user;
259       String user_id;
260
261       public Attempt(int step) {
262         this.step = step;
263       }
264     }
265
266     public AttemptToPostWrapper(int step) {
267       attempt = new Attempt(step);
268     }
269
270     Attempt attempt;
271   }
272
273   static class AttemptContainer {
274     List<AttemptWrapper.Attempt> attempts;
275   }
276
277   static class SolutionFile {
278     String name;
279     String text;
280
281     public SolutionFile(String name, String text) {
282       this.name = name;
283       this.text = text;
284     }
285   }
286
287   static class AuthorWrapper {
288     List<StepicUser> users;
289   }
290
291   static class SubmissionWrapper {
292     Submission submission;
293
294
295     public SubmissionWrapper(int attempt, String score, ArrayList<SolutionFile> files) {
296       submission = new Submission(score, attempt, files);
297     }
298
299     static class Submission {
300       int attempt;
301       private final Reply reply;
302
303       public Submission(String score, int attempt, ArrayList<SolutionFile> files) {
304         reply = new Reply(files, score);
305         this.attempt = attempt;
306       }
307
308       static class Reply {
309         String score;
310         List<SolutionFile> solution;
311
312         public Reply(ArrayList<SolutionFile> files, String score) {
313           this.score = score;
314           solution = files;
315         }
316       }
317     }
318   }
319
320   static class UserWrapper {
321     StepicUser user;
322
323     public UserWrapper(String user, String password) {
324       this.user = new StepicUser(user, password);
325     }
326   }
327
328   static class RecommendationReaction {
329     int reaction;
330     String user;
331     String lesson;
332
333     public RecommendationReaction(int reaction, String user, String lesson) {
334       this.reaction = reaction;
335       this.user = user;
336       this.lesson = lesson;
337     }
338   }
339
340   static class RecommendationReactionWrapper {
341     RecommendationReaction recommendationReaction;
342
343     public RecommendationReactionWrapper(RecommendationReaction recommendationReaction) {
344       this.recommendationReaction = recommendationReaction;
345     }
346   }
347
348   static class RecommendationWrapper {
349     Recommendation[] recommendations;
350   }
351
352   static class Recommendation {
353     String id;
354     String lesson;
355   }
356
357
358   static class SubmissionToPostWrapper {
359     Submission submission;
360
361     public SubmissionToPostWrapper(@NotNull String attemptId, @NotNull String language, @NotNull String code) {
362       submission = new Submission(attemptId, new Submission.Reply(language, code));
363     }
364
365     static class Submission {
366       String attempt;
367       Reply reply;
368
369       public Submission(String attempt, Reply reply) {
370         this.attempt = attempt;
371         this.reply = reply;
372       }
373
374       static class Reply {
375         String language;
376         String code;
377
378         public Reply(String language, String code) {
379           this.language = language;
380           this.code = code;
381         }
382       }
383     }
384   }
385
386   static class ResultSubmissionWrapper {
387     ResultSubmission[] submissions;
388
389     static class ResultSubmission {
390       int id;
391       String status;
392       String hint;
393     }
394   }
395
396   static class AssignmentsWrapper {
397     List<Assignment> assignments;
398   }
399
400   static class Assignment {
401     int id;
402     int step;
403   }
404
405   static class ViewsWrapper {
406     View view;
407
408     public ViewsWrapper(final int assignment, final int step) {
409       this.view = new View(assignment, step);
410     }
411   }
412
413   static class View {
414     int assignment;
415     int step;
416
417     public View(int assignment, int step) {
418       this.assignment = assignment;
419       this.step = step;
420     }
421   }
422
423   static class Enrollment {
424     String course;
425
426     public Enrollment(String courseId) {
427       course = courseId;
428     }
429   }
430
431   static class EnrollmentWrapper {
432     Enrollment enrollment;
433
434     public EnrollmentWrapper(@NotNull final String courseId) {
435       enrollment = new Enrollment(courseId);
436     }
437   }
438
439   static class TokenInfo {
440     @Expose String accessToken;
441     @Expose String refreshToken;
442     @Expose String tokenType;
443     @Expose String scope;
444     @Expose int expiresIn;
445
446     public TokenInfo() {
447       accessToken = "";
448       refreshToken = "";
449     }
450
451     public String getAccessToken() {
452       return accessToken;
453     }
454
455     public String getRefreshToken() {
456       return refreshToken;
457     }
458   }
459 }