EDU-338 Add supported python versions info to the course.json
[idea/community.git] / python / educational-python / course-creator-python / src / com / jetbrains / edu / coursecreator / PyCCProjectGenerator.java
1 package com.jetbrains.edu.coursecreator;
2
3 import com.intellij.facet.ui.FacetEditorValidator;
4 import com.intellij.facet.ui.FacetValidatorsManager;
5 import com.intellij.facet.ui.ValidationResult;
6 import com.intellij.ide.fileTemplates.FileTemplate;
7 import com.intellij.ide.fileTemplates.FileTemplateManager;
8 import com.intellij.ide.fileTemplates.FileTemplateUtil;
9 import com.intellij.openapi.application.PathManager;
10 import com.intellij.openapi.command.WriteCommandAction;
11 import com.intellij.openapi.diagnostic.Logger;
12 import com.intellij.openapi.module.Module;
13 import com.intellij.openapi.progress.ProcessCanceledException;
14 import com.intellij.openapi.project.Project;
15 import com.intellij.openapi.ui.ComboBox;
16 import com.intellij.openapi.util.io.FileUtil;
17 import com.intellij.openapi.vfs.VirtualFile;
18 import com.intellij.platform.DirectoryProjectGenerator;
19 import com.intellij.psi.PsiDirectory;
20 import com.intellij.psi.PsiManager;
21 import com.jetbrains.edu.coursecreator.actions.CCCreateLesson;
22 import com.jetbrains.edu.coursecreator.actions.CCCreateTask;
23 import com.jetbrains.edu.coursecreator.ui.CCNewProjectPanel;
24 import com.jetbrains.edu.learning.StudyProjectComponent;
25 import com.jetbrains.edu.learning.StudyTaskManager;
26 import com.jetbrains.edu.learning.core.EduNames;
27 import com.jetbrains.edu.learning.courseFormat.Course;
28 import com.jetbrains.edu.learning.statistics.EduUsagesCollector;
29 import com.jetbrains.python.PythonLanguage;
30 import com.jetbrains.python.newProject.PythonProjectGenerator;
31 import com.jetbrains.python.psi.LanguageLevel;
32 import icons.CourseCreatorPythonIcons;
33 import org.jetbrains.annotations.Nls;
34 import org.jetbrains.annotations.NotNull;
35 import org.jetbrains.annotations.Nullable;
36
37 import javax.swing.*;
38 import java.io.File;
39
40
41 public class PyCCProjectGenerator extends PythonProjectGenerator implements DirectoryProjectGenerator {
42   private static final Logger LOG = Logger.getInstance(PyCCProjectGenerator.class);
43   public static final String ALL_VERSIONS = "All versions";
44   public static final String PYTHON_3 = "3x";
45   public static final String PYTHON_2 = "2x";
46   private CCNewProjectPanel mySettingsPanel;
47
48   @Nls
49   @NotNull
50   @Override
51   public String getName() {
52     return "Course creation";
53   }
54
55   @Nullable
56   @Override
57   public Icon getLogo() {
58     return CourseCreatorPythonIcons.CourseCreationProjectType;
59   }
60
61   @Override
62   public void generateProject(@NotNull final Project project, @NotNull final VirtualFile baseDir,
63                               @Nullable Object settings, @NotNull Module module) {
64     generateProject(project, baseDir, mySettingsPanel);
65   }
66
67   public static void generateProject(@NotNull final Project project, @NotNull final VirtualFile baseDir, CCNewProjectPanel settingsPanel) {
68     final Course course = getCourse(project, settingsPanel);
69     EduUsagesCollector.projectTypeCreated(CCUtils.COURSE_MODE);
70
71     final PsiDirectory projectDir = PsiManager.getInstance(project).findDirectory(baseDir);
72     if (projectDir == null) return;
73     new WriteCommandAction.Simple(project) {
74       @Override
75       protected void run() throws Throwable {
76
77         createTestHelper(project, projectDir);
78
79         PsiDirectory lessonDir = new CCCreateLesson().createItem(null, project, projectDir, course);
80         if (lessonDir == null) {
81           LOG.error("Failed to create lesson");
82           return;
83         }
84         new CCCreateTask().createItem(null, project, lessonDir, course);
85       }
86     }.execute();
87   }
88
89   private static void createTestHelper(@NotNull Project project, PsiDirectory projectDir) {
90     final FileTemplate template = FileTemplateManager.getInstance(project).getInternalTemplate(FileUtil.getNameWithoutExtension(EduNames.TEST_HELPER));
91     try {
92       FileTemplateUtil.createFromTemplate(template, EduNames.TEST_HELPER, null, projectDir);
93     }
94     catch (Exception ignored) {
95     }
96   }
97
98   @NotNull
99   private static Course getCourse(@NotNull Project project, @NotNull CCNewProjectPanel settingsPanel) {
100     final Course course = new Course();
101     String name = settingsPanel.getName();
102     course.setName(name);
103     course.setAuthors(settingsPanel.getAuthors());
104     course.setDescription(settingsPanel.getDescription());
105
106     String language = PythonLanguage.getInstance().getID();
107     String version = settingsPanel.getLanguageVersion();
108     if (version != null && !ALL_VERSIONS.equals(version)) {
109       language += " " + version;
110     }
111     course.setLanguage(language);
112     course.setCourseMode(CCUtils.COURSE_MODE);
113
114     File coursesDir = new File(PathManager.getConfigPath(), "courses");
115     File courseDir = new File(coursesDir, name + "-" + project.getName());
116     course.setCourseDirectory(courseDir.getPath());
117
118     StudyTaskManager.getInstance(project).setCourse(course);
119     StudyProjectComponent.getInstance(project).registerStudyToolWindow(course);
120     return course;
121   }
122
123   @NotNull
124   @Override
125   public ValidationResult validate(@NotNull String s) {
126     String message = "";
127     message = mySettingsPanel.getDescription().isEmpty() ? "Enter description" : message;
128     message = mySettingsPanel.getAuthors().length == 0 ? "Enter author name" : message;
129     message = mySettingsPanel.getName().isEmpty() ? "Enter course name" : message;
130     return message.isEmpty() ? ValidationResult.OK : new ValidationResult(message);
131   }
132
133   @Nullable
134   @Override
135   public JPanel extendBasePanel() throws ProcessCanceledException {
136     mySettingsPanel = new CCNewProjectPanel();
137     setupLanguageLevels(mySettingsPanel);
138     mySettingsPanel.registerValidators(new FacetValidatorsManager() {
139       public void registerValidator(FacetEditorValidator validator, JComponent... componentsToWatch) {
140         throw new UnsupportedOperationException();
141       }
142
143       public void validate() {
144         fireStateChanged();
145       }
146     });
147     return mySettingsPanel.getMainPanel();
148   }
149
150   private static void setupLanguageLevels(CCNewProjectPanel panel) {
151     JLabel languageLevelLabel = panel.getLanguageLevelLabel();
152     languageLevelLabel.setText("Python Version:");
153     languageLevelLabel.setVisible(true);
154     ComboBox<String> languageLevelCombobox = panel.getLanguageLevelCombobox();
155     languageLevelCombobox.addItem(ALL_VERSIONS);
156     languageLevelCombobox.addItem(PYTHON_3);
157     languageLevelCombobox.addItem(PYTHON_2);
158     for (LanguageLevel level : LanguageLevel.values()) {
159       languageLevelCombobox.addItem(level.toString());
160     }
161     languageLevelCombobox.setVisible(true);
162   }
163 }