From bbc7ac48906c9aa0b56173b43b1351ae0b78cb15 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Fri, 16 Dec 2016 15:22:19 +0300 Subject: [PATCH 1/5] create your own private course --- .../learning/stepic/EduStepicConnector.java | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/EduStepicConnector.java b/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/EduStepicConnector.java index 4627f4e91750..523b6359d32e 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/EduStepicConnector.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/EduStepicConnector.java @@ -230,17 +230,17 @@ public class EduStepicConnector { public static List getLessons(@NotNull Project project, int sectionId) throws IOException { final StepicWrappers.SectionContainer - sectionContainer = EduStepicClient.getFromStepic(EduStepicNames.SECTIONS + String.valueOf(sectionId), - StepicWrappers.SectionContainer.class); + sectionContainer = getFromStepic(EduStepicNames.SECTIONS + String.valueOf(sectionId), + StepicWrappers.SectionContainer.class, project); List unitIds = sectionContainer.sections.get(0).units; final List lessons = new ArrayList<>(); for (Integer unitId : unitIds) { StepicWrappers.UnitContainer - unit = EduStepicClient.getFromStepic(EduStepicNames.UNITS + "/" + String.valueOf(unitId), StepicWrappers.UnitContainer.class); + unit = getFromStepic(EduStepicNames.UNITS + "/" + String.valueOf(unitId), StepicWrappers.UnitContainer.class, project); int lessonID = unit.units.get(0).lesson; StepicWrappers.LessonContainer - lessonContainer = EduStepicClient.getFromStepic(EduStepicNames.LESSONS + String.valueOf(lessonID), - StepicWrappers.LessonContainer.class); + lessonContainer = getFromStepic(EduStepicNames.LESSONS + String.valueOf(lessonID), + StepicWrappers.LessonContainer.class, project); Lesson lesson = lessonContainer.lessons.get(0); lesson.taskList = new ArrayList<>(); for (int stepId : lesson.steps) { @@ -257,6 +257,17 @@ public class EduStepicConnector { return lessons; } + private static T getFromStepic(String link, final Class container, @Nullable final Project project) throws IOException{ + if (project != null) { + final StepicUser user = StudyTaskManager.getInstance(project).getUser(); + final boolean isAuthorized = user.getAccessToken() != null; + if (isAuthorized) { + return EduStepicAuthorizedClient.getFromStepic(link, container, user); + } + } + return EduStepicClient.getFromStepic(link, container); + } + @Nullable public static Task createTask(@NotNull Project project, int stepicId) throws IOException { final StepicWrappers.StepSource step = getStep(project, stepicId); @@ -285,16 +296,8 @@ public class EduStepicConnector { } public static StepicWrappers.StepSource getStep(@NotNull Project project, int step) throws IOException { - final StudyTaskManager taskManager = StudyTaskManager.getInstance(project); - final boolean isAuthorized = taskManager.getUser().getAccessToken() != null; - if (isAuthorized) { - return EduStepicAuthorizedClient.getFromStepic(EduStepicNames.STEPS + String.valueOf(step), + return getFromStepic(EduStepicNames.STEPS + String.valueOf(step), StepicWrappers.StepContainer.class, project).steps.get(0); - } - else { - return EduStepicClient.getFromStepic(EduStepicNames.STEPS + String.valueOf(step), - StepicWrappers.StepContainer.class).steps.get(0); - } } public static void postSolution(@NotNull final Task task, boolean passed, @NotNull final Project project) { From 62f53794b1c59869c833400c49e7e750da37499d Mon Sep 17 00:00:00 2001 From: "Liana.Bakradze" Date: Fri, 16 Dec 2016 15:40:33 +0300 Subject: [PATCH 2/5] EDU-806 Upload task descriptions and tests for all subtasks --- .../jetbrains/edu/learning/StudyUtils.java | 6 +- .../edu/learning/courseFormat/Task.java | 9 +++ .../StudyProjectGenerator.java | 45 +++++++---- .../stepic/EduAdaptiveStepicConnector.java | 2 +- .../learning/stepic/EduStepicConnector.java | 10 ++- .../edu/learning/stepic/StepicWrappers.java | 79 +++++++++++++++---- 6 files changed, 114 insertions(+), 37 deletions(-) diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyUtils.java b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyUtils.java index 10a14e60b356..99d184d14744 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/StudyUtils.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/StudyUtils.java @@ -310,7 +310,11 @@ public class StudyUtils { if (manager == null) { return false; } - return manager.getTestFileName().equals(name); + String testFileName = manager.getTestFileName(); + if (name.equals(testFileName)) { + return true; + } + return name.startsWith(FileUtil.getNameWithoutExtension(testFileName)) && name.contains(EduNames.SUBTASK_MARKER); } @Nullable diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/courseFormat/Task.java b/python/educational-core/student/src/com/jetbrains/edu/learning/courseFormat/Task.java index b54508d83820..9d34cdbcc034 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/courseFormat/Task.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/courseFormat/Task.java @@ -39,6 +39,7 @@ public class Task implements StudyItem { private String text; private Map testsText = new HashMap<>(); + private Map taskTexts = new HashMap<>(); @Transient private Lesson myLesson; @Expose @SerializedName("update_date") private Date myUpdateDate; @@ -95,10 +96,18 @@ public class Task implements StudyItem { return testsText; } + public Map getTaskTexts() { + return taskTexts; + } + public void addTestsTexts(String name, String text) { testsText.put(name, text); } + public void addTaskText(String name, String text) { + taskTexts.put(name, text); + } + public Map getTaskFiles() { return taskFiles; } diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java b/python/educational-core/student/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java index b21504b714d7..58c56e80fdf2 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java @@ -284,30 +284,43 @@ public class StudyProjectGenerator { } } catch (IOException e) { - LOG.error("ERROR copying file " + name); + LOG.error(e); } } - final Map testsText = task.getTestsText(); - for (Map.Entry entry : testsText.entrySet()) { - final File testsFile = new File(taskDirectory, entry.getKey()); - if (testsFile.exists()) { - FileUtil.delete(testsFile); - } - FileUtil.createIfDoesntExist(testsFile); - try { - FileUtil.writeToFile(testsFile, entry.getValue()); - } - catch (IOException e) { - LOG.error("ERROR copying tests file"); - } + createFiles(taskDirectory, task.getTestsText()); + if (task.getTaskTexts().isEmpty()) { + createTaskHtml(task, taskDirectory); + return; } - final File taskText = new File(taskDirectory, "task.html"); + task.setText(null); + createFiles(taskDirectory, task.getTaskTexts()); + + } + + private static void createTaskHtml(@NotNull Task task, @NotNull File taskDirectory) { + final File taskText = new File(taskDirectory, EduNames.TASK_HTML); FileUtil.createIfDoesntExist(taskText); try { FileUtil.writeToFile(taskText, task.getText()); } catch (IOException e) { - LOG.error("ERROR copying tests file"); + LOG.error(e); + } + } + + private static void createFiles(@NotNull File taskDirectory, Map files) { + for (Map.Entry entry : files.entrySet()) { + final File file = new File(taskDirectory, entry.getKey()); + if (file.exists()) { + FileUtil.delete(file); + } + FileUtil.createIfDoesntExist(file); + try { + FileUtil.writeToFile(file, entry.getValue()); + } + catch (IOException e) { + LOG.error(e); + } } } diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/EduAdaptiveStepicConnector.java b/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/EduAdaptiveStepicConnector.java index e8e200f4c199..ef9e9e156ab1 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/EduAdaptiveStepicConnector.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/EduAdaptiveStepicConnector.java @@ -432,7 +432,7 @@ public class EduAdaptiveStepicConnector { } if (step.options.test != null) { - for (StepicWrappers.TestFileWrapper wrapper : step.options.test) { + for (StepicWrappers.FileWrapper wrapper : step.options.test) { task.addTestsTexts(wrapper.name, wrapper.text); } } diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/EduStepicConnector.java b/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/EduStepicConnector.java index 523b6359d32e..963864e11e72 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/EduStepicConnector.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/EduStepicConnector.java @@ -280,11 +280,17 @@ public class EduStepicConnector { task.setStepId(stepicId); task.setUpdateDate(step.update_date); task.setName(block.options != null ? block.options.title : (PYCHARM_PREFIX + CURRENT_VERSION)); - task.setText(block.text); task.setLastSubtaskIndex(block.options.lastSubtaskIndex); - for (StepicWrappers.TestFileWrapper wrapper : block.options.test) { + for (StepicWrappers.FileWrapper wrapper : block.options.test) { task.addTestsTexts(wrapper.name, wrapper.text); } + if (block.options.text != null) { + for (StepicWrappers.FileWrapper wrapper : block.options.text) { + task.addTaskText(wrapper.name, wrapper.text); + } + } else { + task.setText(block.text); + } task.taskFiles = new HashMap<>(); // TODO: it looks like we don't need taskFiles as map anymore if (block.options.files != null) { diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/StepicWrappers.java b/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/StepicWrappers.java index c888c5707af0..159e87c1f033 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/StepicWrappers.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/stepic/StepicWrappers.java @@ -7,7 +7,9 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; +import com.jetbrains.edu.learning.StudyUtils; import com.jetbrains.edu.learning.core.EduNames; import com.jetbrains.edu.learning.core.EduUtils; import com.jetbrains.edu.learning.courseFormat.Course; @@ -21,6 +23,7 @@ import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.io.InputStream; import java.util.*; +import java.util.stream.Collectors; public class StepicWrappers { private static final Logger LOG = Logger.getInstance(StepOptions.class); @@ -44,10 +47,10 @@ public class StepicWrappers { } public static class StepOptions { - @Expose List test; + @Expose List test; @Expose String title; @Expose List files; - @Expose String text; + @Expose List text; @Expose List> samples; @Expose Integer executionMemoryLimit; @Expose Integer executionTimeLimit; @@ -61,6 +64,7 @@ public class StepicWrappers { final StepOptions source = new StepOptions(); source.lastSubtaskIndex = task.getLastSubtaskIndex(); setTests(task, source, project); + setTaskTexts(task, source, project); source.files = new ArrayList<>(); source.title = task.getName(); for (final Map.Entry entry : task.getTaskFiles().entrySet()) { @@ -104,22 +108,63 @@ public class StepicWrappers { return source; } - private static void setTests(@NotNull final Task task, @NotNull final StepOptions source, @NotNull final Project project) { + private static void setTaskTexts(@NotNull Task task, @NotNull StepOptions stepOptions, @NotNull Project project) { + stepOptions.text = new ArrayList<>(); + VirtualFile taskDir = task.getTaskDir(project); + if (taskDir == null) { + return; + } + List taskDescriptionFiles = Arrays.stream(taskDir.getChildren()) + .filter(virtualFile -> StudyUtils.isTaskDescriptionFile(virtualFile.getName())) + .collect(Collectors.toList()); + for (VirtualFile taskDescriptionFile : taskDescriptionFiles) { + addFileWrapper(taskDescriptionFile, stepOptions.text); + } + } + + private static void setTests(@NotNull Task task, @NotNull StepOptions source, @NotNull Project project) { final Map testsText = task.getTestsText(); + source.test = new ArrayList<>(); if (testsText.isEmpty()) { - ApplicationManager.getApplication().runReadAction(() -> { - source.test = Collections.singletonList(new TestFileWrapper(EduNames.TESTS_FILE, task.getTestsText(project))); - }); + List testFiles = getTestFiles(task, project); + for (VirtualFile testFile : testFiles) { + addFileWrapper(testFile, source.test); + } } else { - source.test = new ArrayList<>(); for (Map.Entry entry : testsText.entrySet()) { - source.test.add(new TestFileWrapper(entry.getKey(), entry.getValue())); + source.test.add(new FileWrapper(entry.getKey(), entry.getValue())); } } } } + private static void addFileWrapper(@NotNull VirtualFile file, List wrappers) { + try { + wrappers.add(new FileWrapper(file.getName(), VfsUtilCore.loadText(file))); + } + catch (IOException e) { + LOG.error(e); + } + } + + private static List getTestFiles(@NotNull Task task, @NotNull Project project) { + List testFiles = new ArrayList<>(); + VirtualFile taskDir = task.getTaskDir(project); + if (taskDir == null) { + return testFiles; + } + if (!task.hasSubtasks()) { + VirtualFile testFile = taskDir.findChild(EduNames.TESTS_FILE); + testFiles.add(testFile); + return testFiles; + } + testFiles.addAll(Arrays.stream(taskDir.getChildren()) + .filter(file -> StudyUtils.isTestsFile(project, file.getName())) + .collect(Collectors.toList())); + return testFiles; + } + static class CodeTemplatesWrapper { String python3; String python27; @@ -191,11 +236,11 @@ public class StepicWrappers { } } - static class TestFileWrapper { + static class FileWrapper { @Expose public final String name; @Expose public final String text; - public TestFileWrapper(String name, String text) { + public FileWrapper(String name, String text) { this.name = name; this.text = text; } @@ -269,12 +314,12 @@ public class StepicWrappers { public Attempt(int step) { this.step = step; } - + public boolean isActive() { return status.equals("active"); } } - + static class Dataset { boolean is_multiple_choice; List options; @@ -382,7 +427,7 @@ public class StepicWrappers { public SubmissionToPostWrapper(@NotNull String attemptId, @NotNull String language, @NotNull String code) { submission = new Submission(attemptId, new Submission.CodeReply(language, code)); } - + public SubmissionToPostWrapper(@NotNull String attemptId, boolean[] choices) { submission = new Submission(attemptId, new Submission.ChoiceReply(choices)); } @@ -396,11 +441,11 @@ public class StepicWrappers { this.reply = reply; } - + interface Reply { - + } - + static class CodeReply implements Reply { String language; String code; @@ -410,7 +455,7 @@ public class StepicWrappers { this.code = code; } } - + static class ChoiceReply implements Reply { boolean[] choices; From 063ec0416ba6157fa7cec90bed617c8f51d870cf Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Fri, 16 Dec 2016 15:44:23 +0300 Subject: [PATCH 3/5] javac indices: enable in all tests --- .../src/com/intellij/compiler/CompilerReferenceService.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/java/java-indexing-impl/src/com/intellij/compiler/CompilerReferenceService.java b/java/java-indexing-impl/src/com/intellij/compiler/CompilerReferenceService.java index ab49c954a003..0459aae0d45e 100644 --- a/java/java-indexing-impl/src/com/intellij/compiler/CompilerReferenceService.java +++ b/java/java-indexing-impl/src/com/intellij/compiler/CompilerReferenceService.java @@ -15,7 +15,6 @@ */ package com.intellij.compiler; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.AbstractProjectComponent; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; @@ -29,7 +28,6 @@ import org.jetbrains.annotations.Nullable; public abstract class CompilerReferenceService extends AbstractProjectComponent { public static final RegistryValue IS_ENABLED_KEY = Registry.get("compiler.ref.index"); - public static volatile boolean enabledInTests = false; protected CompilerReferenceService(Project project) { super(project); @@ -55,6 +53,6 @@ public abstract class CompilerReferenceService extends AbstractProjectComponent @NotNull FileType searchFileType); public static boolean isEnabled() { - return (!ApplicationManager.getApplication().isHeadlessEnvironment() || enabledInTests) && IS_ENABLED_KEY.asBoolean(); + return IS_ENABLED_KEY.asBoolean(); } } From 254a68b3e586dc3672b0d9d3895d69723ef8479d Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Fri, 16 Dec 2016 15:56:02 +0300 Subject: [PATCH 4/5] fix missed shadow for lightweight dialog --- .../ui/impl/GlassPaneDialogWrapperPeer.java | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/impl/GlassPaneDialogWrapperPeer.java b/platform/platform-impl/src/com/intellij/openapi/ui/impl/GlassPaneDialogWrapperPeer.java index 2307ae19586c..fc22282153dc 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/impl/GlassPaneDialogWrapperPeer.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/impl/GlassPaneDialogWrapperPeer.java @@ -44,7 +44,6 @@ import com.intellij.ui.FocusTrackback; import com.intellij.ui.ScreenUtil; import com.intellij.ui.components.JBLayeredPane; import com.intellij.util.ui.JBInsets; -import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -383,9 +382,10 @@ public class GlassPaneDialogWrapperPeer extends DialogWrapperPeer implements Foc private JComponent myContentPane; private MyRootPane myRootPane; private BufferedImage shadow; + private int shadowWidth; + private int shadowHeight; private final JLayeredPane myTransparentPane; private JButton myDefaultButton; - private Dimension myShadowSize = null; private final Container myWrapperPane; private Component myPreviouslyFocusedComponent; private Dimension myCachedSize = null; @@ -468,10 +468,6 @@ public class GlassPaneDialogWrapperPeer extends DialogWrapperPeer implements Foc return result; } - public Container getTransparentPane() { - return myTransparentPane; - } - private TransparentLayeredPane getExistingTransparentPane() { for (int i = 0; i < myPane.getComponentCount(); i++) { Component c = myPane.getComponent(i); @@ -570,15 +566,13 @@ public class GlassPaneDialogWrapperPeer extends DialogWrapperPeer implements Foc } super.setBounds(x, y, width, height); - if (myShadowSize == null || !myShadowSize.equals(getSize())) { - createShadow(); - myShadowSize = getSize(); + if (RemoteDesktopDetector.isRemoteSession()) { + shadow = null; } - } - - private void createShadow() { - if (!RemoteDesktopDetector.isRemoteSession() && !JBUI.isHiDPI()) { - shadow = ShadowBorderPainter.createShadow(this, getWidth(), getHeight()); + else if (shadow == null || shadowWidth != width || shadowHeight != height) { + shadow = ShadowBorderPainter.createShadow(this, width, height); + shadowWidth = width; + shadowHeight = height; } } From a9a367dd02d211b8a5f01f76605e5ddb222e2973 Mon Sep 17 00:00:00 2001 From: "Liana.Bakradze" Date: Fri, 16 Dec 2016 15:59:38 +0300 Subject: [PATCH 5/5] remove pycharm additional lessons --- .../edu/learning/courseGeneration/StudyProjectGenerator.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java b/python/educational-core/student/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java index 58c56e80fdf2..2b6f2ab6530c 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java @@ -222,9 +222,11 @@ public class StudyProjectGenerator { flushCourseJson(course, courseDirectory); int lessonIndex = 1; + List additionalLessons = new ArrayList<>(); for (Lesson lesson : course.getLessons()) { if (lesson.getName().equals(EduNames.PYCHARM_ADDITIONAL)) { flushAdditionalFiles(courseDirectory, lesson); + additionalLessons.add(lesson); } else { final File lessonDirectory = new File(courseDirectory, EduNames.LESSON + String.valueOf(lessonIndex)); @@ -232,6 +234,9 @@ public class StudyProjectGenerator { lessonIndex += 1; } } + for (Lesson lesson : additionalLessons) { + course.getLessons().remove(lesson); + } } private static void flushAdditionalFiles(File courseDirectory, Lesson lesson) {