add update of one task on stepic
authorEkaterina Tuzova <Ekaterina.Tuzova@jetbrains.com>
Tue, 19 Jul 2016 16:51:21 +0000 (19:51 +0300)
committerEkaterina Tuzova <Ekaterina.Tuzova@jetbrains.com>
Tue, 19 Jul 2016 18:11:41 +0000 (21:11 +0300)
python/educational-core/course-creator/resources/META-INF/plugin.xml
python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCPushTask.java [new file with mode: 0644]
python/educational-core/student/src/com/jetbrains/edu/learning/StudySerializationUtils.java
python/educational-core/student/src/com/jetbrains/edu/learning/checker/StudyCheckTask.java
python/educational-core/student/src/com/jetbrains/edu/learning/stepic/EduStepicConnector.java

index 94c1704c042943c08b4c4c636670ea8d80995bad..6fcf9ff9d11f6c988c3e9bea7d83e867c4634e93 100644 (file)
@@ -63,6 +63,7 @@
         <add-to-group group-id="EditorTabPopupMenu"/>
       </action>
       <action id="PackCourse" class="com.jetbrains.edu.coursecreator.actions.CCCreateCourseArchive"/>
+      <action id="PushTask" class="com.jetbrains.edu.coursecreator.actions.CCPushTask"/>
       <action id="PushLesson" class="com.jetbrains.edu.coursecreator.actions.CCPushLesson"/>
       <action id="PushCourse" class="com.jetbrains.edu.coursecreator.actions.CCPushCourse"/>
       <reference id="ChangeCourseInfo"/>
diff --git a/python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCPushTask.java b/python/educational-core/course-creator/src/com/jetbrains/edu/coursecreator/actions/CCPushTask.java
new file mode 100644 (file)
index 0000000..d9649da
--- /dev/null
@@ -0,0 +1,81 @@
+package com.jetbrains.edu.coursecreator.actions;
+
+import com.intellij.ide.IdeView;
+import com.intellij.ide.util.DirectoryChooserUtil;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.LangDataKeys;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiDirectory;
+import com.jetbrains.edu.learning.StudyTaskManager;
+import com.jetbrains.edu.learning.courseFormat.Course;
+import com.jetbrains.edu.learning.courseFormat.Lesson;
+import com.jetbrains.edu.learning.stepic.EduStepicConnector;
+import org.jetbrains.annotations.NotNull;
+
+public class CCPushTask extends DumbAwareAction {
+  public CCPushTask() {
+    super("Update Task on Stepic", "Update Task on Stepic", null);
+  }
+
+  @Override
+  public void update(@NotNull AnActionEvent e) {
+    e.getPresentation().setEnabledAndVisible(false);
+    final IdeView view = e.getData(LangDataKeys.IDE_VIEW);
+    final Project project = e.getData(CommonDataKeys.PROJECT);
+    if (view == null || project == null) {
+      return;
+    }
+    final Course course = StudyTaskManager.getInstance(project).getCourse();
+    if (course == null) {
+      return;
+    }
+    PsiDirectory taskDir = DirectoryChooserUtil.getOrChooseDirectory(view);
+    if (taskDir == null || !taskDir.getName().contains("task")) {
+      return;
+    }
+    final PsiDirectory lessonDir = taskDir.getParentDirectory();
+    if (lessonDir == null) return;
+    final Lesson lesson = course.getLesson(lessonDir.getName());
+    if (lesson != null && lesson.getId() > 0) {
+      e.getPresentation().setEnabledAndVisible(true);
+    }
+  }
+
+  @Override
+  public void actionPerformed(@NotNull AnActionEvent e) {
+    final IdeView view = e.getData(LangDataKeys.IDE_VIEW);
+    final Project project = e.getData(CommonDataKeys.PROJECT);
+    if (view == null || project == null) {
+      return;
+    }
+    final Course course = StudyTaskManager.getInstance(project).getCourse();
+    if (course == null) {
+      return;
+    }
+    PsiDirectory taskDir = DirectoryChooserUtil.getOrChooseDirectory(view);
+    if (taskDir == null || !taskDir.getName().contains("task")) {
+      return;
+    }
+    final PsiDirectory lessonDir = taskDir.getParentDirectory();
+    if (lessonDir == null) return;
+    final Lesson lesson = course.getLesson(lessonDir.getName());
+    if (lesson == null) return;
+
+    final com.jetbrains.edu.learning.courseFormat.Task task = lesson.getTask(taskDir.getName());
+    if (task == null) return;
+
+    ProgressManager.getInstance().run(new Task.Modal(project, "Uploading Task", true) {
+      @Override
+      public void run(@NotNull ProgressIndicator indicator) {
+        indicator.setText("Uploading task to http://stepic.org");
+        EduStepicConnector.updateTask(project, task);
+      }
+    });
+  }
+
+}
\ No newline at end of file
index 436ef8f3ebaadb1f494d765e5874f893113495cd..6926cb3796546f79dcd86fad0ae7746c86bc71db 100644 (file)
@@ -423,10 +423,12 @@ public class StudySerializationUtils {
         final int length = src.getLength();
         final int start = src.getOffset();
         final String possibleAnswer = src.getPossibleAnswer();
+        int line = -1;
 
         final Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
         final JsonObject answerPlaceholder = new JsonObject();
-        answerPlaceholder.addProperty(OFFSET, start);
+        answerPlaceholder.addProperty(LINE, line);
+        answerPlaceholder.addProperty(START, start);
         answerPlaceholder.addProperty(LENGTH, length);
         answerPlaceholder.addProperty(POSSIBLE_ANSWER, possibleAnswer);
 
index ddfea35c6925ce839840291f95c4fe1d160ff05d..ced92c91afb8c94b88844c6e8ec7f9122b25ecc6 100644 (file)
@@ -240,7 +240,6 @@ public class StudyCheckTask extends com.intellij.openapi.progress.Task.Backgroun
   protected void postAttemptToStepic(@NotNull StudyTestsOutputParser.TestsOutput testsOutput) {
     final StudyTaskManager studySettings = StudyTaskManager.getInstance(myProject);
     final StepicUser user = studySettings.getUser();
-    if (user == null) return;
     final String login = user.getEmail();
     final String password = StringUtil.isEmptyOrSpaces(login) ? "" : user.getPassword();
     EduStepicConnector.postAttempt(myTask, testsOutput.isSuccess(), login, password);
index 2698f74871776443d794aeff231fbf645c16ca7d..931e7ca5bd400c4c19662ddb8cfe7d26b914d68e 100644 (file)
@@ -3,6 +3,7 @@ package com.jetbrains.edu.learning.stepic;
 import com.google.gson.FieldNamingPolicy;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
+import com.google.gson.JsonObject;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.ModalityState;
 import com.intellij.openapi.diagnostic.Logger;
@@ -631,6 +632,41 @@ public class EduStepicConnector {
     return -1;
   }
 
+  public static int updateTask(@NotNull final Project project, @NotNull final Task task) {
+    final Lesson lesson = task.getLesson();
+    final int lessonId = lesson.getId();
+
+    final HttpPut request = new HttpPut(EduStepicNames.STEPIC_API_URL + "/step-sources/" + String.valueOf(task.getStepicId()));
+    setHeaders(request, "application/json");
+    if (ourClient == null) {
+      if (!login(project)) {
+        LOG.error("Failed to update task");
+        return 0;
+      }
+    }
+
+    final Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().
+      registerTypeAdapter(AnswerPlaceholder.class, new StudySerializationUtils.Json.StepicAnswerPlaceholderAdapter()).create();
+    ApplicationManager.getApplication().invokeLater(() -> {
+      final String requestBody = gson.toJson(new StepicWrappers.StepSourceWrapper(project, task, lessonId));
+      request.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
+
+      try {
+        final CloseableHttpResponse response = ourClient.execute(request);
+        final StatusLine line = response.getStatusLine();
+        if (line.getStatusCode() != HttpStatus.SC_OK) {
+          final HttpEntity responseEntity = response.getEntity();
+          final String responseString = responseEntity != null ? EntityUtils.toString(responseEntity) : "";
+          LOG.error("Failed to push " + responseString);
+        }
+      }
+      catch (IOException e) {
+        LOG.error(e.getMessage());
+      }
+    });
+    return -1;
+  }
+
   public static int updateLesson(@NotNull final Project project, @NotNull final Lesson lesson, ProgressIndicator indicator) {
     final HttpPut request = new HttpPut(EduStepicNames.STEPIC_API_URL + EduStepicNames.LESSONS + String.valueOf(lesson.getId()));
     if (ourClient == null) {
@@ -735,11 +771,15 @@ public class EduStepicConnector {
       try {
         final CloseableHttpResponse response = ourClient.execute(request);
         final StatusLine line = response.getStatusLine();
+        final HttpEntity responseEntity = response.getEntity();
+        final String responseString = responseEntity != null ? EntityUtils.toString(responseEntity) : "";
         if (line.getStatusCode() != HttpStatus.SC_CREATED) {
-          final HttpEntity responseEntity = response.getEntity();
-          final String responseString = responseEntity != null ? EntityUtils.toString(responseEntity) : "";
           LOG.error("Failed to push " + responseString);
         }
+
+        final JsonObject postedTask = new Gson().fromJson(responseString, JsonObject.class);
+        final JsonObject stepSource = postedTask.getAsJsonArray("step-sources").get(0).getAsJsonObject();
+        task.setStepicId(stepSource.getAsJsonPrimitive("id").getAsInt());
       }
       catch (IOException e) {
         LOG.error(e.getMessage());