store stepic user in study task manager (per project)

due to some strange behaviour on startup
This commit is contained in:
Ekaterina Tuzova
2016-12-17 16:57:56 +03:00
parent b5ce9665c0
commit 3f4e4989d0
17 changed files with 161 additions and 126 deletions
@@ -61,14 +61,14 @@ public class CCGetCourseFromStepic extends DumbAwareAction {
private static void createCourse(Project project, String courseId) {
final VirtualFile baseDir = project.getBaseDir();
final CourseInfo info = CCStepicConnector.getCourseInfo(courseId);
final CourseInfo info = CCStepicConnector.getCourseInfo(project, courseId);
if (info == null) return;
final Course course = EduStepicConnector.getCourse(project, info);
if (course != null) {
flushCourse(course);
flushCourse(project, course);
final File courseDirectory = StudyUtils.getCourseDirectory(course);
final File courseDirectory = StudyUtils.getCourseDirectory(project, course);
ApplicationManager.getApplication().invokeAndWait(() -> ApplicationManager.getApplication().runWriteAction(() -> {
final VirtualFile[] children = baseDir.getChildren();
for (VirtualFile child : children) {
@@ -66,7 +66,7 @@ public class CCPushCourse extends DumbAwareAction {
final int lessonId = CCStepicConnector.postLesson(project, lesson, indicator);
final List<Integer> sections = info.getSections();
final Integer sectionId = sections.get(sections.size() - 1);
CCStepicConnector.postUnit(lessonId, lesson.getIndex(), sectionId);
CCStepicConnector.postUnit(project, lessonId, lesson.getIndex(), sectionId);
}
}
}
@@ -84,7 +84,7 @@ public class CCPushLesson extends DumbAwareAction {
final int lessonId = CCStepicConnector.postLesson(project, lesson, indicator);
final List<Integer> sections = info.getSections();
final Integer sectionId = sections.get(sections.size()-1);
CCStepicConnector.postUnit(lessonId, lesson.getIndex(), sectionId);
CCStepicConnector.postUnit(project, lessonId, lesson.getIndex(), sectionId);
}
}});
}
@@ -0,0 +1,26 @@
package com.jetbrains.edu.learning;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.edu.learning.courseFormat.Task;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class StudyCourseResourceManager {
/**
* Gets text of resource file such as test input file or task text in needed format
*
* @param fileName name of resource file which should exist in task directory
* @param wrapHTML if it's necessary to wrap text with html tags
* @return text of resource file wrapped with html tags if necessary
*/
@Nullable
public String getResourceText(@NotNull final Project project, @NotNull final Task task, @NotNull final String fileName, boolean wrapHTML) {
VirtualFile taskDir = task.getTaskDir(project);
if (taskDir != null) {
return StudyUtils.getFileText(taskDir.getCanonicalPath(), fileName, wrapHTML, "UTF-8");
}
return null;
}
}
@@ -148,7 +148,7 @@ public class StudyProjectComponent implements ProjectComponent {
final Course course = EduStepicConnector.getCourse(myProject, info);
if (course == null) return;
flushCourse(course);
flushCourse(myProject, course);
course.initCourse(false);
StudyLanguageManager manager = StudyUtils.getLanguageManager(course);
@@ -13,6 +13,7 @@ import com.intellij.util.xmlb.XmlSerializer;
import com.intellij.util.xmlb.annotations.Transient;
import com.jetbrains.edu.learning.courseFormat.*;
import com.jetbrains.edu.learning.courseGeneration.StudyProjectGenerator;
import com.jetbrains.edu.learning.stepic.StepicUser;
import com.jetbrains.edu.learning.ui.StudyToolWindow;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;
@@ -34,6 +35,7 @@ import java.util.Map;
public class StudyTaskManager implements PersistentStateComponent<Element>, DumbAware {
private static final Logger LOG = Logger.getInstance(StudyTaskManager.class);
public static final int CURRENT_VERSION = 4;
private StepicUser myUser = new StepicUser();
private Course myCourse;
public int VERSION = 4;
@@ -197,6 +199,15 @@ public class StudyTaskManager implements PersistentStateComponent<Element>, Dumb
myTurnEditingMode = turnEditingMode;
}
@NotNull
public StepicUser getUser() {
return myUser;
}
public void setUser(@NotNull final StepicUser user) {
myUser = user;
}
public boolean isEnableTestingFromSamples() {
return myEnableTestingFromSamples;
}
@@ -61,7 +61,6 @@ import com.jetbrains.edu.learning.core.EduUtils;
import com.jetbrains.edu.learning.courseFormat.*;
import com.jetbrains.edu.learning.courseGeneration.StudyProjectGenerator;
import com.jetbrains.edu.learning.editor.StudyEditor;
import com.jetbrains.edu.learning.stepic.StepicUpdateSettings;
import com.jetbrains.edu.learning.ui.StudyToolWindow;
import com.jetbrains.edu.learning.ui.StudyToolWindowFactory;
import com.petebevin.markdown.MarkdownProcessor;
@@ -628,12 +627,12 @@ public class StudyUtils {
}
@NotNull
public static File getCourseDirectory(Course course) {
public static File getCourseDirectory(@NotNull Project project, Course course) {
final File courseDirectory;
if (course.isAdaptive()) {
courseDirectory = new File(StudyProjectGenerator.OUR_COURSES_DIR,
StudyProjectGenerator.ADAPTIVE_COURSE_PREFIX + course.getName()
+ "_" + StepicUpdateSettings.getInstance().getUser().getEmail());
+ "_" + StudyTaskManager.getInstance(project).getUser().getEmail());
}
else {
courseDirectory = new File(StudyProjectGenerator.OUR_COURSES_DIR, course.getName());
@@ -23,7 +23,6 @@ import com.jetbrains.edu.learning.core.EduUtils;
import com.jetbrains.edu.learning.courseFormat.*;
import com.jetbrains.edu.learning.stepic.EduAdaptiveStepicConnector;
import com.jetbrains.edu.learning.stepic.EduStepicConnector;
import com.jetbrains.edu.learning.stepic.StepicUpdateSettings;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -105,7 +104,7 @@ public class StudyCheckTask extends com.intellij.openapi.progress.Task.Backgroun
runAfterTaskCheckedActions();
final Course course = StudyTaskManager.getInstance(myProject).getCourse();
if (course != null && EduNames.STUDY.equals(course.getCourseMode())) {
if (StepicUpdateSettings.getInstance().getUser().getAccessToken() != null) {
if (StudyTaskManager.getInstance(myProject).getUser().getAccessToken() != null) {
EduStepicConnector.postSolution(myTask, testsOutput.isSuccess(), myProject);
}
}
@@ -14,6 +14,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
@@ -36,7 +37,6 @@ import com.jetbrains.edu.learning.editor.StudyEditor;
import com.jetbrains.edu.learning.statistics.EduUsagesCollector;
import com.jetbrains.edu.learning.stepic.CourseInfo;
import com.jetbrains.edu.learning.stepic.EduStepicConnector;
import com.jetbrains.edu.learning.stepic.StepicUpdateSettings;
import com.jetbrains.edu.learning.stepic.StepicUser;
import org.apache.commons.codec.binary.Base64;
import org.jetbrains.annotations.NotNull;
@@ -57,6 +57,7 @@ public class StudyProjectGenerator {
private static final String COURSE_DESCRIPTION = "description";
private static final String CACHE_NAME = "courseNames.txt";
private final List<SettingsListener> myListeners = ContainerUtil.newArrayList();
@Nullable public StepicUser myUser;
private List<CourseInfo> myCourses = new ArrayList<>();
private List<Integer> myEnrolledCoursesIds = new ArrayList<>();
protected CourseInfo mySelectedCourseInfo;
@@ -66,8 +67,7 @@ public class StudyProjectGenerator {
}
public boolean isLoggedIn() {
final StepicUser user = StepicUpdateSettings.getInstance().getUser();
return user.getAccessToken() != null;
return myUser != null && !StringUtil.isEmptyOrSpaces(myUser.getPassword()) && !StringUtil.isEmptyOrSpaces(myUser.getEmail());
}
public void setEnrolledCoursesIds(@NotNull final List<Integer> coursesIds) {
@@ -88,13 +88,16 @@ public class StudyProjectGenerator {
}
public void generateProject(@NotNull final Project project, @NotNull final VirtualFile baseDir) {
if (myUser != null) {
StudyTaskManager.getInstance(project).setUser(myUser);
}
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(course);
final File courseDirectory = StudyUtils.getCourseDirectory(project, course);
StudyTaskManager.getInstance(project).setCourse(course);
ApplicationManager.getApplication().runWriteAction(() -> {
StudyGenerator.createCourse(course, baseDir, courseDirectory, project);
@@ -117,15 +120,12 @@ public class StudyProjectGenerator {
}
return getCourseFromStepic(project);
}
else {
final StepicUser user = StepicUpdateSettings.getInstance().getUser();
if (user.getAccessToken() != null) {
final File adaptiveCourseFile = new File(new File(OUR_COURSES_DIR, ADAPTIVE_COURSE_PREFIX +
mySelectedCourseInfo.getName() + "_" +
user.getEmail()), EduNames.COURSE_META_FILE);
if (adaptiveCourseFile.exists()) {
return readCourseFromCache(adaptiveCourseFile, true);
}
else if (myUser != null) {
final File adaptiveCourseFile = new File(new File(OUR_COURSES_DIR, ADAPTIVE_COURSE_PREFIX +
mySelectedCourseInfo.getName() + "_" +
myUser.getEmail()), EduNames.COURSE_META_FILE);
if (adaptiveCourseFile.exists()) {
return readCourseFromCache(adaptiveCourseFile, true);
}
}
return getCourseFromStepic(project);
@@ -137,7 +137,7 @@ public class StudyProjectGenerator {
return execCancelable(() -> {
final Course course = EduStepicConnector.getCourse(project, mySelectedCourseInfo);
if (course != null) {
flushCourse(course);
flushCourse(project, course);
course.initCourse(false);
}
return course;
@@ -216,8 +216,8 @@ public class StudyProjectGenerator {
}
}
public static void flushCourse(@NotNull final Course course) {
final File courseDirectory = StudyUtils.getCourseDirectory(course);
public static void flushCourse(@NotNull final Project project, @NotNull final Course course) {
final File courseDirectory = StudyUtils.getCourseDirectory(project, course);
FileUtil.createDirectory(courseDirectory);
flushCourseJson(course, courseDirectory);
@@ -423,7 +423,7 @@ public class StudyProjectGenerator {
myCourses = getCoursesFromCache();
}
if (force || myCourses.isEmpty()) {
myCourses = execCancelable(() -> EduStepicConnector.getCourses(StepicUpdateSettings.getInstance().getUser()));
myCourses = execCancelable(() -> EduStepicConnector.getCourses(myUser));
flushCache(myCourses);
}
if (myCourses.isEmpty() || (myCourses.size() == 1 && myCourses.contains(CourseInfo.INVALID_COURSE))) {
@@ -43,11 +43,11 @@ public class CCStepicConnector {
private CCStepicConnector() {
}
public static CourseInfo getCourseInfo(String courseId) {
public static CourseInfo getCourseInfo(Project project, String courseId) {
final String url = EduStepicNames.COURSES + "/" + courseId;
try {
final StepicWrappers.CoursesContainer coursesContainer =
EduStepicAuthorizedClient.getFromStepic(url, StepicWrappers.CoursesContainer.class);
EduStepicAuthorizedClient.getFromStepic(url, StepicWrappers.CoursesContainer.class, project);
return coursesContainer.courses.get(0);
}
catch (IOException e) {
@@ -69,7 +69,7 @@ public class CCStepicConnector {
indicator.setText("Uploading course to " + EduStepicNames.STEPIC_URL);
final HttpPost request = new HttpPost(EduStepicNames.STEPIC_API_URL + "/courses");
final StepicUser currentUser = EduStepicAuthorizedClient.getCurrentUser(EduStepicAuthorizedClient.getHttpClient());
final StepicUser currentUser = EduStepicAuthorizedClient.getCurrentUser(EduStepicAuthorizedClient.getHttpClient(project));
if (currentUser != null) {
final List<StepicUser> courseAuthors = course.getAuthors();
for (int i = 0; i < courseAuthors.size(); i++) {
@@ -86,7 +86,7 @@ public class CCStepicConnector {
request.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
try {
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient();
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient(project);
final CloseableHttpResponse response = client.execute(request);
final HttpEntity responseEntity = response.getEntity();
final String responseString = responseEntity != null ? EntityUtils.toString(responseEntity) : "";
@@ -98,12 +98,12 @@ public class CCStepicConnector {
}
final CourseInfo postedCourse = new Gson().fromJson(responseString, StepicWrappers.CoursesContainer.class).courses.get(0);
course.setId(postedCourse.id);
final int sectionId = postModule(postedCourse.id, 1, String.valueOf(postedCourse.getName()));
final int sectionId = postModule(project, postedCourse.id, 1, String.valueOf(postedCourse.getName()));
int position = 1;
for (Lesson lesson : course.getLessons()) {
indicator.checkCanceled();
final int lessonId = postLesson(project, lesson, indicator);
postUnit(lessonId, position, sectionId);
postUnit(project, lessonId, position, sectionId);
position += 1;
}
ApplicationManager.getApplication().runReadAction(() -> postAdditionalFiles(project, postedCourse.id, indicator));
@@ -125,7 +125,7 @@ public class CCStepicConnector {
});
if (!files.isEmpty()) {
final int sectionId = postModule(id, 2, EduNames.PYCHARM_ADDITIONAL);
final int sectionId = postModule(project, id, 2, EduNames.PYCHARM_ADDITIONAL);
final Lesson lesson = new Lesson();
lesson.setName(EduNames.PYCHARM_ADDITIONAL);
final Task task = new Task();
@@ -151,11 +151,11 @@ public class CCStepicConnector {
lesson.addTask(task);
lesson.setIndex(1);
final int lessonId = postLesson(project, lesson, indicator);
postUnit(lessonId, 1, sectionId);
postUnit(project, lessonId, 1, sectionId);
}
}
public static void postUnit(int lessonId, int position, int sectionId) {
public static void postUnit(@NotNull final Project project, int lessonId, int position, int sectionId) {
final HttpPost request = new HttpPost(EduStepicNames.STEPIC_API_URL + EduStepicNames.UNITS);
final StepicWrappers.UnitWrapper unitWrapper = new StepicWrappers.UnitWrapper();
unitWrapper.unit = new StepicWrappers.Unit();
@@ -167,7 +167,7 @@ public class CCStepicConnector {
request.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
try {
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient();
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient(project);
final CloseableHttpResponse response = client.execute(request);
final HttpEntity responseEntity = response.getEntity();
final String responseString = responseEntity != null ? EntityUtils.toString(responseEntity) : "";
@@ -182,7 +182,7 @@ public class CCStepicConnector {
}
}
private static int postModule(int courseId, int position, @NotNull final String title) {
private static int postModule(@NotNull final Project project, int courseId, int position, @NotNull final String title) {
final HttpPost request = new HttpPost(EduStepicNames.STEPIC_API_URL + "/sections");
final StepicWrappers.Section section = new StepicWrappers.Section();
section.course = courseId;
@@ -194,7 +194,7 @@ public class CCStepicConnector {
request.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
try {
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient();
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient(project);
final CloseableHttpResponse response = client.execute(request);
final HttpEntity responseEntity = response.getEntity();
final String responseString = responseEntity != null ? EntityUtils.toString(responseEntity) : "";
@@ -226,7 +226,7 @@ public class CCStepicConnector {
request.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
try {
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient();
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient(project);
final CloseableHttpResponse response = client.execute(request);
final HttpEntity responseEntity = response.getEntity();
final String responseString = responseEntity != null ? EntityUtils.toString(responseEntity) : "";
@@ -250,7 +250,7 @@ public class CCStepicConnector {
request.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
try {
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient();
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient(project);
final CloseableHttpResponse response = client.execute(request);
final HttpEntity responseEntity = response.getEntity();
final String responseString = responseEntity != null ? EntityUtils.toString(responseEntity) : "";
@@ -262,7 +262,7 @@ public class CCStepicConnector {
}
final Lesson postedLesson = new Gson().fromJson(responseString, Course.class).getLessons().get(0);
for (Integer step : postedLesson.steps) {
deleteTask(step);
deleteTask(step, project);
}
for (Task task : lesson.getTaskList()) {
@@ -284,7 +284,7 @@ public class CCStepicConnector {
request.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
try {
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient();
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient(project);
final CloseableHttpResponse response = client.execute(request);
final HttpEntity responseEntity = response.getEntity();
final String responseString = responseEntity != null ? EntityUtils.toString(responseEntity) : "";
@@ -308,11 +308,11 @@ public class CCStepicConnector {
return -1;
}
public static void deleteTask(@NotNull final Integer task) {
public static void deleteTask(@NotNull final Integer task, Project project) {
final HttpDelete request = new HttpDelete(EduStepicNames.STEPIC_API_URL + EduStepicNames.STEP_SOURCES + task);
ApplicationManager.getApplication().invokeLater(() -> {
try {
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient();
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient(project);
final CloseableHttpResponse response = client.execute(request);
final HttpEntity responseEntity = response.getEntity();
final String responseString = responseEntity != null ? EntityUtils.toString(responseEntity) : "";
@@ -337,7 +337,7 @@ public class CCStepicConnector {
request.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
try {
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient();
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient(project);
final CloseableHttpResponse response = client.execute(request);
final StatusLine line = response.getStatusLine();
final HttpEntity responseEntity = response.getEntity();
@@ -67,7 +67,7 @@ public class EduAdaptiveStepicConnector {
@Nullable
public static Task getNextRecommendation(@NotNull Project project, @NotNull Course course) {
try {
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient();
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient(project);
final URI uri = new URIBuilder(EduStepicNames.STEPIC_API_URL + EduStepicNames.RECOMMENDATIONS_URL)
.addParameter(EduNames.COURSE, String.valueOf(course.getId()))
.build();
@@ -88,7 +88,8 @@ public class EduAdaptiveStepicConnector {
final StepicWrappers.Recommendation recommendation = recomWrapper.recommendations[0];
final String lessonId = recommendation.lesson;
final StepicWrappers.LessonContainer lessonContainer = EduStepicAuthorizedClient.getFromStepic(EduStepicNames.LESSONS + lessonId,
StepicWrappers.LessonContainer.class);
StepicWrappers.LessonContainer.class,
project);
if (lessonContainer.lessons.size() == 1) {
final Lesson realLesson = lessonContainer.lessons.get(0);
course.getLessons().get(0).setId(Integer.parseInt(lessonId));
@@ -98,8 +99,8 @@ public class EduAdaptiveStepicConnector {
if (taskFromStep != null) return taskFromStep;
}
final StepicUser user = StepicUpdateSettings.getInstance().getUser();
postRecommendationReaction(lessonId,
final StepicUser user = StudyTaskManager.getInstance(project).getUser();
postRecommendationReaction(project, lessonId,
String.valueOf(user.getId()), -1);
return getNextRecommendation(project, course);
}
@@ -136,29 +137,30 @@ public class EduAdaptiveStepicConnector {
@Nullable
private static Task getTask(@NotNull Project project, @NotNull String name, int stepId) throws IOException {
final StepicWrappers.StepSource step = getStep(stepId);
final StepicWrappers.StepSource step = getStep(project, stepId);
final String stepType = step.block.name;
if (stepType.equals(CODE_TASK_TYPE)) {
return getCodeTaskFromStep(project, step.block, name, stepId);
}
else if (stepType.equals(CHOICE_TYPE_TEXT)) {
return getChoiceTaskFromStep(name, step.block, stepId);
return getChoiceTaskFromStep(project, name, step.block, stepId);
}
else if (stepType.startsWith(EduStepicConnector.PYCHARM_PREFIX)) {
return EduStepicConnector.createTask(stepId);
return EduStepicConnector.createTask(project, stepId);
}
return null;
}
private static Task getChoiceTaskFromStep(@NotNull String lessonName,
private static Task getChoiceTaskFromStep(@NotNull Project project,
@NotNull String lessonName,
@NotNull StepicWrappers.Step block,
int stepId) {
final Task task = new Task(lessonName);
task.setStepId(stepId);
task.setText(block.text);
final StepicWrappers.AdaptiveAttemptWrapper.Attempt attempt = getAttemptForStep(stepId);
final StepicWrappers.AdaptiveAttemptWrapper.Attempt attempt = getAttemptForStep(project, stepId);
if (attempt != null) {
final StepicWrappers.AdaptiveAttemptWrapper.Dataset dataset = attempt.dataset;
if (dataset != null) {
@@ -182,16 +184,16 @@ public class EduAdaptiveStepicConnector {
}
@Nullable
private static StepicWrappers.AdaptiveAttemptWrapper.Attempt getAttemptForStep(int id) {
final StepicUser user = StepicUpdateSettings.getInstance().getUser();
private static StepicWrappers.AdaptiveAttemptWrapper.Attempt getAttemptForStep(@NotNull Project project, int id) {
final StepicUser user = StudyTaskManager.getInstance(project).getUser();
try {
final List<StepicWrappers.AdaptiveAttemptWrapper.Attempt> attempts = getAttempts(user, id);
if (attempts != null && attempts.size() > 0) {
final StepicWrappers.AdaptiveAttemptWrapper.Attempt attempt = attempts.get(0);
return attempt.isActive() ? attempt : createNewAttempt(id);
return attempt.isActive() ? attempt : createNewAttempt(project, id);
}
else {
return createNewAttempt(id);
return createNewAttempt(project, id);
}
}
catch (URISyntaxException | IOException e) {
@@ -200,8 +202,8 @@ public class EduAdaptiveStepicConnector {
return null;
}
private static StepicWrappers.AdaptiveAttemptWrapper.Attempt createNewAttempt(int id) throws IOException {
final String response = EduStepicConnector.postAttempt(id);
private static StepicWrappers.AdaptiveAttemptWrapper.Attempt createNewAttempt(@NotNull Project project, int id) throws IOException {
final String response = EduStepicConnector.postAttempt(project, id);
final StepicWrappers.AdaptiveAttemptContainer attempt = new Gson().fromJson(response, StepicWrappers.AdaptiveAttemptContainer.class);
return attempt.attempts.get(0);
}
@@ -235,14 +237,15 @@ public class EduAdaptiveStepicConnector {
request.setConfig(requestConfig);
}
public static boolean postRecommendationReaction(@NotNull String lessonId,
public static boolean postRecommendationReaction(@NotNull Project project,
@NotNull String lessonId,
@NotNull String user,
int reaction) {
final HttpPost post = new HttpPost(EduStepicNames.STEPIC_API_URL + EduStepicNames.RECOMMENDATION_REACTIONS_URL);
final String json = new Gson()
.toJson(new StepicWrappers.RecommendationReactionWrapper(new StepicWrappers.RecommendationReaction(reaction, user, lessonId)));
post.setEntity(new StringEntity(json, ContentType.APPLICATION_JSON));
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient();
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient(project);
setTimeout(post);
try {
final CloseableHttpResponse execute = client.execute(post);
@@ -271,10 +274,10 @@ public class EduAdaptiveStepicConnector {
final Course course = StudyTaskManager.getInstance(project).getCourse();
if (course != null && editor != null && editor.getTaskFile() != null) {
indicator.checkCanceled();
final StepicUser user = StepicUpdateSettings.getInstance().getUser();
final StepicUser user = StudyTaskManager.getInstance(project).getUser();
final boolean recommendationReaction =
postRecommendationReaction(String.valueOf(editor.getTaskFile().getTask().getLesson().getId()),
postRecommendationReaction(project, String.valueOf(editor.getTaskFile().getTask().getLesson().getId()),
String.valueOf(user.getId()), reaction);
if (recommendationReaction) {
indicator.checkCanceled();
@@ -470,7 +473,7 @@ public class EduAdaptiveStepicConnector {
public static Pair<Boolean, String> checkChoiceTask(@NotNull Project project, @NotNull Task task) {
if (task.getSelectedVariants().isEmpty()) return Pair.create(false, "No variants selected");
final StepicWrappers.AdaptiveAttemptWrapper.Attempt attempt = getAttemptForStep(task.getStepId());
final StepicWrappers.AdaptiveAttemptWrapper.Attempt attempt = getAttemptForStep(project, task.getStepId());
if (attempt != null) {
final int attemptId = attempt.id;
@@ -480,10 +483,10 @@ public class EduAdaptiveStepicConnector {
if (!isActiveAttempt) return Pair.create(false, "Your solution is out of date. Please try again");
final StepicWrappers.SubmissionToPostWrapper wrapper = new StepicWrappers.SubmissionToPostWrapper(String.valueOf(attemptId),
createChoiceTaskAnswerArray(task));
final Pair<Boolean, String> pair = doAdaptiveCheck(wrapper, attemptId);
final Pair<Boolean, String> pair = doAdaptiveCheck(project, wrapper, attemptId);
if (!pair.getFirst()) {
try {
createNewAttempt(task.getStepId());
createNewAttempt(project, task.getStepId());
final Task updatedTask = getTask(project, task.getName(), task.getStepId());
if (updatedTask != null) {
final List<String> variants = updatedTask.getChoiceVariants();
@@ -514,7 +517,7 @@ public class EduAdaptiveStepicConnector {
public static Pair<Boolean, String> checkCodeTask(@NotNull Project project, @NotNull Task task) {
int attemptId = -1;
try {
attemptId = getAttemptId(task);
attemptId = getAttemptId(project, task);
}
catch (IOException e) {
LOG.warn(e.getMessage());
@@ -526,7 +529,7 @@ public class EduAdaptiveStepicConnector {
final String answer = PYCHARM_COMMENT + editor.getDocument().getText();
final StepicWrappers.SubmissionToPostWrapper submissionToPost =
new StepicWrappers.SubmissionToPostWrapper(String.valueOf(attemptId), language, answer);
return doAdaptiveCheck(submissionToPost, attemptId);
return doAdaptiveCheck(project, submissionToPost, attemptId);
}
}
else {
@@ -535,10 +538,11 @@ public class EduAdaptiveStepicConnector {
return Pair.create(false, "");
}
private static Pair<Boolean, String> doAdaptiveCheck(@NotNull StepicWrappers.SubmissionToPostWrapper submission,
private static Pair<Boolean, String> doAdaptiveCheck(@NotNull Project project,
@NotNull StepicWrappers.SubmissionToPostWrapper submission,
int attemptId) {
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient();
final StepicUser user = StepicUpdateSettings.getInstance().getUser();
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient(project);
final StepicUser user = StudyTaskManager.getInstance(project).getUser();
StepicWrappers.ResultSubmissionWrapper wrapper = postResultsForCheck(client, submission);
if (wrapper != null) {
wrapper = getCheckResults(client, wrapper, attemptId, user.getId());
@@ -636,13 +640,13 @@ public class EduAdaptiveStepicConnector {
return null;
}
private static int getAttemptId(@NotNull Task task) throws IOException {
private static int getAttemptId(@NotNull final Project project, @NotNull Task task) throws IOException {
final StepicWrappers.AdaptiveAttemptWrapper attemptWrapper = new StepicWrappers.AdaptiveAttemptWrapper(task.getStepId());
final HttpPost post = new HttpPost(EduStepicNames.STEPIC_API_URL + EduStepicNames.ATTEMPTS);
post.setEntity(new StringEntity(new Gson().toJson(attemptWrapper)));
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient();
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient(project);
setTimeout(post);
final CloseableHttpResponse httpResponse = client.execute(post);
final int statusCode = httpResponse.getStatusLine().getStatusCode();
@@ -5,9 +5,12 @@ import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.net.HttpConfigurable;
import com.intellij.util.net.ssl.CertificateManager;
import com.jetbrains.edu.learning.StudyTaskManager;
import com.jetbrains.edu.learning.StudyUtils;
import org.apache.http.*;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
@@ -45,24 +48,24 @@ public class EduStepicAuthorizedClient {
}
@NotNull
public static CloseableHttpClient getHttpClient() {
public static CloseableHttpClient getHttpClient(@NotNull final Project project) {
if (ourClient != null) {
return ourClient;
}
final StepicUser stepicUser = StepicUpdateSettings.getInstance().getUser();
final StepicUser stepicUser = StudyTaskManager.getInstance(project).getUser();
ourClient = initializeClient(stepicUser);
if (ourClient == null) {
final StepicUser user = login(stepicUser);
if (user != null) {
StepicUpdateSettings.getInstance().setUser(user);
StudyTaskManager.getInstance(project).setUser(user);
ourClient = initializeClient(stepicUser);
}
}
return ourClient;
}
public static <T> T getFromStepic(String link, final Class<T> container) throws IOException {
return EduStepicClient.getFromStepic(link, container, getHttpClient());
public static <T> T getFromStepic(String link, final Class<T> container, @NotNull final Project project) throws IOException {
return EduStepicClient.getFromStepic(link, container, getHttpClient(project));
}
/*
@@ -101,7 +104,10 @@ public class EduStepicAuthorizedClient {
else {
final StepicUser authorizedUser = login(stepicUser);
if (authorizedUser != null) {
StepicUpdateSettings.getInstance().setUser(authorizedUser);
final Project project = StudyUtils.getStudyProject();
if (project != null) {
StudyTaskManager.getInstance(project).setUser(authorizedUser);
}
return initializeClient(authorizedUser);
}
}
@@ -9,6 +9,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
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.courseFormat.Task;
@@ -203,7 +204,7 @@ public class EduStepicConnector {
course.setLanguage(language);
try {
for (Integer section : info.sections) {
course.addLessons(getLessons(section));
course.addLessons(getLessons(project, section));
}
return course;
}
@@ -229,23 +230,23 @@ public class EduStepicConnector {
return null;
}
public static List<Lesson> getLessons(int sectionId) throws IOException {
public static List<Lesson> getLessons(@NotNull Project project, int sectionId) throws IOException {
final StepicWrappers.SectionContainer
sectionContainer = getFromStepic(EduStepicNames.SECTIONS + String.valueOf(sectionId),
StepicWrappers.SectionContainer.class);
StepicWrappers.SectionContainer.class, project);
List<Integer> unitIds = sectionContainer.sections.get(0).units;
final List<Lesson> lessons = new ArrayList<>();
for (Integer unitId : unitIds) {
StepicWrappers.UnitContainer
unit = 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 = getFromStepic(EduStepicNames.LESSONS + String.valueOf(lessonID),
StepicWrappers.LessonContainer.class);
StepicWrappers.LessonContainer.class, project);
Lesson lesson = lessonContainer.lessons.get(0);
lesson.taskList = new ArrayList<>();
for (int stepId : lesson.steps) {
final Task task = createTask(stepId);
final Task task = createTask(project, stepId);
if (task != null) {
lesson.addTask(task);
}
@@ -258,18 +259,20 @@ public class EduStepicConnector {
return lessons;
}
private static <T> T getFromStepic(String link, final Class<T> container) throws IOException{
final StepicUser user = StepicUpdateSettings.getInstance().getUser();
final boolean isAuthorized = user.getAccessToken() != null;
if (isAuthorized) {
return EduStepicAuthorizedClient.getFromStepic(link, container, user);
private static <T> T getFromStepic(String link, final Class<T> 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(int stepicId) throws IOException {
final StepicWrappers.StepSource step = getStep(stepicId);
public static Task createTask(@NotNull Project project, int stepicId) throws IOException {
final StepicWrappers.StepSource step = getStep(project, stepicId);
final StepicWrappers.Step block = step.block;
if (!block.name.startsWith(PYCHARM_PREFIX)) {
LOG.error("Got a block with non-pycharm prefix: " + block.name + " for step: " + stepicId);
@@ -300,9 +303,9 @@ public class EduStepicConnector {
return task;
}
public static StepicWrappers.StepSource getStep(int step) throws IOException {
public static StepicWrappers.StepSource getStep(@NotNull Project project, int step) throws IOException {
return getFromStepic(EduStepicNames.STEPS + String.valueOf(step),
StepicWrappers.StepContainer.class).steps.get(0);
StepicWrappers.StepContainer.class, project).steps.get(0);
}
public static void postSolution(@NotNull final Task task, boolean passed, @NotNull final Project project) {
@@ -311,7 +314,7 @@ public class EduStepicConnector {
}
try {
final String response = postAttempt(task.getStepId());
final String response = postAttempt(project, task.getStepId());
if (response.isEmpty()) return;
final StepicWrappers.AttemptWrapper.Attempt attempt =
new Gson().fromJson(response, StepicWrappers.AttemptContainer.class).attempts.get(0);
@@ -335,16 +338,16 @@ public class EduStepicConnector {
}
}
postSubmission(passed, attempt, files);
postSubmission(passed, attempt, project, files);
}
catch (IOException e) {
LOG.error(e.getMessage());
}
}
public static String postAttempt(int id) throws IOException {
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient();
if (StepicUpdateSettings.getInstance().getUser().getAccessToken() == null) return "";
public static String postAttempt(@NotNull Project project, int id) throws IOException {
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient(project);
if (StudyTaskManager.getInstance(project).getUser().getAccessToken() == null) return "";
final HttpPost attemptRequest = new HttpPost(EduStepicNames.STEPIC_API_URL + EduStepicNames.ATTEMPTS);
String attemptRequestBody = new Gson().toJson(new StepicWrappers.AttemptWrapper(id));
attemptRequest.setEntity(new StringEntity(attemptRequestBody, ContentType.APPLICATION_JSON));
@@ -361,12 +364,12 @@ public class EduStepicConnector {
}
private static void postSubmission(boolean passed, StepicWrappers.AttemptWrapper.Attempt attempt,
ArrayList<StepicWrappers.SolutionFile> files) throws IOException {
Project project, ArrayList<StepicWrappers.SolutionFile> files) throws IOException {
final HttpPost request = new HttpPost(EduStepicNames.STEPIC_API_URL + EduStepicNames.SUBMISSIONS);
String requestBody = new Gson().toJson(new StepicWrappers.SubmissionWrapper(attempt.id, passed ? "1" : "0", files));
request.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient();
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient(project);
final CloseableHttpResponse response = client.execute(request);
final HttpEntity responseEntity = response.getEntity();
final String responseString = responseEntity != null ? EntityUtils.toString(responseEntity) : "";
@@ -92,7 +92,7 @@ public class StepicStudyOptions implements StudyOptionsProvider {
Project project = StudyUtils.getStudyProject();
if (project != null) {
StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
final StepicUser user = StepicUpdateSettings.getInstance().getUser();
final StepicUser user = taskManager.getUser();
setLogin(user.getEmail());
setPassword(user.getPassword());
myEnableTestingFromSamples.setSelected(taskManager.isEnableTestingFromSamples());
@@ -116,7 +116,7 @@ public class StepicStudyOptions implements StudyOptionsProvider {
taskManager.setEnableTestingFromSamples(isTestingFromSamplesEnabled());
}
final StepicUser user = StepicUpdateSettings.getInstance().getUser();
final StepicUser user = taskManager.getUser();
final boolean isCredentialsModified = !getLogin().equals(user.getEmail()) || !getPassword().equals(user.getPassword());
if (isCredentialsModified) {
final String login = getLogin();
@@ -132,14 +132,14 @@ public class StepicStudyOptions implements StudyOptionsProvider {
myProject);
if (stepicUser[0] != null && stepicUser[0].getAccessToken() != null) {
StepicUpdateSettings.getInstance().setUser(stepicUser[0]);
taskManager.setUser(stepicUser[0]);
}
else {
throw new ConfigurationException("Unable to login");
}
}
else {
removeCredentials();
removeCredentials(taskManager);
}
}
}
@@ -148,8 +148,8 @@ public class StepicStudyOptions implements StudyOptionsProvider {
}
}
private static void removeCredentials() {
StepicUpdateSettings.getInstance().setUser(new StepicUser());
private static void removeCredentials(StudyTaskManager taskManager) {
taskManager.setUser(new StepicUser());
}
@Nullable
@@ -163,7 +163,7 @@ public class StepicStudyOptions implements StudyOptionsProvider {
if (project == null) return false;
final StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
final StepicUser user = StepicUpdateSettings.getInstance().getUser();
final StepicUser user = taskManager.getUser();
return !getLogin().equals(user.getEmail())
|| !getPassword().equals(user.getPassword())
@@ -5,12 +5,10 @@ import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.util.xmlb.XmlSerializerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@State(name = "StepicUpdateSettings", storages = @Storage("other.xml"))
public class StepicUpdateSettings implements PersistentStateComponent<StepicUpdateSettings> {
private StepicUser myUser = new StepicUser();
public long LAST_TIME_CHECKED = 0;
public StepicUpdateSettings() {
@@ -39,13 +37,4 @@ public class StepicUpdateSettings implements PersistentStateComponent<StepicUpda
public static StepicUpdateSettings getInstance() {
return ServiceManager.getService(StepicUpdateSettings.class);
}
@NotNull
public StepicUser getUser() {
return myUser;
}
public void setUser(@NotNull final StepicUser user) {
myUser = user;
}
}
@@ -353,7 +353,7 @@ public class StudyNewProjectPanel extends JPanel implements PanelWithAnchor {
if (stepicUser != null && stepicUser.getAccessToken() != null) {
stepicUser.setEmail(myLoginPanel.getLogin());
stepicUser.setPassword(myLoginPanel.getPassword());
StepicUpdateSettings.getInstance().setUser(stepicUser);
myGenerator.myUser = stepicUser;
myGenerator.setEnrolledCoursesIds(EduAdaptiveStepicConnector.getEnrolledCoursesIds(stepicUser));
final List<CourseInfo> courses = myGenerator.getCourses(true);
if (courses != null && myRefreshCourseList) {
@@ -27,7 +27,6 @@ import com.jetbrains.edu.learning.courseFormat.Course;
import com.jetbrains.edu.learning.courseGeneration.StudyProjectGenerator;
import com.jetbrains.edu.learning.stepic.CourseInfo;
import com.jetbrains.edu.learning.stepic.EduStepicConnector;
import com.jetbrains.edu.learning.stepic.StepicUpdateSettings;
import com.jetbrains.edu.learning.ui.StudyNewProjectPanel;
import com.jetbrains.python.configuration.PyConfigurableInterpreterList;
import com.jetbrains.python.newProject.PyNewProjectSettings;
@@ -189,8 +188,7 @@ public class PyStudyDirectoryProjectGenerator extends PythonProjectGenerator<PyN
if (course.getId() > 0 && !enrolledCoursesIds.contains(course.getId())) {
ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> {
ProgressManager.getInstance().getProgressIndicator().setIndeterminate(true);
return StudyUtils.execCancelable(() -> EduStepicConnector.enrollToCourse(course.getId(),
StepicUpdateSettings.getInstance().getUser()));
return StudyUtils.execCancelable(() -> EduStepicConnector.enrollToCourse(course.getId(), myGenerator.myUser));
}, "Creating Course", true, ProjectManager.getInstance().getDefaultProject());
}