cleanup, removed unneeded parameters
[idea/community.git] / python / educational-core / course-creator / src / com / jetbrains / edu / coursecreator / actions / CCCreateCourseArchive.java
1 package com.jetbrains.edu.coursecreator.actions;
2
3 import com.google.gson.Gson;
4 import com.google.gson.GsonBuilder;
5 import com.intellij.ide.projectView.ProjectView;
6 import com.intellij.openapi.actionSystem.AnActionEvent;
7 import com.intellij.openapi.actionSystem.CommonDataKeys;
8 import com.intellij.openapi.actionSystem.LangDataKeys;
9 import com.intellij.openapi.actionSystem.Presentation;
10 import com.intellij.openapi.application.ApplicationManager;
11 import com.intellij.openapi.diagnostic.Logger;
12 import com.intellij.openapi.module.Module;
13 import com.intellij.openapi.project.DumbAwareAction;
14 import com.intellij.openapi.project.Project;
15 import com.intellij.openapi.ui.DialogWrapper;
16 import com.intellij.openapi.ui.Messages;
17 import com.intellij.openapi.util.io.FileUtil;
18 import com.intellij.openapi.vfs.VfsUtil;
19 import com.intellij.openapi.vfs.VirtualFile;
20 import com.intellij.openapi.vfs.VirtualFileManager;
21 import com.intellij.util.containers.HashMap;
22 import com.intellij.util.io.ZipUtil;
23 import com.jetbrains.edu.coursecreator.CCLanguageManager;
24 import com.jetbrains.edu.coursecreator.CCUtils;
25 import com.jetbrains.edu.coursecreator.ui.CreateCourseArchiveDialog;
26 import com.jetbrains.edu.learning.StudyTaskManager;
27 import com.jetbrains.edu.learning.core.EduNames;
28 import com.jetbrains.edu.learning.core.EduUtils;
29 import com.jetbrains.edu.learning.courseFormat.*;
30 import org.jetbrains.annotations.NotNull;
31
32 import java.io.*;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.zip.ZipOutputStream;
36
37 public class CCCreateCourseArchive extends DumbAwareAction {
38   private static final Logger LOG = Logger.getInstance(CCCreateCourseArchive.class.getName());
39   private String myZipName;
40   private String myLocationDir;
41
42   public void setZipName(String zipName) {
43     myZipName = zipName;
44   }
45
46   public void setLocationDir(String locationDir) {
47     myLocationDir = locationDir;
48   }
49
50   public CCCreateCourseArchive() {
51     super("Generate Course Archive", "Generate Course Archive", null);
52   }
53
54   @Override
55   public void update(@NotNull AnActionEvent e) {
56     Presentation presentation = e.getPresentation();
57     Project project = e.getProject();
58     presentation.setEnabledAndVisible(project != null && CCUtils.isCourseCreator(project));
59   }
60
61   @Override
62   public void actionPerformed(@NotNull AnActionEvent e) {
63     final Project project = e.getData(CommonDataKeys.PROJECT);
64     final Module module = e.getData(LangDataKeys.MODULE);
65     if (project == null || module == null) {
66       return;
67     }
68     CreateCourseArchiveDialog dlg = new CreateCourseArchiveDialog(project, this);
69     dlg.show();
70     if (dlg.getExitCode() != DialogWrapper.OK_EXIT_CODE) {
71       return;
72     }
73     createCourseArchive(project, module, myZipName, myLocationDir, true);
74   }
75
76   public static void createCourseArchive(final Project project, Module module, String zipName, String locationDir, boolean showMessage) {
77     final Course course = StudyTaskManager.getInstance(project).getCourse();
78     if (course == null) return;
79     final VirtualFile baseDir = project.getBaseDir();
80     VirtualFile archiveFolder = CCUtils.generateFolder(project, module, zipName);
81     if (archiveFolder == null) {
82       return;
83     }
84
85     CCLanguageManager manager = CCUtils.getStudyLanguageManager(course);
86     if (manager == null) {
87       return;
88     }
89     FileFilter filter = pathname -> !manager.doNotPackFile(pathname);
90
91     for (VirtualFile child : baseDir.getChildren()) {
92       String name = child.getName();
93       File fromFile = new File(child.getPath());
94       if (CCUtils.GENERATED_FILES_FOLDER.equals(name) || ".idea".equals(name)
95           || name.contains("iml") || manager.doNotPackFile(fromFile)) {
96         continue;
97       }
98       copyChild(archiveFolder, filter, child, fromFile);
99     }
100
101     final List<Lesson> lessons = course.getLessons();
102
103     ApplicationManager.getApplication().runWriteAction(new Runnable() {
104       @Override
105       public void run() {
106         final Map<TaskFile, TaskFile> savedTaskFiles = new HashMap<TaskFile, TaskFile>();
107         replaceAnswerFilesWithTaskFiles(savedTaskFiles);
108         generateJson(project, archiveFolder);
109         resetTaskFiles(savedTaskFiles);
110         VirtualFileManager.getInstance().refreshWithoutFileWatcher(false);
111         packCourse(archiveFolder, locationDir, zipName, showMessage);
112         synchronize(project);
113       }
114
115       private void replaceAnswerFilesWithTaskFiles(Map<TaskFile, TaskFile> savedTaskFiles) {
116         for (Lesson lesson : lessons) {
117           final VirtualFile lessonDir = baseDir.findChild(EduNames.LESSON + String.valueOf(lesson.getIndex()));
118           if (lessonDir == null) continue;
119           for (Task task : lesson.getTaskList()) {
120             final VirtualFile taskDir = lessonDir.findChild(EduNames.TASK + String.valueOf(task.getIndex()));
121             if (taskDir == null) continue;
122             for (final Map.Entry<String, TaskFile> entry : task.getTaskFiles().entrySet()) {
123               TaskFile taskFileCopy = new TaskFile();
124               TaskFile taskFile = entry.getValue();
125               TaskFile.copy(taskFile, taskFileCopy);
126               savedTaskFiles.put(taskFile, taskFileCopy);
127
128               VirtualFile userFileDir = VfsUtil.findRelativeFile(archiveFolder, lessonDir.getName(), taskDir.getName());
129               if (userFileDir == null) {
130                 continue;
131               }
132               String taskFileName = entry.getKey();
133               EduUtils.createStudentFileFromAnswer(project, userFileDir, taskDir, taskFileName, taskFile);
134             }
135           }
136         }
137       }
138     });
139
140
141   }
142
143   private static void copyChild(VirtualFile archiveFolder, FileFilter filter, VirtualFile child, File fromFile) {
144     File toFile = new File(archiveFolder.getPath(), child.getName());
145
146     try {
147       if (child.isDirectory()) {
148         FileUtil.copyDir(fromFile, toFile, filter);
149       }
150       else {
151         if (filter.accept(fromFile)) {
152           FileUtil.copy(fromFile, toFile);
153         }
154       }
155     }
156     catch (IOException e) {
157       LOG.info("Failed to copy" + fromFile.getPath(), e);
158     }
159   }
160
161   private static void resetTaskFiles(Map<TaskFile, TaskFile> savedTaskFiles) {
162     for (Map.Entry<TaskFile, TaskFile> entry : savedTaskFiles.entrySet()) {
163       List<AnswerPlaceholder> placeholders = entry.getValue().getAnswerPlaceholders();
164       for (AnswerPlaceholder placeholder : placeholders) {
165         placeholder.setUseLength(false);
166       }
167       entry.getKey().setAnswerPlaceholders(placeholders);
168     }
169   }
170
171   private static void synchronize(@NotNull final Project project) {
172     VirtualFileManager.getInstance().refreshWithoutFileWatcher(true);
173     ProjectView.getInstance(project).refresh();
174   }
175
176   private static void packCourse(@NotNull final VirtualFile baseDir, String locationDir, String zipName, boolean showMessage) {
177     try {
178       final File zipFile = new File(locationDir, zipName + ".zip");
179       ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile)));
180       VirtualFile[] courseFiles = baseDir.getChildren();
181       for (VirtualFile file : courseFiles) {
182         ZipUtil.addFileOrDirRecursively(zos, null, new File(file.getPath()), file.getName(), null, null);
183       }
184       zos.close();
185       if (showMessage) {
186         Messages.showInfoMessage("Course archive was saved to " + zipFile.getPath(), "Course Archive Was Created Successfully");
187       }
188     }
189     catch (IOException e1) {
190       LOG.error(e1);
191     }
192   }
193
194   @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
195   private static void generateJson(@NotNull final Project project, VirtualFile parentDir) {
196     final Course course = StudyTaskManager.getInstance(project).getCourse();
197     final Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().create();
198     final String json = gson.toJson(course);
199     final File courseJson = new File(parentDir.getPath(), EduNames.COURSE_META_FILE);
200     OutputStreamWriter outputStreamWriter = null;
201     try {
202       outputStreamWriter = new OutputStreamWriter(new FileOutputStream(courseJson), "UTF-8");
203       outputStreamWriter.write(json);
204     }
205     catch (Exception e) {
206       Messages.showErrorDialog(e.getMessage(), "Failed to Generate Json");
207       LOG.info(e);
208     }
209     finally {
210       try {
211         if (outputStreamWriter != null) {
212           outputStreamWriter.close();
213         }
214       }
215       catch (IOException e1) {
216         //close silently
217       }
218     }
219   }
220 }