fix unpack course action
[idea/community.git] / python / educational-core / course-creator / src / com / jetbrains / edu / coursecreator / actions / CCFromCourseArchive.java
1 package com.jetbrains.edu.coursecreator.actions;
2
3 import com.google.gson.FieldNamingPolicy;
4 import com.google.gson.Gson;
5 import com.google.gson.GsonBuilder;
6 import com.google.gson.JsonSyntaxException;
7 import com.intellij.icons.AllIcons;
8 import com.intellij.ide.projectView.ProjectView;
9 import com.intellij.openapi.actionSystem.AnActionEvent;
10 import com.intellij.openapi.actionSystem.CommonDataKeys;
11 import com.intellij.openapi.application.ApplicationManager;
12 import com.intellij.openapi.command.CommandProcessor;
13 import com.intellij.openapi.diagnostic.Logger;
14 import com.intellij.openapi.editor.Document;
15 import com.intellij.openapi.fileChooser.FileChooser;
16 import com.intellij.openapi.fileChooser.FileChooserDescriptor;
17 import com.intellij.openapi.fileEditor.FileDocumentManager;
18 import com.intellij.openapi.project.DumbAwareAction;
19 import com.intellij.openapi.project.Project;
20 import com.intellij.openapi.util.TextRange;
21 import com.intellij.openapi.util.text.StringUtil;
22 import com.intellij.openapi.vfs.VirtualFile;
23 import com.intellij.openapi.vfs.VirtualFileManager;
24 import com.intellij.platform.templates.github.ZipUtil;
25 import com.jetbrains.edu.coursecreator.CCUtils;
26 import com.jetbrains.edu.learning.StudyTaskManager;
27 import com.jetbrains.edu.learning.core.EduDocumentListener;
28 import com.jetbrains.edu.learning.core.EduNames;
29 import com.jetbrains.edu.learning.core.EduUtils;
30 import com.jetbrains.edu.learning.courseFormat.*;
31 import com.jetbrains.edu.learning.oldCourseFormat.OldCourse;
32 import org.jetbrains.annotations.NotNull;
33
34 import java.io.*;
35 import java.util.Map;
36
37 public class CCFromCourseArchive extends DumbAwareAction {
38   private static final Logger LOG = Logger.getInstance(CCFromCourseArchive.class.getName());
39
40   public CCFromCourseArchive() {
41     super("Unpack Course Archive", "Unpack Course Archive", AllIcons.FileTypes.Archive);
42   }
43
44   @Override
45   public void actionPerformed(@NotNull AnActionEvent e) {
46     final Project project = e.getData(CommonDataKeys.PROJECT);
47     if (project == null) {
48       return;
49     }
50     unpackCourseArchive(project);
51   }
52
53   private static void unpackCourseArchive(final Project project) {
54     FileChooserDescriptor descriptor = new FileChooserDescriptor(true, true, true, true, true, false);
55
56     final VirtualFile virtualFile = FileChooser.chooseFile(descriptor, project, null);
57     if (virtualFile == null) {
58       return;
59     }
60     final String basePath = project.getBasePath();
61     if (basePath == null) return;
62     Reader reader = null;
63     try {
64       ZipUtil.unzip(null, new File(basePath), new File(virtualFile.getPath()), null, null, true);
65       reader = new InputStreamReader(new FileInputStream(new File(basePath, EduNames.COURSE_META_FILE)));
66       Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
67       Course course = gson.fromJson(reader, Course.class);
68       if (course == null || course.getLessons().isEmpty() || StringUtil.isEmptyOrSpaces(course.getLessons().get(0).getName())) {
69         try {
70           reader.close();
71         }
72         catch (IOException e) {
73           LOG.error(e.getMessage());
74         }
75         reader = new InputStreamReader(new FileInputStream(new File(basePath, EduNames.COURSE_META_FILE)));
76         OldCourse oldCourse = gson.fromJson(reader, OldCourse.class);
77         course = EduUtils.transformOldCourse(oldCourse);
78       }
79
80       StudyTaskManager.getInstance(project).setCourse(course);
81       course.setCourseMode(CCUtils.COURSE_MODE);
82       project.getBaseDir().refresh(false, true);
83       int index = 1;
84       int taskIndex = 1;
85       for (Lesson lesson : course.getLessons()) {
86         final VirtualFile lessonDir = project.getBaseDir().findChild(EduNames.LESSON + String.valueOf(index));
87         lesson.setIndex(index);
88         if (lessonDir == null) continue;
89         for (Task task : lesson.getTaskList()) {
90           final VirtualFile taskDir = lessonDir.findChild(EduNames.TASK + String.valueOf(taskIndex));
91           task.setIndex(taskIndex);
92           task.setLesson(lesson);
93           if (taskDir == null) continue;
94           for (final Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
95             ApplicationManager.getApplication().runWriteAction(new Runnable() {
96               @Override
97               public void run() {
98                 createAnswerFile(project, taskDir, entry);
99               }
100             });
101           }
102           taskIndex += 1;
103         }
104         index += 1;
105         taskIndex = 1;
106       }
107       course.initCourse(true);
108     }
109     catch (FileNotFoundException e) {
110       LOG.error(e.getMessage());
111     }
112     catch (IOException e) {
113       LOG.error(e.getMessage());
114     }
115     catch (JsonSyntaxException e) {
116       LOG.error(e.getMessage());
117     }
118     finally {
119       if (reader != null) {
120         try {
121           reader.close();
122         }
123         catch (IOException e) {
124           LOG.error(e.getMessage());
125         }
126       }
127     }
128     synchronize(project);
129   }
130
131   public static void createAnswerFile(@NotNull final Project project,
132                                       @NotNull final VirtualFile userFileDir,
133                                       @NotNull final Map.Entry<String, TaskFile> taskFileEntry) {
134     final String name = taskFileEntry.getKey();
135     final TaskFile taskFile = taskFileEntry.getValue();
136     VirtualFile file = userFileDir.findChild(name);
137     assert file != null;
138     final Document originDocument = FileDocumentManager.getInstance().getDocument(file);
139     if (originDocument == null) {
140       return;
141     }
142     final Document document = FileDocumentManager.getInstance().getDocument(file);
143     if (document == null) return;
144
145     CommandProcessor.getInstance().executeCommand(project, new Runnable() {
146       @Override
147       public void run() {
148         ApplicationManager.getApplication().runWriteAction(new Runnable() {
149           @Override
150           public void run() {
151             document.replaceString(0, document.getTextLength(), originDocument.getCharsSequence());
152           }
153         });
154       }
155     }, "Create answer document", "Create answer document");
156     EduDocumentListener listener = new EduDocumentListener(taskFile, false);
157     document.addDocumentListener(listener);
158     taskFile.sortAnswerPlaceholders();
159     for (int i = taskFile.getAnswerPlaceholders().size() - 1; i >= 0; i--) {
160       final AnswerPlaceholder answerPlaceholder = taskFile.getAnswerPlaceholders().get(i);
161       replaceAnswerPlaceholder(project, document, answerPlaceholder);
162     }
163     CommandProcessor.getInstance().executeCommand(project, new Runnable() {
164       @Override
165       public void run() {
166         ApplicationManager.getApplication().runWriteAction(new Runnable() {
167           @Override
168           public void run() {
169             FileDocumentManager.getInstance().saveDocument(document);
170           }
171         });
172       }
173     }, "x", "qwe");
174     document.removeDocumentListener(listener);
175   }
176
177   private static void replaceAnswerPlaceholder(@NotNull final Project project,
178                                                @NotNull final Document document,
179                                                @NotNull final AnswerPlaceholder answerPlaceholder) {
180     final int offset = answerPlaceholder.getRealStartOffset(document);
181     CommandProcessor.getInstance().executeCommand(project, new Runnable() {
182       @Override
183       public void run() {
184         ApplicationManager.getApplication().runWriteAction(new Runnable() {
185           @Override
186           public void run() {
187             final String text = document.getText(TextRange.create(offset, offset + answerPlaceholder.getLength()));
188             answerPlaceholder.setTaskText(text);
189             answerPlaceholder.init();
190             final VirtualFile hints = project.getBaseDir().findChild(EduNames.HINTS);
191             if (hints != null) {
192               final String hintFile = answerPlaceholder.getHint();
193               final VirtualFile virtualFile = hints.findChild(hintFile);
194               if (virtualFile != null) {
195                 final Document hintDocument = FileDocumentManager.getInstance().getDocument(virtualFile);
196                 if (hintDocument != null) {
197                   final String hintText = hintDocument.getText();
198                   answerPlaceholder.setHint(hintText);
199                 }
200               }
201             }
202
203             document.replaceString(offset, offset + answerPlaceholder.getLength(), answerPlaceholder.getPossibleAnswer());
204             FileDocumentManager.getInstance().saveDocument(document);
205           }
206         });
207       }
208     }, "x", "qwe");
209   }
210
211   private static void synchronize(@NotNull final Project project) {
212     VirtualFileManager.getInstance().refreshWithoutFileWatcher(true);
213     ProjectView.getInstance(project).refresh();
214   }
215
216 }