1 package com.jetbrains.edu.coursecreator.actions;
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.EduDocumentListener;
26 import com.jetbrains.edu.EduNames;
27 import com.jetbrains.edu.EduUtils;
28 import com.jetbrains.edu.courseFormat.*;
29 import com.jetbrains.edu.coursecreator.CCProjectService;
30 import com.jetbrains.edu.oldCourseFormat.OldCourse;
31 import org.jetbrains.annotations.NotNull;
36 public class CCFromCourseArchive extends DumbAwareAction {
37 private static final Logger LOG = Logger.getInstance(CCFromCourseArchive.class.getName());
39 public CCFromCourseArchive() {
40 super("Unpack Course Archive", "Unpack Course Archive", AllIcons.FileTypes.Archive);
44 public void update(@NotNull AnActionEvent e) {
45 e.getPresentation().setEnabledAndVisible(false);
46 //CCProjectService.setCCActionAvailable(e);
50 public void actionPerformed(@NotNull AnActionEvent e) {
51 final Project project = e.getData(CommonDataKeys.PROJECT);
52 if (project == null) {
55 unpackCourseArchive(project);
58 private static void unpackCourseArchive(final Project project) {
59 FileChooserDescriptor descriptor = new FileChooserDescriptor(true, true, true, true, true, false);
61 final VirtualFile virtualFile = FileChooser.chooseFile(descriptor, project, null);
62 if (virtualFile == null) {
65 final String basePath = project.getBasePath();
66 if (basePath == null) return;
67 final CCProjectService service = CCProjectService.getInstance(project);
70 ZipUtil.unzip(null, new File(basePath), new File(virtualFile.getPath()), null, null, true);
71 reader = new InputStreamReader(new FileInputStream(new File(basePath, EduNames.COURSE_META_FILE)));
72 Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
73 Course course = gson.fromJson(reader, Course.class);
74 if (course == null || course.getLessons().isEmpty() || StringUtil.isEmptyOrSpaces(course.getLessons().get(0).getName())) {
78 catch (IOException e) {
79 LOG.error(e.getMessage());
81 reader = new InputStreamReader(new FileInputStream(new File(basePath, EduNames.COURSE_META_FILE)));
82 OldCourse oldCourse = gson.fromJson(reader, OldCourse.class);
83 course = EduUtils.transformOldCourse(oldCourse);
86 service.setCourse(course);
87 project.getBaseDir().refresh(false, true);
90 for (Lesson lesson : course.getLessons()) {
91 final VirtualFile lessonDir = project.getBaseDir().findChild(EduNames.LESSON + String.valueOf(index));
92 lesson.setIndex(index);
93 if (lessonDir == null) continue;
94 for (Task task : lesson.getTaskList()) {
95 final VirtualFile taskDir = lessonDir.findChild(EduNames.TASK + String.valueOf(taskIndex));
96 task.setIndex(taskIndex);
97 task.setLesson(lesson);
98 if (taskDir == null) continue;
99 for (final Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
100 ApplicationManager.getApplication().runWriteAction(new Runnable() {
103 createAnswerFile(project, taskDir, taskDir, entry);
113 catch (FileNotFoundException e) {
114 LOG.error(e.getMessage());
116 catch (IOException e) {
117 LOG.error(e.getMessage());
119 catch (JsonSyntaxException e) {
120 LOG.error(e.getMessage());
123 if (reader != null) {
127 catch (IOException e) {
128 LOG.error(e.getMessage());
132 synchronize(project);
135 public static void createAnswerFile(@NotNull final Project project,
136 @NotNull final VirtualFile userFileDir,
137 @NotNull final VirtualFile answerFileDir,
138 @NotNull final Map.Entry<String, TaskFile> taskFileEntry) {
139 final String name = taskFileEntry.getKey();
140 final TaskFile taskFile = taskFileEntry.getValue();
141 VirtualFile file = userFileDir.findChild(name);
143 String answerFileName = file.getNameWithoutExtension() + ".answer." + file.getExtension();
144 VirtualFile answerFile = answerFileDir.findChild(answerFileName);
145 if (answerFile != null) {
147 answerFile.delete(project);
149 catch (IOException e) {
154 answerFile = userFileDir.createChildData(project, answerFileName);
156 catch (IOException e) {
159 if (answerFile == null) return;
161 final Document originDocument = FileDocumentManager.getInstance().getDocument(file);
162 if (originDocument == null) {
165 final Document document = FileDocumentManager.getInstance().getDocument(answerFile);
166 if (document == null) return;
168 CommandProcessor.getInstance().executeCommand(project, new Runnable() {
171 ApplicationManager.getApplication().runWriteAction(new Runnable() {
174 document.replaceString(0, document.getTextLength(), originDocument.getCharsSequence());
178 }, "Create answer document", "Create answer document");
179 EduDocumentListener listener = new EduDocumentListener(taskFile, false);
180 document.addDocumentListener(listener);
181 taskFile.sortAnswerPlaceholders();
182 for (int i = taskFile.getAnswerPlaceholders().size() - 1; i >= 0; i--) {
183 final AnswerPlaceholder answerPlaceholder = taskFile.getAnswerPlaceholders().get(i);
184 replaceAnswerPlaceholder(project, document, answerPlaceholder);
186 CommandProcessor.getInstance().executeCommand(project, new Runnable() {
189 ApplicationManager.getApplication().runWriteAction(new Runnable() {
192 FileDocumentManager.getInstance().saveDocument(document);
197 document.removeDocumentListener(listener);
200 private static void replaceAnswerPlaceholder(@NotNull final Project project,
201 @NotNull final Document document,
202 @NotNull final AnswerPlaceholder answerPlaceholder) {
203 final int offset = answerPlaceholder.getRealStartOffset(document);
204 CommandProcessor.getInstance().executeCommand(project, new Runnable() {
207 ApplicationManager.getApplication().runWriteAction(new Runnable() {
210 final String text = document.getText(TextRange.create(offset, offset + answerPlaceholder.getLength()));
211 answerPlaceholder.setTaskText(text);
212 final VirtualFile hints = project.getBaseDir().findChild(EduNames.HINTS);
214 final String hintFile = answerPlaceholder.getHint();
215 final VirtualFile virtualFile = hints.findChild(hintFile);
216 if (virtualFile != null) {
217 final Document hintDocument = FileDocumentManager.getInstance().getDocument(virtualFile);
218 if (hintDocument != null) {
219 final String hintText = hintDocument.getText();
220 answerPlaceholder.setHint(hintText);
225 document.replaceString(offset, offset + answerPlaceholder.getLength(), answerPlaceholder.getPossibleAnswer());
226 FileDocumentManager.getInstance().saveDocument(document);
233 private static void synchronize(@NotNull final Project project) {
234 VirtualFileManager.getInstance().refreshWithoutFileWatcher(true);
235 ProjectView.getInstance(project).refresh();