Fix according to review IDEA-CR-11509: 1) Don't post attempts to Stepic in Course...
authorValentina Kiryushkina <valentina.kiryushkina@jetbrains.com>
Tue, 21 Jun 2016 14:52:34 +0000 (17:52 +0300)
committerValentina Kiryushkina <valentina.kiryushkina@jetbrains.com>
Tue, 21 Jun 2016 16:20:39 +0000 (19:20 +0300)
python/educational-core/student/src/com/jetbrains/edu/learning/checker/StudyCheckTask.java
python/educational-core/student/src/com/jetbrains/edu/learning/courseGeneration/StudyProjectGenerator.java
python/educational-core/student/src/com/jetbrains/edu/learning/stepic/EduAdaptiveStepicConnector.java
python/educational-core/student/src/com/jetbrains/edu/learning/stepic/EduStepicConnector.java

index 62374bff04674b6841c45f5e30248f9a55022359..fd98e16901393d9b25fdc42fb8315fc48c6301f2 100644 (file)
@@ -17,6 +17,7 @@ import com.jetbrains.edu.learning.StudyState;
 import com.jetbrains.edu.learning.StudyTaskManager;
 import com.jetbrains.edu.learning.StudyUtils;
 import com.jetbrains.edu.learning.actions.StudyAfterCheckAction;
+import com.jetbrains.edu.learning.core.EduNames;
 import com.jetbrains.edu.learning.core.EduUtils;
 import com.jetbrains.edu.learning.courseFormat.Course;
 import com.jetbrains.edu.learning.courseFormat.StudyStatus;
@@ -95,7 +96,10 @@ public class StudyCheckTask extends com.intellij.openapi.progress.Task.Backgroun
         onTaskFailed(testsOutput.getMessage());
       }
       runAfterTaskCheckedActions();
-      postAttemptToStepic(testsOutput);
+      final Course course = StudyTaskManager.getInstance(myProject).getCourse();
+      if (course != null && EduNames.STUDY.equals(course.getCourseMode())) {
+        postAttemptToStepic(testsOutput);
+      }
     }
   }
 
index 8c2db07be964b76ceed3cb1a3ad3ca4a41a13b89..5f86fc96212c4acf5f260fceda0381dfecb9828d 100644 (file)
@@ -11,6 +11,7 @@ import com.intellij.openapi.fileEditor.FileEditorManager;
 import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.ThrowableComputable;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.LocalFileSystem;
@@ -59,7 +60,7 @@ public class StudyProjectGenerator {
   private final List<SettingsListener> myListeners = ContainerUtil.newArrayList();
   public StepicUser myUser;
   private List<CourseInfo> myCourses = new ArrayList<>();
-  private List<Integer> myEnrolledCoursesIds = new ArrayList<>(); 
+  private List<Integer> myEnrolledCoursesIds = new ArrayList<>();
   protected CourseInfo mySelectedCourseInfo;
 
   public void setCourses(List<CourseInfo> courses) {
@@ -69,7 +70,7 @@ public class StudyProjectGenerator {
   public boolean isLoggedIn() {
     return myUser != null && !StringUtil.isEmptyOrSpaces(myUser.getPassword()) && !StringUtil.isEmptyOrSpaces(myUser.getEmail());
   }
-  
+
   public void setEnrolledCoursesIds(@NotNull final List<Integer> coursesIds) {
     myEnrolledCoursesIds = coursesIds;
   }
@@ -88,21 +89,23 @@ public class StudyProjectGenerator {
     final Course course = getCourse(project);
     if (course == null) {
       LOG.warn("Course is null");
+      Messages.showWarningDialog("Some problems occurred while creating the course", "Error in Course Creation");
       return;
     }
     final File courseDirectory = StudyUtils.getCourseDirectory(project, course);
     StudyTaskManager.getInstance(project).setCourse(course);
     ApplicationManager.getApplication().runWriteAction(() -> {
-                                                         StudyGenerator.createCourse(course, baseDir, courseDirectory, project);
-                                                         course.setCourseDirectory(courseDirectory.getAbsolutePath());
-                                                         VirtualFileManager.getInstance().refreshWithoutFileWatcher(true);
-                                                         StudyProjectComponent.getInstance(project).registerStudyToolWindow(course);
-                                                         openFirstTask(course, project);
-                                                       });
+      StudyGenerator.createCourse(course, baseDir, courseDirectory, project);
+      course.setCourseDirectory(courseDirectory.getAbsolutePath());
+      VirtualFileManager.getInstance().refreshWithoutFileWatcher(true);
+      StudyProjectComponent.getInstance(project).registerStudyToolWindow(course);
+      openFirstTask(course, project);
+    });
   }
 
   @Nullable
   protected Course getCourse(@NotNull final Project project) {
+
     final File courseFile = new File(new File(OUR_COURSES_DIR, mySelectedCourseInfo.getName()), EduNames.COURSE_META_FILE);
     if (courseFile.exists()) {
       return readCourseFromCache(courseFile, false);
@@ -115,12 +118,21 @@ public class StudyProjectGenerator {
         return readCourseFromCache(adaptiveCourseFile, true);
       }
     }
-    final Course course = EduStepicConnector.getCourse(project, mySelectedCourseInfo);
-    if (course != null) {
-      flushCourse(project, course);
-      course.initCourse(false);
-    }
-    return course;
+    return ProgressManager.getInstance().runProcessWithProgressSynchronously(new ThrowableComputable<Course, RuntimeException>() {
+      @Override
+      public Course compute() throws RuntimeException {
+        ProgressManager.getInstance().getProgressIndicator().setIndeterminate(true);
+        return execCancelable(() -> {
+
+          final Course course = EduStepicConnector.getCourse(project, mySelectedCourseInfo);
+          if (course != null) {
+            flushCourse(project, course);
+            course.initCourse(false);
+          }
+          return course;
+        });
+      }
+    }, "Creating Course", true, project);
   }
 
   @Nullable
index 642b0a160b3b12d9beb96b068a8d6ebb8eca1633..fd50ea62cf7f2eb9742bc3654034ecf249cef91f 100644 (file)
@@ -10,6 +10,9 @@ import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.ui.MessageType;
+import com.intellij.openapi.ui.popup.Balloon;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.util.text.StringUtil;
@@ -28,6 +31,7 @@ import com.jetbrains.edu.learning.ui.StudyToolWindow;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpStatus;
 import org.apache.http.StatusLine;
+import org.apache.http.client.config.RequestConfig;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
@@ -55,6 +59,7 @@ public class EduAdaptiveStepicConnector {
   public static final String PYTHON27 = "python27";
   public static final String PYTHON3 = "python3";
   private static final Logger LOG = Logger.getInstance(EduAdaptiveStepicConnector.class);
+  private static final int CONNECTION_TIMEOUT = 60 * 1000;
 
   @Nullable
   public static Task getNextRecommendation(@NotNull final Project project, @NotNull Course course) {
@@ -65,6 +70,7 @@ public class EduAdaptiveStepicConnector {
         .build();
       final HttpGet request = new HttpGet(uri);
       setHeaders(request, EduStepicNames.CONTENT_TYPE_APPL_JSON);
+      setTimeout(request);
 
       final CloseableHttpResponse response = client.execute(request);
       final StatusLine statusLine = response.getStatusLine();
@@ -106,6 +112,17 @@ public class EduAdaptiveStepicConnector {
     }
     catch (IOException e) {
       LOG.warn(e.getMessage());
+
+      final String connectionMessages = "Connection problems, Please, try again";
+      final Balloon balloon =
+        JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(connectionMessages, MessageType.ERROR, null)
+          .createBalloon();
+      ApplicationManager.getApplication().invokeLater(() -> {
+        if (StudyUtils.getSelectedEditor(project) != null) {
+          StudyUtils.showCheckPopUp(project, balloon);
+        }
+      });
+      
     }
     catch (URISyntaxException e) {
       LOG.warn(e.getMessage());
@@ -113,6 +130,24 @@ public class EduAdaptiveStepicConnector {
     return null;
   }
 
+  private static void setTimeout(HttpGet request) {
+    final RequestConfig requestConfig = RequestConfig.custom()
+      .setConnectionRequestTimeout(CONNECTION_TIMEOUT)
+      .setConnectTimeout(CONNECTION_TIMEOUT)
+      .setSocketTimeout(CONNECTION_TIMEOUT)
+      .build();
+    request.setConfig(requestConfig);
+  }
+
+  private static void setTimeout(HttpPost request) {
+    final RequestConfig requestConfig = RequestConfig.custom()
+      .setConnectionRequestTimeout(CONNECTION_TIMEOUT)
+      .setConnectTimeout(CONNECTION_TIMEOUT)
+      .setSocketTimeout(CONNECTION_TIMEOUT)
+      .build();
+    request.setConfig(requestConfig);
+  }
+
   private static void viewAllSteps(CloseableHttpClient client, int lessonId) throws URISyntaxException, IOException {
     final URI unitsUrl = new URIBuilder(EduStepicNames.UNITS).addParameter(EduNames.LESSON, String.valueOf(lessonId)).build();
     final StepicWrappers.UnitContainer unitContainer = getFromStepic(unitsUrl.toString(), StepicWrappers.UnitContainer.class);
@@ -152,6 +187,7 @@ public class EduAdaptiveStepicConnector {
     post.setEntity(new StringEntity(json, ContentType.APPLICATION_JSON));
     final CloseableHttpClient client = getHttpClient(project);
     setHeaders(post, EduStepicNames.CONTENT_TYPE_APPL_JSON);
+    setTimeout(post);
     try {
       final CloseableHttpResponse execute = client.execute(post);
       return execute.getStatusLine().getStatusCode() == HttpStatus.SC_CREATED;
@@ -405,6 +441,7 @@ public class EduAdaptiveStepicConnector {
         new StepicWrappers.SubmissionToPostWrapper(String.valueOf(attemptId), language, text);
       final HttpPost httpPost = new HttpPost(EduStepicNames.STEPIC_API_URL + EduStepicNames.SUBMISSIONS);
       setHeaders(httpPost, EduStepicNames.CONTENT_TYPE_APPL_JSON);
+      setTimeout(httpPost);
       try {
         httpPost.setEntity(new StringEntity(new Gson().toJson(submissionToPostWrapper)));
       }
@@ -435,6 +472,7 @@ public class EduAdaptiveStepicConnector {
           .build();
         final HttpGet httpGet = new HttpGet(submissionURI);
         setHeaders(httpGet, EduStepicNames.CONTENT_TYPE_APPL_JSON);
+        setTimeout(httpGet);
         final CloseableHttpResponse httpResponse = client.execute(httpGet);
         final String entity = EntityUtils.toString(httpResponse.getEntity());
         wrapper = new Gson().fromJson(entity, StepicWrappers.ResultSubmissionWrapper.class);
@@ -481,6 +519,7 @@ public class EduAdaptiveStepicConnector {
 
     final CloseableHttpClient client = getHttpClient(project);
     setHeaders(post, EduStepicNames.CONTENT_TYPE_APPL_JSON);
+    setTimeout(post);
     final CloseableHttpResponse httpResponse = client.execute(post);
     final String entity = EntityUtils.toString(httpResponse.getEntity());
     final StepicWrappers.AttemptContainer container =
index 081081923c8f871ec59c019b08f4d2865b00e368..a70a18bb8c3fac652266138e2311b577dd2fc6c5 100644 (file)
@@ -334,9 +334,11 @@ public class EduStepicConnector {
       final Task recommendation = EduAdaptiveStepicConnector.getNextRecommendation(project, course);
       if (recommendation != null) {
         lesson.addTask(recommendation);
+        return course;
+      }
+      else {
+        return null;
       }
-
-      return course;
     }
     return null;
   }