mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
get rid of courseInfo
extracted remoteCourse for stepik specific fields
This commit is contained in:
committed by
Ekaterina Tuzova
parent
b9faa00c19
commit
8eadfc678b
+1
-1
@@ -220,7 +220,7 @@ public class CCCreateCourseArchive extends DumbAwareAction {
|
||||
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
|
||||
private static void generateJson(VirtualFile parentDir, Course course) {
|
||||
final Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().
|
||||
registerTypeAdapter(Task.class, new StudySerializationUtils.Json.TaskSerializer()).create();
|
||||
registerTypeAdapter(Task.class, new StudySerializationUtils.Json.TaskAdapter()).create();
|
||||
final String json = gson.toJson(course);
|
||||
final File courseJson = new File(parentDir.getPath(), EduNames.COURSE_META_FILE);
|
||||
OutputStreamWriter outputStreamWriter = null;
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ public class CCFromCourseArchive extends DumbAwareAction {
|
||||
reader = new InputStreamReader(new FileInputStream(courseMetaFile));
|
||||
Gson gson = new GsonBuilder()
|
||||
.registerTypeAdapter(Course.class, new StudySerializationUtils.Json.CourseTypeAdapter(courseMetaFile))
|
||||
.registerTypeAdapter(Task.class, new StudySerializationUtils.Json.TaskDeserializer())
|
||||
.registerTypeAdapter(Task.class, new StudySerializationUtils.Json.TaskAdapter())
|
||||
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
|
||||
.create();
|
||||
Course course = gson.fromJson(reader, Course.class);
|
||||
|
||||
+2
-2
@@ -20,8 +20,8 @@ import com.jetbrains.edu.learning.StudyTaskManager;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.core.EduNames;
|
||||
import com.jetbrains.edu.learning.courseFormat.Course;
|
||||
import com.jetbrains.edu.learning.courseFormat.CourseInfo;
|
||||
import com.jetbrains.edu.learning.courseFormat.Lesson;
|
||||
import com.jetbrains.edu.learning.courseFormat.RemoteCourse;
|
||||
import com.jetbrains.edu.learning.courseFormat.TaskFile;
|
||||
import com.jetbrains.edu.learning.courseFormat.tasks.Task;
|
||||
import com.jetbrains.edu.learning.courseGeneration.StudyGenerator;
|
||||
@@ -58,7 +58,7 @@ 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 RemoteCourse info = CCStepicConnector.getCourseInfo(courseId);
|
||||
if (info == null) return;
|
||||
|
||||
final Course course = EduStepicConnector.getCourse(project, info);
|
||||
|
||||
+5
-9
@@ -14,8 +14,8 @@ import com.jetbrains.edu.coursecreator.CCUtils;
|
||||
import com.jetbrains.edu.coursecreator.stepik.CCStepicConnector;
|
||||
import com.jetbrains.edu.learning.StudyTaskManager;
|
||||
import com.jetbrains.edu.learning.courseFormat.Course;
|
||||
import com.jetbrains.edu.learning.courseFormat.CourseInfo;
|
||||
import com.jetbrains.edu.learning.courseFormat.Lesson;
|
||||
import com.jetbrains.edu.learning.courseFormat.RemoteCourse;
|
||||
import com.jetbrains.edu.learning.statistics.EduUsagesCollector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -33,11 +33,8 @@ public class CCPushCourse extends DumbAwareAction {
|
||||
presentation.setEnabledAndVisible(project != null && CCUtils.isCourseCreator(project));
|
||||
if (project != null) {
|
||||
final Course course = StudyTaskManager.getInstance(project).getCourse();
|
||||
if (course != null) {
|
||||
final int id = course.getId();
|
||||
if (id > 0) {
|
||||
presentation.setText("Update Course on Stepik");
|
||||
}
|
||||
if (course instanceof RemoteCourse) {
|
||||
presentation.setText("Update Course on Stepik");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,7 +50,7 @@ public class CCPushCourse extends DumbAwareAction {
|
||||
if (course == null) {
|
||||
return;
|
||||
}
|
||||
if (course.getId() > 0) {
|
||||
if (course instanceof RemoteCourse) {
|
||||
ProgressManager.getInstance().run(new Task.Modal(project, "Updating Course", true) {
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
@@ -62,10 +59,9 @@ public class CCPushCourse extends DumbAwareAction {
|
||||
CCStepicConnector.updateLesson(project, lesson);
|
||||
}
|
||||
else {
|
||||
final CourseInfo info = CourseInfo.fromCourse(course);
|
||||
final int lessonId = CCStepicConnector.postLesson(project, lesson);
|
||||
if (lessonId != -1) {
|
||||
final List<Integer> sections = info.getSections();
|
||||
final List<Integer> sections = ((RemoteCourse)course).getSections();
|
||||
final Integer sectionId = sections.get(sections.size() - 1);
|
||||
CCStepicConnector.postUnit(lessonId, lesson.getIndex(), sectionId);
|
||||
}
|
||||
|
||||
+5
-6
@@ -15,8 +15,8 @@ import com.jetbrains.edu.coursecreator.CCUtils;
|
||||
import com.jetbrains.edu.coursecreator.stepik.CCStepicConnector;
|
||||
import com.jetbrains.edu.learning.StudyTaskManager;
|
||||
import com.jetbrains.edu.learning.courseFormat.Course;
|
||||
import com.jetbrains.edu.learning.courseFormat.CourseInfo;
|
||||
import com.jetbrains.edu.learning.courseFormat.Lesson;
|
||||
import com.jetbrains.edu.learning.courseFormat.RemoteCourse;
|
||||
import com.jetbrains.edu.learning.stepic.EduStepicNames;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -36,7 +36,7 @@ public class CCPushLesson extends DumbAwareAction {
|
||||
return;
|
||||
}
|
||||
final Course course = StudyTaskManager.getInstance(project).getCourse();
|
||||
if (course == null) {
|
||||
if (course == null || !(course instanceof RemoteCourse)) {
|
||||
return;
|
||||
}
|
||||
if (!course.getCourseMode().equals(CCUtils.COURSE_MODE)) return;
|
||||
@@ -45,7 +45,7 @@ public class CCPushLesson extends DumbAwareAction {
|
||||
return;
|
||||
}
|
||||
final Lesson lesson = course.getLesson(lessonDir.getName());
|
||||
if (lesson != null && course.getId() > 0) {
|
||||
if (lesson != null && ((RemoteCourse)course).getId() > 0) {
|
||||
e.getPresentation().setEnabledAndVisible(true);
|
||||
if (lesson.getId() <= 0) {
|
||||
e.getPresentation().setText("Upload Lesson to Stepik");
|
||||
@@ -61,7 +61,7 @@ public class CCPushLesson extends DumbAwareAction {
|
||||
return;
|
||||
}
|
||||
final Course course = StudyTaskManager.getInstance(project).getCourse();
|
||||
if (course == null) {
|
||||
if (course == null || !(course instanceof RemoteCourse)) {
|
||||
return;
|
||||
}
|
||||
PsiDirectory lessonDir = DirectoryChooserUtil.getOrChooseDirectory(view);
|
||||
@@ -80,9 +80,8 @@ public class CCPushLesson extends DumbAwareAction {
|
||||
CCStepicConnector.updateLesson(project, lesson);
|
||||
}
|
||||
else {
|
||||
final CourseInfo info = CourseInfo.fromCourse(course);
|
||||
final int lessonId = CCStepicConnector.postLesson(project, lesson);
|
||||
final List<Integer> sections = info.getSections();
|
||||
final List<Integer> sections = ((RemoteCourse)course).getSections();
|
||||
final Integer sectionId = sections.get(sections.size()-1);
|
||||
CCStepicConnector.postUnit(lessonId, lesson.getIndex(), sectionId);
|
||||
}
|
||||
|
||||
@@ -12,11 +12,12 @@ import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.jetbrains.edu.coursecreator.CCUtils;
|
||||
import com.jetbrains.edu.coursecreator.stepik.CCStepicConnector;
|
||||
import com.jetbrains.edu.learning.StudyTaskManager;
|
||||
import com.jetbrains.edu.learning.core.EduNames;
|
||||
import com.jetbrains.edu.learning.courseFormat.Course;
|
||||
import com.jetbrains.edu.learning.courseFormat.Lesson;
|
||||
import com.jetbrains.edu.coursecreator.stepik.CCStepicConnector;
|
||||
import com.jetbrains.edu.learning.courseFormat.RemoteCourse;
|
||||
import com.jetbrains.edu.learning.stepic.EduStepicNames;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -34,7 +35,7 @@ public class CCPushTask extends DumbAwareAction {
|
||||
return;
|
||||
}
|
||||
final Course course = StudyTaskManager.getInstance(project).getCourse();
|
||||
if (course == null) {
|
||||
if (course == null || !(course instanceof RemoteCourse)) {
|
||||
return;
|
||||
}
|
||||
if (!course.getCourseMode().equals(CCUtils.COURSE_MODE)) return;
|
||||
@@ -45,7 +46,7 @@ public class CCPushTask extends DumbAwareAction {
|
||||
final PsiDirectory lessonDir = taskDir.getParentDirectory();
|
||||
if (lessonDir == null) return;
|
||||
final Lesson lesson = course.getLesson(lessonDir.getName());
|
||||
if (lesson != null && lesson.getId() > 0 && course.getId() > 0) {
|
||||
if (lesson != null && lesson.getId() > 0 && ((RemoteCourse)course).getId() > 0) {
|
||||
e.getPresentation().setEnabledAndVisible(true);
|
||||
final com.jetbrains.edu.learning.courseFormat.tasks.Task task = lesson.getTask(taskDir.getName());
|
||||
if (task.getStepId() <= 0) {
|
||||
|
||||
+10
-6
@@ -10,11 +10,12 @@ import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.jetbrains.edu.coursecreator.CCUtils;
|
||||
import com.jetbrains.edu.learning.StudySerializationUtils;
|
||||
import com.jetbrains.edu.learning.StudyTaskManager;
|
||||
import com.jetbrains.edu.learning.core.EduNames;
|
||||
import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
|
||||
import com.jetbrains.edu.learning.courseFormat.Course;
|
||||
import com.jetbrains.edu.learning.courseFormat.CourseInfo;
|
||||
import com.jetbrains.edu.learning.courseFormat.Lesson;
|
||||
import com.jetbrains.edu.learning.courseFormat.RemoteCourse;
|
||||
import com.jetbrains.edu.learning.courseFormat.tasks.Task;
|
||||
import com.jetbrains.edu.learning.stepic.EduStepicAuthorizedClient;
|
||||
import com.jetbrains.edu.learning.stepic.EduStepicNames;
|
||||
@@ -43,7 +44,7 @@ public class CCStepicConnector {
|
||||
private CCStepicConnector() {
|
||||
}
|
||||
|
||||
public static CourseInfo getCourseInfo(String courseId) {
|
||||
public static RemoteCourse getCourseInfo(String courseId) {
|
||||
final String url = EduStepicNames.COURSES + "/" + courseId;
|
||||
try {
|
||||
final StepicWrappers.CoursesContainer coursesContainer =
|
||||
@@ -103,8 +104,10 @@ public class CCStepicConnector {
|
||||
LOG.error("Failed to push " + responseString);
|
||||
return;
|
||||
}
|
||||
final CourseInfo postedCourse = new Gson().fromJson(responseString, StepicWrappers.CoursesContainer.class).courses.get(0);
|
||||
course.setId(postedCourse.getId());
|
||||
final RemoteCourse postedCourse = new Gson().fromJson(responseString, StepicWrappers.CoursesContainer.class).courses.get(0);
|
||||
postedCourse.setLessons(course.getLessons(true));
|
||||
postedCourse.setAuthors(course.getAuthors());
|
||||
postedCourse.setCourseMode(CCUtils.COURSE_MODE);
|
||||
final int sectionId = postModule(postedCourse.getId(), 1, String.valueOf(postedCourse.getName()));
|
||||
int position = 1;
|
||||
for (Lesson lesson : course.getLessons()) {
|
||||
@@ -116,6 +119,7 @@ public class CCStepicConnector {
|
||||
position += 1;
|
||||
}
|
||||
ApplicationManager.getApplication().runReadAction(() -> postAdditionalFiles(course, project, postedCourse.getId()));
|
||||
StudyTaskManager.getInstance(project).setCourse(postedCourse);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e.getMessage());
|
||||
@@ -241,7 +245,7 @@ public class CCStepicConnector {
|
||||
LOG.error("Failed to push " + responseString);
|
||||
return -1;
|
||||
}
|
||||
final Lesson postedLesson = new Gson().fromJson(responseString, Course.class).getLessons().get(0);
|
||||
final Lesson postedLesson = new Gson().fromJson(responseString, RemoteCourse.class).getLessons().get(0);
|
||||
for (Integer step : postedLesson.steps) {
|
||||
deleteTask(step);
|
||||
}
|
||||
@@ -279,7 +283,7 @@ public class CCStepicConnector {
|
||||
LOG.error("Failed to push " + responseString);
|
||||
return 0;
|
||||
}
|
||||
final Lesson postedLesson = new Gson().fromJson(responseString, Course.class).getLessons().get(0);
|
||||
final Lesson postedLesson = new Gson().fromJson(responseString, RemoteCourse.class).getLessons(true).get(0);
|
||||
lesson.setId(postedLesson.getId());
|
||||
for (Task task : lesson.getTaskList()) {
|
||||
final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
|
||||
|
||||
@@ -146,10 +146,8 @@ public class StudyProjectComponent implements ProjectComponent {
|
||||
|
||||
private void updateCourse() {
|
||||
final Course currentCourse = StudyTaskManager.getInstance(myProject).getCourse();
|
||||
final CourseInfo info = CourseInfo.fromCourse(currentCourse);
|
||||
if (info == null) return;
|
||||
|
||||
final Course course = EduStepicConnector.getCourse(myProject, info);
|
||||
if (currentCourse == null || !(currentCourse instanceof RemoteCourse)) return;
|
||||
final Course course = EduStepicConnector.getCourse(myProject, (RemoteCourse)currentCourse);
|
||||
if (course == null) return;
|
||||
course.initCourse(false);
|
||||
|
||||
|
||||
+20
-5
@@ -16,6 +16,7 @@ import com.intellij.util.containers.hash.HashMap;
|
||||
import com.jetbrains.edu.learning.core.EduNames;
|
||||
import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
|
||||
import com.jetbrains.edu.learning.courseFormat.Course;
|
||||
import com.jetbrains.edu.learning.courseFormat.RemoteCourse;
|
||||
import com.jetbrains.edu.learning.courseFormat.StudyStatus;
|
||||
import com.jetbrains.edu.learning.courseFormat.tasks.*;
|
||||
import com.jetbrains.edu.learning.stepic.EduStepicConnector;
|
||||
@@ -62,6 +63,7 @@ public class StudySerializationUtils {
|
||||
public static class Xml {
|
||||
public final static String COURSE_ELEMENT = "courseElement";
|
||||
public final static String MAIN_ELEMENT = "StudyTaskManager";
|
||||
public final static String REMOTE_COURSE = "RemoteCourse";
|
||||
public static final String MAP = "map";
|
||||
public static final String KEY = "key";
|
||||
public static final String VALUE = "value";
|
||||
@@ -498,7 +500,7 @@ public class StudySerializationUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
return new GsonBuilder().registerTypeAdapter(Task.class, new TaskDeserializer()).create().fromJson(json, Course.class);
|
||||
return new GsonBuilder().registerTypeAdapter(Task.class, new TaskAdapter()).create().fromJson(json, Course.class);
|
||||
}
|
||||
|
||||
private static void convertToAbsoluteOffset(Document document, JsonElement placeholder) {
|
||||
@@ -676,7 +678,23 @@ public class StudySerializationUtils {
|
||||
subtaskInfo.addProperty(POSSIBLE_ANSWER, placeholderObject.getAsJsonPrimitive(POSSIBLE_ANSWER).getAsString());
|
||||
}
|
||||
|
||||
public static class TaskSerializer implements JsonSerializer<Task> {
|
||||
public static class StepikCourseSerializer implements JsonSerializer<Course>, JsonDeserializer<Course> {
|
||||
|
||||
@Override
|
||||
public Course deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(Course src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
if (src instanceof RemoteCourse) {
|
||||
context.serialize(src, RemoteCourse.class);
|
||||
}
|
||||
return context.serialize(src);
|
||||
}
|
||||
}
|
||||
|
||||
public static class TaskAdapter implements JsonSerializer<Task>, JsonDeserializer<Task> {
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(Task src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
@@ -686,9 +704,6 @@ public class StudySerializationUtils {
|
||||
task.add(TASK_TYPE, new JsonPrimitive(src.getTaskType()));
|
||||
return task;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TaskDeserializer implements JsonDeserializer<Task> {
|
||||
|
||||
@Override
|
||||
public Task deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
|
||||
@@ -24,6 +24,8 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.jetbrains.edu.learning.StudySerializationUtils.Xml.REMOTE_COURSE;
|
||||
|
||||
/**
|
||||
* Implementation of class which contains all the information
|
||||
* about study in context of current project
|
||||
@@ -115,10 +117,32 @@ public class StudyTaskManager implements PersistentStateComponent<Element>, Dumb
|
||||
if (myCourse == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return serialize();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Element serialize() {
|
||||
Element el = new Element("taskManager");
|
||||
Element courseElement = new Element(StudySerializationUtils.Xml.MAIN_ELEMENT);
|
||||
XmlSerializer.serializeInto(this, courseElement);
|
||||
el.addContent(courseElement);
|
||||
Element taskManagerElement = new Element(StudySerializationUtils.Xml.MAIN_ELEMENT);
|
||||
XmlSerializer.serializeInto(this, taskManagerElement);
|
||||
|
||||
if (myCourse instanceof RemoteCourse) {
|
||||
try {
|
||||
Element course = new Element(REMOTE_COURSE);
|
||||
//noinspection RedundantCast
|
||||
XmlSerializer.serializeInto((RemoteCourse)myCourse, course);
|
||||
|
||||
final Element xmlCourse = StudySerializationUtils.Xml.getChildWithName(taskManagerElement, StudySerializationUtils.COURSE);
|
||||
xmlCourse.removeContent();
|
||||
xmlCourse.addContent(course);
|
||||
}
|
||||
catch (StudySerializationUtils.StudyUnrecognizedFormatException e) {
|
||||
LOG.error("Failed to serialize remote course");
|
||||
}
|
||||
}
|
||||
|
||||
el.addContent(taskManagerElement);
|
||||
return el;
|
||||
}
|
||||
|
||||
@@ -143,7 +167,7 @@ public class StudyTaskManager implements PersistentStateComponent<Element>, Dumb
|
||||
//case 5:
|
||||
// state = StudySerializationUtils.Xml.convertToSixthVersion(state, myProject);
|
||||
}
|
||||
XmlSerializer.deserializeInto(this, state.getChild(StudySerializationUtils.Xml.MAIN_ELEMENT));
|
||||
deserialize(state);
|
||||
VERSION = CURRENT_VERSION;
|
||||
if (myCourse != null) {
|
||||
myCourse.initCourse(true);
|
||||
@@ -154,6 +178,18 @@ public class StudyTaskManager implements PersistentStateComponent<Element>, Dumb
|
||||
}
|
||||
}
|
||||
|
||||
private void deserialize(Element state) throws StudySerializationUtils.StudyUnrecognizedFormatException {
|
||||
final Element taskManagerElement = state.getChild(StudySerializationUtils.Xml.MAIN_ELEMENT);
|
||||
XmlSerializer.deserializeInto(this, taskManagerElement);
|
||||
final Element xmlCourse = StudySerializationUtils.Xml.getChildWithName(taskManagerElement, StudySerializationUtils.COURSE);
|
||||
final Element remoteCourseElement = xmlCourse.getChild(REMOTE_COURSE);
|
||||
if (remoteCourseElement != null) {
|
||||
final RemoteCourse remoteCourse = new RemoteCourse();
|
||||
XmlSerializer.deserializeInto(remoteCourse, remoteCourseElement);
|
||||
myCourse = remoteCourse;
|
||||
}
|
||||
}
|
||||
|
||||
public static StudyTaskManager getInstance(@NotNull final Project project) {
|
||||
return ServiceManager.getService(project, StudyTaskManager.class);
|
||||
}
|
||||
|
||||
@@ -8,32 +8,29 @@ import com.intellij.util.xmlb.XmlSerializer;
|
||||
import com.intellij.util.xmlb.annotations.Transient;
|
||||
import com.jetbrains.edu.learning.core.EduNames;
|
||||
import com.jetbrains.edu.learning.core.EduUtils;
|
||||
import com.jetbrains.edu.learning.courseFormat.tasks.Task;
|
||||
import com.jetbrains.edu.learning.stepic.EduStepicConnector;
|
||||
import com.jetbrains.edu.learning.stepic.StepicUser;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Course {
|
||||
@Expose private List<Lesson> lessons = new ArrayList<>();
|
||||
@Expose private List<StepicUser> authors = new ArrayList<>();
|
||||
@Expose private String description;
|
||||
@Expose private String name;
|
||||
@Expose private int id;
|
||||
@Expose @SerializedName("update_date") private Date myUpdateDate;
|
||||
@Expose private boolean isAdaptive = false;
|
||||
@Expose @SerializedName("language") private String myLanguage = "Python";
|
||||
public static final Course INVALID_COURSE = new Course();
|
||||
|
||||
@Expose protected List<Lesson> lessons = new ArrayList<>();
|
||||
transient private List<StepicUser> authors = new ArrayList<>();
|
||||
@Expose @SerializedName("summary") private String description;
|
||||
@Expose @SerializedName("title") private String name;
|
||||
|
||||
transient private String myLanguage = "Python";
|
||||
|
||||
//this field is used to distinguish ordinary and CheckIO projects,
|
||||
//"PyCharm" is used here for historical reasons
|
||||
private String courseType = EduNames.PYCHARM;
|
||||
private String courseMode = EduNames.STUDY; //this field is used to distinguish study and course creator modes
|
||||
protected String courseMode = EduNames.STUDY; //this field is used to distinguish study and course creator modes
|
||||
|
||||
public Course() {}
|
||||
|
||||
@@ -136,35 +133,10 @@ public class Course {
|
||||
}
|
||||
|
||||
public boolean isUpToDate() {
|
||||
if (id == 0) return true;
|
||||
if (!EduNames.STUDY.equals(courseMode)) return true;
|
||||
final Date date = EduStepicConnector.getCourseUpdateDate(id);
|
||||
if (date == null) return true;
|
||||
if (myUpdateDate == null) return true;
|
||||
if (date.after(myUpdateDate)) return false;
|
||||
for (Lesson lesson : lessons) {
|
||||
if (!lesson.isUpToDate()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setUpdated() {
|
||||
setUpdateDate(EduStepicConnector.getCourseUpdateDate(id));
|
||||
for (Lesson lesson : lessons) {
|
||||
lesson.setUpdateDate(EduStepicConnector.getLessonUpdateDate(lesson.getId()));
|
||||
for (Task task : lesson.getTaskList()) {
|
||||
task.setUpdateDate(EduStepicConnector.getTaskUpdateDate(task.getStepId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setUpdateDate(Date date) {
|
||||
myUpdateDate = date;
|
||||
}
|
||||
|
||||
public Date getUpdateDate() {
|
||||
return myUpdateDate;
|
||||
}
|
||||
public void setUpdated() {}
|
||||
|
||||
public Language getLanguageById() {
|
||||
return Language.findLanguageByID(getLanguageID());
|
||||
@@ -209,22 +181,6 @@ public class Course {
|
||||
this.courseType = courseType;
|
||||
}
|
||||
|
||||
public boolean isAdaptive() {
|
||||
return isAdaptive;
|
||||
}
|
||||
|
||||
public void setAdaptive(boolean adaptive) {
|
||||
isAdaptive = adaptive;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getCourseMode() {
|
||||
return courseMode;
|
||||
}
|
||||
@@ -235,8 +191,17 @@ public class Course {
|
||||
|
||||
public Course copy() {
|
||||
Element element = XmlSerializer.serialize(this);
|
||||
Course copy = XmlSerializer.deserialize(element, Course.class);
|
||||
Course copy = XmlSerializer.deserialize(element, getClass());
|
||||
copy.initCourse(true);
|
||||
return copy;
|
||||
}
|
||||
|
||||
public boolean isAdaptive() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,175 +0,0 @@
|
||||
package com.jetbrains.edu.learning.courseFormat;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.jetbrains.edu.learning.stepic.EduStepicConnector;
|
||||
import com.jetbrains.edu.learning.stepic.StepicUser;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Implementation of class which contains information to be shawn in course description in tool window
|
||||
* and when project is being created
|
||||
*/
|
||||
public class CourseInfo {
|
||||
public static final CourseInfo INVALID_COURSE = new CourseInfo();
|
||||
|
||||
@SerializedName("title") private String myName;
|
||||
int id;
|
||||
boolean isAdaptive;
|
||||
@SerializedName("is_public") boolean isPublic;
|
||||
List<Integer> sections;
|
||||
List<Integer> instructors = new ArrayList<>();
|
||||
|
||||
List<StepicUser> myAuthors = new ArrayList<>();
|
||||
@SerializedName("summary") private String myDescription;
|
||||
@SerializedName("course_format") private String myType = "pycharm" + EduStepicConnector.CURRENT_VERSION + " Python"; //course type in format "pycharm<version> <language>"
|
||||
@Nullable private String username;
|
||||
|
||||
@SerializedName("update_date") private Date updateDate;
|
||||
@SerializedName("is_idea_compatible") private boolean isCompatible = true;
|
||||
|
||||
public String getName() {
|
||||
return myName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<StepicUser> getAuthors() {
|
||||
return myAuthors;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return myDescription;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return myType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
CourseInfo that = (CourseInfo)o;
|
||||
final String thatName = that.getName();
|
||||
final String thatDescription = that.getDescription();
|
||||
if (thatName == null && getName() == null && thatDescription == null &&
|
||||
getDescription() == null) {
|
||||
return true;
|
||||
}
|
||||
if (thatName == null || thatDescription == null) {
|
||||
return false;
|
||||
}
|
||||
return thatName.equals(getName())
|
||||
&& thatDescription.equals(myDescription);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = getName() != null ? getName().hashCode() : 0;
|
||||
result = 31 * result + (myDescription != null ? myDescription.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(@Nullable String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
myName = name;
|
||||
}
|
||||
|
||||
public void setAuthors(List<StepicUser> authors) {
|
||||
myAuthors = authors;
|
||||
for (StepicUser author : authors) {
|
||||
if (author.getId() > 0) {
|
||||
instructors.add(author.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addAuthor(StepicUser author) {
|
||||
if (myAuthors == null) {
|
||||
myAuthors = new ArrayList<>();
|
||||
}
|
||||
myAuthors.add(author);
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
myDescription = description;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
myType = type;
|
||||
}
|
||||
|
||||
public boolean isAdaptive() {
|
||||
return isAdaptive;
|
||||
}
|
||||
|
||||
public void setAdaptive(boolean adaptive) {
|
||||
isAdaptive = adaptive;
|
||||
}
|
||||
|
||||
public boolean isPublic() {
|
||||
return isPublic;
|
||||
}
|
||||
|
||||
public void setPublic(boolean aPublic) {
|
||||
isPublic = aPublic;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Date getUpdateDate() {
|
||||
return updateDate;
|
||||
}
|
||||
|
||||
public void setUpdateDate(Date updateDate) {
|
||||
this.updateDate = updateDate;
|
||||
}
|
||||
|
||||
public static CourseInfo fromCourse(@Nullable final Course course) {
|
||||
if (course == null) return null;
|
||||
CourseInfo courseInfo = new CourseInfo();
|
||||
courseInfo.setName(course.getName());
|
||||
courseInfo.setDescription(course.getDescription());
|
||||
courseInfo.setAuthors(course.getAuthors());
|
||||
return courseInfo;
|
||||
}
|
||||
|
||||
public List<Integer> getSections() {
|
||||
return sections;
|
||||
}
|
||||
|
||||
public boolean isCompatible() {
|
||||
return isCompatible;
|
||||
}
|
||||
|
||||
public void setCompatible(boolean compatible) {
|
||||
isCompatible = compatible;
|
||||
}
|
||||
|
||||
public List<Integer> getInstructors() {
|
||||
return instructors;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package com.jetbrains.edu.learning.courseFormat;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.jetbrains.edu.learning.core.EduNames;
|
||||
import com.jetbrains.edu.learning.courseFormat.tasks.Task;
|
||||
import com.jetbrains.edu.learning.stepic.EduStepicConnector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class RemoteCourse extends Course {
|
||||
//course type in format "pycharm<version> <language>"
|
||||
@SerializedName("course_format") private String myType = "pycharm" + EduStepicConnector.CURRENT_VERSION + " Python";
|
||||
@SerializedName("is_idea_compatible") private boolean isCompatible = true;
|
||||
List<Integer> sections;
|
||||
List<Integer> instructors = new ArrayList<>();
|
||||
@Expose private int id;
|
||||
@Expose @SerializedName("update_date") private Date myUpdateDate;
|
||||
@Expose private boolean isAdaptive = false;
|
||||
@SerializedName("is_public") boolean isPublic;
|
||||
|
||||
public String getType() {
|
||||
return myType;
|
||||
}
|
||||
|
||||
public List<Integer> getSections() {
|
||||
return sections;
|
||||
}
|
||||
|
||||
public void setSections(List<Integer> sections) {
|
||||
this.sections = sections;
|
||||
}
|
||||
|
||||
public void setInstructors(List<Integer> instructors) {
|
||||
this.instructors = instructors;
|
||||
}
|
||||
|
||||
public List<Integer> getInstructors() {
|
||||
return instructors;
|
||||
}
|
||||
|
||||
|
||||
public boolean isUpToDate() {
|
||||
if (id == 0) return true;
|
||||
if (!EduNames.STUDY.equals(courseMode)) return true;
|
||||
final Date date = EduStepicConnector.getCourseUpdateDate(id);
|
||||
if (date == null) return true;
|
||||
if (myUpdateDate == null) return true;
|
||||
if (date.after(myUpdateDate)) return false;
|
||||
for (Lesson lesson : lessons) {
|
||||
if (!lesson.isUpToDate()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setUpdated() {
|
||||
setUpdateDate(EduStepicConnector.getCourseUpdateDate(id));
|
||||
for (Lesson lesson : lessons) {
|
||||
lesson.setUpdateDate(EduStepicConnector.getLessonUpdateDate(lesson.getId()));
|
||||
for (Task task : lesson.getTaskList()) {
|
||||
task.setUpdateDate(EduStepicConnector.getTaskUpdateDate(task.getStepId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setUpdateDate(Date date) {
|
||||
myUpdateDate = date;
|
||||
}
|
||||
|
||||
public Date getUpdateDate() {
|
||||
return myUpdateDate;
|
||||
}
|
||||
|
||||
public boolean isAdaptive() {
|
||||
return isAdaptive;
|
||||
}
|
||||
|
||||
public void setAdaptive(boolean adaptive) {
|
||||
isAdaptive = adaptive;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void copyCourseParameters(RemoteCourse course) {
|
||||
setName(course.getName());
|
||||
|
||||
setUpdateDate(course.getUpdateDate());
|
||||
|
||||
}
|
||||
}
|
||||
+29
-39
@@ -23,7 +23,7 @@ import com.jetbrains.edu.learning.StudyTaskManager;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.core.EduNames;
|
||||
import com.jetbrains.edu.learning.courseFormat.Course;
|
||||
import com.jetbrains.edu.learning.courseFormat.CourseInfo;
|
||||
import com.jetbrains.edu.learning.courseFormat.RemoteCourse;
|
||||
import com.jetbrains.edu.learning.courseFormat.tasks.Task;
|
||||
import com.jetbrains.edu.learning.statistics.EduUsagesCollector;
|
||||
import com.jetbrains.edu.learning.stepic.EduStepicConnector;
|
||||
@@ -41,12 +41,11 @@ import static com.jetbrains.edu.learning.StudyUtils.execCancelable;
|
||||
public class StudyProjectGenerator {
|
||||
private static final Logger LOG = Logger.getInstance(StudyProjectGenerator.class.getName());
|
||||
private final List<SettingsListener> myListeners = ContainerUtil.newArrayList();
|
||||
private List<CourseInfo> myCourses = new ArrayList<>();
|
||||
private List<Course> myLocalCourses = new ArrayList<>();
|
||||
private List<Course> myCourses = new ArrayList<>();
|
||||
private List<Integer> myEnrolledCoursesIds = new ArrayList<>();
|
||||
protected CourseInfo mySelectedCourseInfo;
|
||||
protected Course mySelectedCourse;
|
||||
|
||||
public void setCourses(List<CourseInfo> courses) {
|
||||
public void setCourses(List<Course> courses) {
|
||||
myCourses = courses;
|
||||
}
|
||||
|
||||
@@ -64,12 +63,12 @@ public class StudyProjectGenerator {
|
||||
return myEnrolledCoursesIds;
|
||||
}
|
||||
|
||||
public void setSelectedCourse(@NotNull final CourseInfo courseName) {
|
||||
mySelectedCourseInfo = courseName;
|
||||
public void setSelectedCourse(@NotNull final Course course) {
|
||||
mySelectedCourse = course;
|
||||
}
|
||||
|
||||
public CourseInfo getSelectedCourseInfo() {
|
||||
return mySelectedCourseInfo;
|
||||
public Course getSelectedCourse() {
|
||||
return mySelectedCourse;
|
||||
}
|
||||
|
||||
public void generateProject(@NotNull final Project project, @NotNull final VirtualFile baseDir) {
|
||||
@@ -94,22 +93,18 @@ public class StudyProjectGenerator {
|
||||
|
||||
@Nullable
|
||||
public Course getCourse(@NotNull final Project project) {
|
||||
final CourseInfo info = mySelectedCourseInfo;
|
||||
for (Course course : myLocalCourses) {
|
||||
if (course.getName().equals(info.getName())){
|
||||
course.initCourse(false);
|
||||
return course;
|
||||
}
|
||||
|
||||
if (mySelectedCourse instanceof RemoteCourse) {
|
||||
return getCourseFromStepic(project, (RemoteCourse)mySelectedCourse);
|
||||
}
|
||||
return getCourseFromStepic(project);
|
||||
mySelectedCourse.initCourse(false);
|
||||
return mySelectedCourse;
|
||||
}
|
||||
|
||||
private Course getCourseFromStepic(@NotNull Project project) {
|
||||
private static RemoteCourse getCourseFromStepic(@NotNull Project project, RemoteCourse selectedCourse) {
|
||||
return ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> {
|
||||
ProgressManager.getInstance().getProgressIndicator().setIndeterminate(true);
|
||||
return execCancelable(() -> {
|
||||
final Course course = EduStepicConnector.getCourse(project, mySelectedCourseInfo);
|
||||
final RemoteCourse course = EduStepicConnector.getCourse(project, selectedCourse);
|
||||
if (StudyUtils.isCourseValid(course)) {
|
||||
course.initCourse(false);
|
||||
}
|
||||
@@ -119,25 +114,25 @@ public class StudyProjectGenerator {
|
||||
}
|
||||
|
||||
// Supposed to be called under progress
|
||||
public List<CourseInfo> getCourses(boolean force) {
|
||||
public List<Course> getCourses(boolean force) {
|
||||
if (force) {
|
||||
myCourses = execCancelable(() -> EduStepicConnector.getCourses(StepicUpdateSettings.getInstance().getUser()));
|
||||
}
|
||||
if (myCourses == null || myCourses.isEmpty() || (myCourses.size() == 1 && myCourses.contains(CourseInfo.INVALID_COURSE))) {
|
||||
if (myCourses == null || myCourses.isEmpty() || (myCourses.size() == 1 && myCourses.contains(Course.INVALID_COURSE))) {
|
||||
myCourses = Collections.singletonList(getBundledIntro());
|
||||
}
|
||||
sortCourses(myCourses);
|
||||
return myCourses;
|
||||
}
|
||||
|
||||
public void sortCourses(List<CourseInfo> result) {
|
||||
public void sortCourses(List<Course> result) {
|
||||
// sort courses so as to have non-adaptive courses in the beginning of the list
|
||||
Collections.sort(result, (c1, c2) -> {
|
||||
if (mySelectedCourseInfo != null) {
|
||||
if (mySelectedCourseInfo.equals(c1)) {
|
||||
if (mySelectedCourse != null) {
|
||||
if (mySelectedCourse.equals(c1)) {
|
||||
return -1;
|
||||
}
|
||||
if (mySelectedCourseInfo.equals(c2)) {
|
||||
if (mySelectedCourse.equals(c2)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -149,7 +144,7 @@ public class StudyProjectGenerator {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<CourseInfo> getCoursesUnderProgress(boolean force, @NotNull final String progressTitle, @NotNull final Project project) {
|
||||
public List<Course> getCoursesUnderProgress(boolean force, @NotNull final String progressTitle, @NotNull final Project project) {
|
||||
try {
|
||||
return ProgressManager.getInstance()
|
||||
.runProcessWithProgressSynchronously(() -> {
|
||||
@@ -158,7 +153,7 @@ public class StudyProjectGenerator {
|
||||
}, progressTitle, true, project);
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
return Collections.singletonList(CourseInfo.INVALID_COURSE);
|
||||
return Collections.singletonList(Course.INVALID_COURSE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,21 +172,21 @@ public class StudyProjectGenerator {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CourseInfo getBundledIntro() {
|
||||
public Course getBundledIntro() {
|
||||
final LanguageExtensionPoint<EduPluginConfigurator>[] extensions = Extensions.getExtensions(EduPluginConfigurator.EP_NAME, null);
|
||||
for (LanguageExtensionPoint<EduPluginConfigurator> extension : extensions) {
|
||||
final EduPluginConfigurator configurator = extension.getInstance();
|
||||
final String path = configurator.getBundledCoursePath();
|
||||
if (path != null) {
|
||||
return getCourseInfo(path);
|
||||
return getCourse(path);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CourseInfo addLocalCourse(String zipFilePath) {
|
||||
final CourseInfo courseInfo = getCourseInfo(zipFilePath);
|
||||
public Course addLocalCourse(String zipFilePath) {
|
||||
final Course courseInfo = getCourse(zipFilePath);
|
||||
if (courseInfo != null) {
|
||||
myCourses.add(0, courseInfo);
|
||||
}
|
||||
@@ -199,22 +194,17 @@ public class StudyProjectGenerator {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CourseInfo getCourseInfo(String zipFilePath) {
|
||||
public Course getCourse(String zipFilePath) {
|
||||
try {
|
||||
final JBZipFile zipFile = new JBZipFile(zipFilePath);
|
||||
final JBZipEntry entry = zipFile.getEntry(EduNames.COURSE_META_FILE);
|
||||
byte[] bytes = entry.getData();
|
||||
final String jsonText = new String(bytes, CharsetToolkit.UTF8_CHARSET);
|
||||
Gson gson = new GsonBuilder()
|
||||
.registerTypeAdapter(Task.class, new StudySerializationUtils.Json.TaskDeserializer())
|
||||
.registerTypeAdapter(Task.class, new StudySerializationUtils.Json.TaskAdapter())
|
||||
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
|
||||
.create();
|
||||
Course course = gson.fromJson(jsonText, Course.class);
|
||||
final CourseInfo courseInfo = CourseInfo.fromCourse(course);
|
||||
if (courseInfo != null) {
|
||||
myLocalCourses.add(course);
|
||||
}
|
||||
return courseInfo;
|
||||
return gson.fromJson(jsonText, Course.class);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error("Failed to unzip course archive");
|
||||
|
||||
+4
-7
@@ -14,7 +14,6 @@ import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.jetbrains.edu.learning.EduPluginConfigurator;
|
||||
import com.jetbrains.edu.learning.StudyTaskManager;
|
||||
import com.jetbrains.edu.learning.courseFormat.Course;
|
||||
import com.jetbrains.edu.learning.courseFormat.CourseInfo;
|
||||
import com.jetbrains.edu.learning.courseGeneration.StudyProjectGenerator;
|
||||
import com.jetbrains.edu.learning.intellij.generation.EduProjectGenerator;
|
||||
import org.jdom.JDOMException;
|
||||
@@ -27,7 +26,7 @@ import java.io.IOException;
|
||||
class EduCustomCourseModuleBuilder extends JavaModuleBuilder {
|
||||
private static final Logger LOG = Logger.getInstance(EduCustomCourseModuleBuilder.class);
|
||||
private EduProjectGenerator myGenerator = new EduProjectGenerator();
|
||||
private CourseInfo mySelectedCourse;
|
||||
private Course mySelectedCourse;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
@@ -36,8 +35,7 @@ class EduCustomCourseModuleBuilder extends JavaModuleBuilder {
|
||||
if (module == null) {
|
||||
return null;
|
||||
}
|
||||
String type = mySelectedCourse.getType();
|
||||
String languageName = type.substring("pycharm ".length());
|
||||
String languageName = mySelectedCourse.getLanguageID();
|
||||
Language language = Language.findLanguageByID(languageName);
|
||||
if (language == null) {
|
||||
return module;
|
||||
@@ -87,7 +85,7 @@ class EduCustomCourseModuleBuilder extends JavaModuleBuilder {
|
||||
return ProjectWizardStepFactory.getInstance().createJavaSettingsStep(settingsStep, this, Conditions.alwaysTrue());
|
||||
}
|
||||
|
||||
void setSelectedCourse(CourseInfo selectedCourse) {
|
||||
void setSelectedCourse(Course selectedCourse) {
|
||||
mySelectedCourse = selectedCourse;
|
||||
}
|
||||
|
||||
@@ -97,8 +95,7 @@ class EduCustomCourseModuleBuilder extends JavaModuleBuilder {
|
||||
throws InvalidDataException, IOException, ModuleWithNameAlreadyExists, JDOMException, ConfigurationException {
|
||||
Module baseModule = super.createModule(moduleModel);
|
||||
if (mySelectedCourse != null) {
|
||||
String type = mySelectedCourse.getType();
|
||||
String languageName = type.substring("pycharm ".length());
|
||||
String languageName = mySelectedCourse.getLanguageID();
|
||||
Language language = Language.findLanguageByID(languageName);
|
||||
if (language != null) {
|
||||
EduPluginConfigurator configurator = EduPluginConfigurator.INSTANCE.forLanguage(language);
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@ package com.jetbrains.edu.learning.intellij.localCourses;
|
||||
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||
import com.jetbrains.edu.learning.courseFormat.CourseInfo;
|
||||
import com.jetbrains.edu.learning.courseFormat.Course;
|
||||
import com.jetbrains.edu.learning.courseGeneration.StudyProjectGenerator;
|
||||
import com.jetbrains.edu.learning.ui.StudyNewProjectPanel;
|
||||
|
||||
@@ -25,7 +25,7 @@ public class EduLocalCoursePanel {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent actionEvent) {
|
||||
String coursePath = myCourseArchivePath.getText();
|
||||
CourseInfo courseInfo = generator.addLocalCourse(coursePath);
|
||||
Course courseInfo = generator.addLocalCourse(coursePath);
|
||||
if (courseInfo != null) {
|
||||
myBuilder.setSelectedCourse(courseInfo);
|
||||
myGenerator.setSelectedCourse(courseInfo);
|
||||
|
||||
+10
-11
@@ -67,11 +67,12 @@ public class EduAdaptiveStepicConnector {
|
||||
private static final Logger LOG = Logger.getInstance(EduAdaptiveStepicConnector.class);
|
||||
private static final int CONNECTION_TIMEOUT = 60 * 1000;
|
||||
private static final String CODE_TASK_TYPE = "code";
|
||||
private static final String CODE_TASK_NAME = "code.py";
|
||||
private static final String CHOICE_TYPE_TEXT = "choice";
|
||||
private static final String TEXT_STEP_TYPE = "text";
|
||||
|
||||
@Nullable
|
||||
public static Task getNextRecommendation(@NotNull Project project, @NotNull Course course) {
|
||||
public static Task getNextRecommendation(@NotNull Project project, @NotNull RemoteCourse course) {
|
||||
try {
|
||||
final CloseableHttpClient client = EduStepicAuthorizedClient.getHttpClient();
|
||||
if (client == null) {
|
||||
@@ -204,8 +205,8 @@ public class EduAdaptiveStepicConnector {
|
||||
private static void createMockTaskFile(@NotNull Task task, String editorText) {
|
||||
final TaskFile taskFile = new TaskFile();
|
||||
taskFile.text = editorText;
|
||||
taskFile.name = "code.py";
|
||||
task.taskFiles.put("code.py", taskFile);
|
||||
taskFile.name = CODE_TASK_NAME;
|
||||
task.taskFiles.put(CODE_TASK_NAME, taskFile);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -297,7 +298,7 @@ public class EduAdaptiveStepicConnector {
|
||||
int reaction) {
|
||||
final StudyEditor editor = StudyUtils.getSelectedStudyEditor(project);
|
||||
final Course course = StudyTaskManager.getInstance(project).getCourse();
|
||||
if (course == null || editor == null || editor.getTaskFile() == null) {
|
||||
if (course == null || editor == null || editor.getTaskFile() == null || !(course instanceof RemoteCourse)) {
|
||||
return;
|
||||
}
|
||||
indicator.checkCanceled();
|
||||
@@ -314,7 +315,7 @@ public class EduAdaptiveStepicConnector {
|
||||
String.valueOf(user.getId()), reaction);
|
||||
if (recommendationReaction) {
|
||||
indicator.checkCanceled();
|
||||
final Task task = getNextRecommendation(project, course);
|
||||
final Task task = getNextRecommendation(project, (RemoteCourse)course);
|
||||
|
||||
if (task != null) {
|
||||
task.initTask(lesson, false);
|
||||
@@ -438,11 +439,9 @@ public class EduAdaptiveStepicConnector {
|
||||
}
|
||||
}
|
||||
else {
|
||||
final TaskFile taskFile = new TaskFile();
|
||||
taskFile.name = CODE_TASK_TYPE;
|
||||
final String templateForTask = getCodeTemplateForTask(project, task, step.options.codeTemplates);
|
||||
taskFile.text = templateForTask == null ? "# write your answer here \n" : templateForTask;
|
||||
task.taskFiles.put("code.py", taskFile);
|
||||
String text = templateForTask == null ? "# write your answer here \n" : templateForTask;
|
||||
createMockTaskFile(task, text);
|
||||
}
|
||||
return task;
|
||||
}
|
||||
@@ -662,11 +661,11 @@ public class EduAdaptiveStepicConnector {
|
||||
public static List<Integer> getEnrolledCoursesIds(@NotNull StepicUser stepicUser) {
|
||||
try {
|
||||
final URI enrolledCoursesUri = new URIBuilder(EduStepicNames.COURSES).addParameter("enrolled", "true").build();
|
||||
final List<CourseInfo> courses = EduStepicAuthorizedClient.getFromStepic(enrolledCoursesUri.toString(),
|
||||
final List<RemoteCourse> courses = EduStepicAuthorizedClient.getFromStepic(enrolledCoursesUri.toString(),
|
||||
StepicWrappers.CoursesContainer.class,
|
||||
stepicUser).courses;
|
||||
final ArrayList<Integer> ids = new ArrayList<>();
|
||||
for (CourseInfo course : courses) {
|
||||
for (RemoteCourse course : courses) {
|
||||
ids.add(course.getId());
|
||||
}
|
||||
return ids;
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.URI;
|
||||
@@ -70,6 +71,7 @@ public class EduStepicClient {
|
||||
|
||||
static <T> T deserializeStepicResponse(Class<T> container, String responseString) {
|
||||
Gson gson = new GsonBuilder().registerTypeAdapter(StepicWrappers.StepOptions.class, new StudySerializationUtils.Json.StepicStepOptionsAdapter()).
|
||||
excludeFieldsWithModifiers(Modifier.TRANSIENT).
|
||||
setDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").
|
||||
setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
|
||||
return gson.fromJson(responseString, container);
|
||||
|
||||
+24
-31
@@ -12,8 +12,8 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.jetbrains.edu.learning.StudySettings;
|
||||
import com.jetbrains.edu.learning.core.EduNames;
|
||||
import com.jetbrains.edu.learning.courseFormat.Course;
|
||||
import com.jetbrains.edu.learning.courseFormat.CourseInfo;
|
||||
import com.jetbrains.edu.learning.courseFormat.Lesson;
|
||||
import com.jetbrains.edu.learning.courseFormat.RemoteCourse;
|
||||
import com.jetbrains.edu.learning.courseFormat.TaskFile;
|
||||
import com.jetbrains.edu.learning.courseFormat.tasks.Task;
|
||||
import com.jetbrains.edu.learning.courseFormat.tasks.TaskWithSubtasks;
|
||||
@@ -65,9 +65,9 @@ public class EduStepicConnector {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<CourseInfo> getCourses(@Nullable StepicUser user) {
|
||||
public static List<Course> getCourses(@Nullable StepicUser user) {
|
||||
try {
|
||||
List<CourseInfo> result = new ArrayList<>();
|
||||
List<Course> result = new ArrayList<>();
|
||||
int pageNumber = 1;
|
||||
while (addCoursesFromStepic(user, result, pageNumber)) {
|
||||
pageNumber += 1;
|
||||
@@ -77,13 +77,13 @@ public class EduStepicConnector {
|
||||
catch (IOException e) {
|
||||
LOG.warn("Cannot load course list " + e.getMessage());
|
||||
}
|
||||
return Collections.singletonList(CourseInfo.INVALID_COURSE);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public static Date getCourseUpdateDate(final int courseId) {
|
||||
final String url = EduStepicNames.COURSES + "/" + courseId;
|
||||
try {
|
||||
final List<CourseInfo> courses = EduStepicClient.getFromStepic(url, StepicWrappers.CoursesContainer.class).courses;
|
||||
final List<RemoteCourse> courses = EduStepicClient.getFromStepic(url, StepicWrappers.CoursesContainer.class).courses;
|
||||
if (!courses.isEmpty()) {
|
||||
return courses.get(0).getUpdateDate();
|
||||
}
|
||||
@@ -125,7 +125,7 @@ public class EduStepicConnector {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean addCoursesFromStepic(@Nullable StepicUser user, List<CourseInfo> result, int pageNumber) throws IOException {
|
||||
private static boolean addCoursesFromStepic(@Nullable StepicUser user, List<Course> result, int pageNumber) throws IOException {
|
||||
final URI url;
|
||||
try {
|
||||
url = new URIBuilder(EduStepicNames.COURSES).addParameter("is_idea_compatible", "true").
|
||||
@@ -146,27 +146,28 @@ public class EduStepicConnector {
|
||||
return coursesContainer.meta.containsKey("has_next") && coursesContainer.meta.get("has_next") == Boolean.TRUE;
|
||||
}
|
||||
|
||||
static void addAvailableCourses(List<CourseInfo> result, StepicWrappers.CoursesContainer coursesContainer) throws IOException {
|
||||
final List<CourseInfo> courseInfos = coursesContainer.courses;
|
||||
for (CourseInfo info : courseInfos) {
|
||||
static void addAvailableCourses(List<Course> result, StepicWrappers.CoursesContainer coursesContainer) throws IOException {
|
||||
final List<RemoteCourse> courses = coursesContainer.courses;
|
||||
for (RemoteCourse info : courses) {
|
||||
if (!info.isAdaptive() && StringUtil.isEmptyOrSpaces(info.getType())) continue;
|
||||
if (canBeOpened(info)) {
|
||||
final ArrayList<StepicUser> authors = new ArrayList<>();
|
||||
for (Integer instructor : info.getInstructors()) {
|
||||
final StepicUser author = EduStepicClient.getFromStepic(EduStepicNames.USERS + String.valueOf(instructor),
|
||||
StepicWrappers.AuthorWrapper.class).users.get(0);
|
||||
info.addAuthor(author);
|
||||
authors.add(author);
|
||||
}
|
||||
info.setAuthors(authors);
|
||||
|
||||
if (info.isAdaptive()) {
|
||||
info.setDescription("This is a Stepik Adaptive course.\n\n" + info.getDescription() + ADAPTIVE_NOTE);
|
||||
}
|
||||
|
||||
result.add(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static boolean canBeOpened(CourseInfo courseInfo) {
|
||||
static boolean canBeOpened(RemoteCourse courseInfo) {
|
||||
if (courseInfo.isAdaptive()) {
|
||||
return true;
|
||||
}
|
||||
@@ -190,26 +191,19 @@ public class EduStepicConnector {
|
||||
}
|
||||
}
|
||||
|
||||
public static Course getCourse(@NotNull final Project project, @NotNull final CourseInfo info) {
|
||||
final Course course = new Course();
|
||||
course.setAuthors(info.getAuthors());
|
||||
course.setDescription(info.getDescription());
|
||||
course.setAdaptive(info.isAdaptive());
|
||||
course.setId(info.getId());
|
||||
course.setUpdateDate(getCourseUpdateDate(info.getId()));
|
||||
|
||||
if (!course.isAdaptive()) {
|
||||
String courseType = info.getType();
|
||||
course.setName(info.getName());
|
||||
public static RemoteCourse getCourse(@NotNull final Project project, @NotNull final RemoteCourse course) {
|
||||
final RemoteCourse remoteCourse = (RemoteCourse)course.copy();
|
||||
if (!remoteCourse.isAdaptive()) {
|
||||
String courseType = remoteCourse.getType();
|
||||
final int separator = courseType.indexOf(" ");
|
||||
assert separator != -1;
|
||||
final String language = courseType.substring(separator + 1);
|
||||
course.setLanguage(language);
|
||||
remoteCourse.setLanguage(language);
|
||||
try {
|
||||
for (Integer section : info.getSections()) {
|
||||
course.addLessons(getLessons(section));
|
||||
for (Integer section : remoteCourse.getSections()) {
|
||||
remoteCourse.addLessons(getLessons(section));
|
||||
}
|
||||
return course;
|
||||
return remoteCourse;
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error("IOException " + e.getMessage());
|
||||
@@ -218,14 +212,13 @@ public class EduStepicConnector {
|
||||
else {
|
||||
final Lesson lesson = new Lesson();
|
||||
lesson.setName("Adaptive");
|
||||
course.addLesson(lesson);
|
||||
course.setName(info.getName());
|
||||
remoteCourse.addLesson(lesson);
|
||||
//TODO: more specific name?
|
||||
final Task recommendation = EduAdaptiveStepicConnector.getNextRecommendation(project, course);
|
||||
final Task recommendation = EduAdaptiveStepicConnector.getNextRecommendation(project, remoteCourse);
|
||||
if (recommendation != null) {
|
||||
lesson.addTask(recommendation);
|
||||
}
|
||||
return course;
|
||||
return remoteCourse;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,8 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.text.DateFormatUtil;
|
||||
import com.jetbrains.edu.learning.StudySettings;
|
||||
import com.jetbrains.edu.learning.courseFormat.CourseInfo;
|
||||
import com.jetbrains.edu.learning.courseFormat.Course;
|
||||
import com.jetbrains.edu.learning.courseFormat.RemoteCourse;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -50,13 +51,14 @@ public class EduStepicUpdater {
|
||||
private static ActionCallback updateCourseList() {
|
||||
ActionCallback callback = new ActionCallback();
|
||||
ApplicationManager.getApplication().executeOnPooledThread(() -> {
|
||||
final List<CourseInfo> courses = EduStepicConnector.getCourses(null);
|
||||
StudySettings.getInstance().setLastTimeChecked(System.currentTimeMillis());
|
||||
final List<Course> courses = EduStepicConnector.getCourses(null);
|
||||
StepicSettings.getInstance().setLastTimeChecked(System.currentTimeMillis());
|
||||
|
||||
if (!courses.isEmpty()) {
|
||||
List<CourseInfo> updated = new ArrayList<>();
|
||||
for (CourseInfo course : courses) {
|
||||
if (course.getUpdateDate().after(new Date(StepicUpdateSettings.getInstance().getLastTimeChecked()))) {
|
||||
List<Course> updated = new ArrayList<>();
|
||||
for (Course course : courses) {
|
||||
if (course instanceof RemoteCourse && ((RemoteCourse)course).getUpdateDate().
|
||||
after(new Date(StepicUpdateSettings.getInstance().getLastTimeChecked()))) {
|
||||
updated.add(course);
|
||||
}
|
||||
}
|
||||
@@ -69,7 +71,7 @@ public class EduStepicUpdater {
|
||||
}
|
||||
else {
|
||||
title = "New courses available";
|
||||
message = StringUtil.join(updated, CourseInfo::getName, ", ");
|
||||
message = StringUtil.join(updated, Course::getName, ", ");
|
||||
}
|
||||
final Notification notification = new Notification("New.course", title, message, NotificationType.INFORMATION);
|
||||
notification.notify(null);
|
||||
|
||||
@@ -11,8 +11,8 @@ 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;
|
||||
import com.jetbrains.edu.learning.courseFormat.CourseInfo;
|
||||
import com.jetbrains.edu.learning.courseFormat.Lesson;
|
||||
import com.jetbrains.edu.learning.courseFormat.RemoteCourse;
|
||||
import com.jetbrains.edu.learning.courseFormat.TaskFile;
|
||||
import com.jetbrains.edu.learning.courseFormat.tasks.Task;
|
||||
import com.jetbrains.edu.learning.courseFormat.tasks.TaskWithSubtasks;
|
||||
@@ -171,7 +171,7 @@ public class StepicWrappers {
|
||||
}
|
||||
|
||||
public static class CoursesContainer {
|
||||
public List<CourseInfo> courses;
|
||||
public List<RemoteCourse> courses;
|
||||
public Map meta;
|
||||
}
|
||||
|
||||
@@ -185,10 +185,10 @@ public class StepicWrappers {
|
||||
}
|
||||
|
||||
public static class CourseWrapper {
|
||||
CourseInfo course;
|
||||
RemoteCourse course;
|
||||
|
||||
public CourseWrapper(Course course) {
|
||||
this.course = new CourseInfo();
|
||||
this.course = new RemoteCourse();
|
||||
this.course.setName(course.getName());
|
||||
this.course.setDescription(course.getDescription());
|
||||
this.course.setAuthors(course.getAuthors());
|
||||
|
||||
+27
-28
@@ -29,7 +29,6 @@ import com.intellij.util.ui.UIUtil;
|
||||
import com.jetbrains.edu.learning.StudySettings;
|
||||
import com.jetbrains.edu.learning.StudyUtils;
|
||||
import com.jetbrains.edu.learning.courseFormat.Course;
|
||||
import com.jetbrains.edu.learning.courseFormat.CourseInfo;
|
||||
import com.jetbrains.edu.learning.courseGeneration.StudyProjectGenerator;
|
||||
import com.jetbrains.edu.learning.stepic.EduAdaptiveStepicConnector;
|
||||
import com.jetbrains.edu.learning.stepic.EduStepicAuthorizedClient;
|
||||
@@ -52,9 +51,9 @@ import java.util.List;
|
||||
* data: 7/31/14.
|
||||
*/
|
||||
public class StudyNewProjectPanel extends JPanel implements PanelWithAnchor {
|
||||
private List<CourseInfo> myAvailableCourses = new ArrayList<>();
|
||||
private List<Course> myAvailableCourses = new ArrayList<>();
|
||||
private JButton myBrowseButton;
|
||||
private ComboBox<CourseInfo> myCoursesComboBox;
|
||||
private ComboBox<Course> myCoursesComboBox;
|
||||
private JButton myRefreshButton;
|
||||
private JLabel myAuthorLabel;
|
||||
private JPanel myInfoPanel;
|
||||
@@ -122,20 +121,20 @@ public class StudyNewProjectPanel extends JPanel implements PanelWithAnchor {
|
||||
private void initCoursesCombobox() {
|
||||
myAvailableCourses =
|
||||
myGenerator.getCoursesUnderProgress(!isLocal, "Getting Available Courses", ProjectManager.getInstance().getDefaultProject());
|
||||
if (myAvailableCourses.contains(CourseInfo.INVALID_COURSE)) {
|
||||
if (myAvailableCourses.contains(Course.INVALID_COURSE)) {
|
||||
setError(CONNECTION_ERROR);
|
||||
}
|
||||
else {
|
||||
addCoursesToCombobox(myAvailableCourses);
|
||||
final CourseInfo selectedCourse = StudyUtils.getFirst(myAvailableCourses);
|
||||
final Course selectedCourse = StudyUtils.getFirst(myAvailableCourses);
|
||||
if (selectedCourse == null) return;
|
||||
setAuthors(selectedCourse);
|
||||
myDescriptionPane.setText(selectedCourse.getDescription());
|
||||
myDescriptionPane.setEditable(false);
|
||||
//setting the first course in list as selected
|
||||
myGenerator.setSelectedCourse(selectedCourse);
|
||||
if (myGenerator.getSelectedCourseInfo() != null) {
|
||||
myCoursesComboBox.setSelectedItem(myGenerator.getSelectedCourseInfo());
|
||||
if (myGenerator.getSelectedCourse() != null) {
|
||||
myCoursesComboBox.setSelectedItem(myGenerator.getSelectedCourse());
|
||||
}
|
||||
if (selectedCourse.isAdaptive() && !myGenerator.isLoggedIn()) {
|
||||
setError(LOGIN_TO_STEPIC_MESSAGE);
|
||||
@@ -174,7 +173,7 @@ public class StudyNewProjectPanel extends JPanel implements PanelWithAnchor {
|
||||
file -> {
|
||||
String fileName = file.getPath();
|
||||
int oldSize = myAvailableCourses.size();
|
||||
CourseInfo courseInfo = myGenerator.addLocalCourse(fileName);
|
||||
Course courseInfo = myGenerator.addLocalCourse(fileName);
|
||||
if (courseInfo != null) {
|
||||
if (oldSize != myAvailableCourses.size()) {
|
||||
myCoursesComboBox.addItem(courseInfo);
|
||||
@@ -185,11 +184,11 @@ public class StudyNewProjectPanel extends JPanel implements PanelWithAnchor {
|
||||
else {
|
||||
setError(INVALID_COURSE);
|
||||
myCoursesComboBox.removeAllItems();
|
||||
myCoursesComboBox.addItem(CourseInfo.INVALID_COURSE);
|
||||
for (CourseInfo course : myAvailableCourses) {
|
||||
myCoursesComboBox.addItem(Course.INVALID_COURSE);
|
||||
for (Course course : myAvailableCourses) {
|
||||
myCoursesComboBox.addItem(course);
|
||||
}
|
||||
myCoursesComboBox.setSelectedItem(CourseInfo.INVALID_COURSE);
|
||||
myCoursesComboBox.setSelectedItem(Course.INVALID_COURSE);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -221,8 +220,8 @@ public class StudyNewProjectPanel extends JPanel implements PanelWithAnchor {
|
||||
isComboboxInitialized = true;
|
||||
initCoursesCombobox();
|
||||
}
|
||||
CourseInfo selectedCourse = (CourseInfo)myCoursesComboBox.getSelectedItem();
|
||||
if (selectedCourse == null || selectedCourse.equals(CourseInfo.INVALID_COURSE)) {
|
||||
Course selectedCourse = (Course)myCoursesComboBox.getSelectedItem();
|
||||
if (selectedCourse == null || selectedCourse.equals(Course.INVALID_COURSE)) {
|
||||
setError(CONNECTION_ERROR);
|
||||
}
|
||||
}
|
||||
@@ -256,9 +255,9 @@ public class StudyNewProjectPanel extends JPanel implements PanelWithAnchor {
|
||||
myAnchor = anchor;
|
||||
}
|
||||
|
||||
public void updateInfoPanel(@NotNull CourseInfo selectedCourseInfo) {
|
||||
setAuthors(selectedCourseInfo);
|
||||
myDescriptionPane.setText(selectedCourseInfo.getDescription());
|
||||
public void updateInfoPanel(@NotNull Course selectedCourse) {
|
||||
setAuthors(selectedCourse);
|
||||
myDescriptionPane.setText(selectedCourse.getDescription());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -269,15 +268,15 @@ public class StudyNewProjectPanel extends JPanel implements PanelWithAnchor {
|
||||
private class RefreshActionListener implements ActionListener {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
final List<CourseInfo> courses =
|
||||
final List<Course> courses =
|
||||
myGenerator.getCoursesUnderProgress(true, "Refreshing Course List", DefaultProjectFactory.getInstance().getDefaultProject());
|
||||
if (!courses.contains(CourseInfo.INVALID_COURSE)) {
|
||||
if (!courses.contains(Course.INVALID_COURSE)) {
|
||||
refreshCoursesList(courses);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshCoursesList(@NotNull final List<CourseInfo> courses) {
|
||||
private void refreshCoursesList(@NotNull final List<Course> courses) {
|
||||
if (courses.isEmpty()) {
|
||||
setError(CONNECTION_ERROR);
|
||||
return;
|
||||
@@ -285,7 +284,7 @@ public class StudyNewProjectPanel extends JPanel implements PanelWithAnchor {
|
||||
myCoursesComboBox.removeAllItems();
|
||||
|
||||
addCoursesToCombobox(courses);
|
||||
final CourseInfo selectedCourse = StudyUtils.getFirst(courses);
|
||||
final Course selectedCourse = StudyUtils.getFirst(courses);
|
||||
if (selectedCourse == null) return;
|
||||
myGenerator.setSelectedCourse(selectedCourse);
|
||||
|
||||
@@ -293,8 +292,8 @@ public class StudyNewProjectPanel extends JPanel implements PanelWithAnchor {
|
||||
myAvailableCourses = courses;
|
||||
}
|
||||
|
||||
private void addCoursesToCombobox(@NotNull List<CourseInfo> courses) {
|
||||
for (CourseInfo courseInfo : courses) {
|
||||
private void addCoursesToCombobox(@NotNull List<Course> courses) {
|
||||
for (Course courseInfo : courses) {
|
||||
myCoursesComboBox.addItem(courseInfo);
|
||||
}
|
||||
}
|
||||
@@ -309,15 +308,15 @@ public class StudyNewProjectPanel extends JPanel implements PanelWithAnchor {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JComboBox cb = (JComboBox)e.getSource();
|
||||
CourseInfo selectedCourse = (CourseInfo)cb.getSelectedItem();
|
||||
if (selectedCourse == null || selectedCourse.equals(CourseInfo.INVALID_COURSE)) {
|
||||
Course selectedCourse = (Course)cb.getSelectedItem();
|
||||
if (selectedCourse == null || selectedCourse.equals(Course.INVALID_COURSE)) {
|
||||
myAuthorLabel.setText("");
|
||||
myDescriptionPane.setText("");
|
||||
setError(INVALID_COURSE);
|
||||
return;
|
||||
}
|
||||
updateInfoPanel(selectedCourse);
|
||||
myCoursesComboBox.removeItem(CourseInfo.INVALID_COURSE);
|
||||
myCoursesComboBox.removeItem(Course.INVALID_COURSE);
|
||||
myGenerator.setSelectedCourse(selectedCourse);
|
||||
|
||||
setOK();
|
||||
@@ -329,12 +328,12 @@ public class StudyNewProjectPanel extends JPanel implements PanelWithAnchor {
|
||||
}
|
||||
}
|
||||
|
||||
private void setAuthors(CourseInfo selectedCourse) {
|
||||
private void setAuthors(Course selectedCourse) {
|
||||
final String authorsString = Course.getAuthorsString(selectedCourse.getAuthors());
|
||||
myAuthorLabel.setText(!StringUtil.isEmptyOrSpaces(authorsString) ? "Author: " + authorsString : "");
|
||||
}
|
||||
|
||||
public JComboBox<CourseInfo> getCoursesComboBox() {
|
||||
public JComboBox<Course> getCoursesComboBox() {
|
||||
return myCoursesComboBox;
|
||||
}
|
||||
|
||||
@@ -367,7 +366,7 @@ public class StudyNewProjectPanel extends JPanel implements PanelWithAnchor {
|
||||
stepicUser.setPassword(myLoginPanel.getPassword());
|
||||
StudySettings.getInstance().setUser(stepicUser);
|
||||
myGenerator.setEnrolledCoursesIds(EduAdaptiveStepicConnector.getEnrolledCoursesIds(stepicUser));
|
||||
final List<CourseInfo> courses = myGenerator.getCourses(true);
|
||||
final List<Course> courses = myGenerator.getCourses(true);
|
||||
if (courses != null && myRefreshCourseList) {
|
||||
ApplicationManager.getApplication().invokeLater(() -> refreshCoursesList(courses));
|
||||
}
|
||||
|
||||
+3
-3
@@ -8,7 +8,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import com.jetbrains.edu.learning.StudySerializationUtils;
|
||||
import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholder;
|
||||
import com.jetbrains.edu.learning.courseFormat.AnswerPlaceholderSubtaskInfo;
|
||||
import com.jetbrains.edu.learning.courseFormat.CourseInfo;
|
||||
import com.jetbrains.edu.learning.courseFormat.RemoteCourse;
|
||||
import com.jetbrains.edu.learning.courseFormat.TaskFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Test;
|
||||
@@ -65,9 +65,9 @@ public class StudyStepicFormatTest {
|
||||
EduStepicClient.deserializeStepicResponse(StepicWrappers.CoursesContainer.class, responseString);
|
||||
assertNotNull(container.courses);
|
||||
assertTrue("Incorrect number of courses", container.courses.size() == 4);
|
||||
List<CourseInfo> filtered = ContainerUtil.filter(container.courses, info -> EduStepicConnector.canBeOpened(info));
|
||||
List<RemoteCourse> filtered = ContainerUtil.filter(container.courses, info -> EduStepicConnector.canBeOpened(info));
|
||||
assertEquals(ContainerUtil.newArrayList("Adaptive Python", "Introduction to Python", "format2"),
|
||||
ContainerUtil.map(filtered, CourseInfo::getName));
|
||||
ContainerUtil.map(filtered, RemoteCourse::getName));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Binary file not shown.
+6
-7
@@ -10,7 +10,6 @@ import com.jetbrains.edu.learning.PyStudyDirectoryProjectGenerator;
|
||||
import com.jetbrains.edu.learning.StudyTaskManager;
|
||||
import com.jetbrains.edu.learning.core.EduNames;
|
||||
import com.jetbrains.edu.learning.courseFormat.Course;
|
||||
import com.jetbrains.edu.learning.courseFormat.CourseInfo;
|
||||
import com.jetbrains.edu.learning.courseGeneration.StudyProjectGenerator;
|
||||
import com.jetbrains.python.newProject.steps.PyCharmNewProjectStep;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -44,10 +43,10 @@ class CreateFromArchiveProjectStep extends PyCharmNewProjectStep {
|
||||
@NotNull
|
||||
@Override
|
||||
protected DirectoryProjectGenerator createEmptyProjectGenerator() {
|
||||
Course course = StudyTaskManager.getInstance(myProject).getCourse();
|
||||
if (course != null) {
|
||||
Course currentCourse = StudyTaskManager.getInstance(myProject).getCourse();
|
||||
if (currentCourse != null) {
|
||||
VirtualFile folder = CCUtils.getGeneratedFilesFolder(myProject, myModule);
|
||||
String zipName = FileUtil.sanitizeFileName(course.getName());
|
||||
String zipName = FileUtil.sanitizeFileName(currentCourse.getName());
|
||||
if (zipName.isEmpty()) {
|
||||
zipName = EduNames.COURSE;
|
||||
}
|
||||
@@ -55,9 +54,9 @@ class CreateFromArchiveProjectStep extends PyCharmNewProjectStep {
|
||||
CCCreateCourseArchive.createCourseArchive(myProject, myModule, zipName, locationDir, false);
|
||||
String path = FileUtil.join(FileUtil.toSystemDependentName(folder.getPath()), zipName + ".zip");
|
||||
StudyProjectGenerator generator = myGenerator.getGenerator();
|
||||
CourseInfo info = generator.addLocalCourse(path);
|
||||
assert info != null;
|
||||
generator.setSelectedCourse(info);
|
||||
Course course = generator.addLocalCourse(path);
|
||||
assert course != null;
|
||||
generator.setSelectedCourse(course);
|
||||
}
|
||||
return myGenerator;
|
||||
}
|
||||
|
||||
+10
-10
@@ -25,7 +25,7 @@ import com.intellij.psi.PsiManager;
|
||||
import com.intellij.util.BooleanFunction;
|
||||
import com.jetbrains.edu.learning.core.EduNames;
|
||||
import com.jetbrains.edu.learning.courseFormat.Course;
|
||||
import com.jetbrains.edu.learning.courseFormat.CourseInfo;
|
||||
import com.jetbrains.edu.learning.courseFormat.RemoteCourse;
|
||||
import com.jetbrains.edu.learning.courseGeneration.StudyProjectGenerator;
|
||||
import com.jetbrains.edu.learning.stepic.EduStepicConnector;
|
||||
import com.jetbrains.edu.learning.ui.StudyNewProjectPanel;
|
||||
@@ -87,7 +87,7 @@ public class PyStudyDirectoryProjectGenerator extends PythonProjectGenerator<PyN
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
final Object selectedItem = mySettingsPanel.getCoursesComboBox().getSelectedItem();
|
||||
if (selectedItem != null && ((CourseInfo)selectedItem).isAdaptive() && !myGenerator.isLoggedIn()) {
|
||||
if (selectedItem != null && ((Course)selectedItem).isAdaptive() && !myGenerator.isLoggedIn()) {
|
||||
mySettingsPanel.showLoginDialog(false, "Signing In");
|
||||
}
|
||||
}
|
||||
@@ -95,14 +95,14 @@ public class PyStudyDirectoryProjectGenerator extends PythonProjectGenerator<PyN
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
final Object selectedItem = mySettingsPanel.getCoursesComboBox().getSelectedItem();
|
||||
if (selectedItem != null && ((CourseInfo)selectedItem).isAdaptive() && !myGenerator.isLoggedIn()) {
|
||||
if (selectedItem != null && ((Course)selectedItem).isAdaptive() && !myGenerator.isLoggedIn()) {
|
||||
e.getComponent().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
final CourseInfo selectedItem = (CourseInfo)mySettingsPanel.getCoursesComboBox().getSelectedItem();
|
||||
final Course selectedItem = (Course)mySettingsPanel.getCoursesComboBox().getSelectedItem();
|
||||
if (selectedItem != null && selectedItem.isAdaptive() && !myGenerator.isLoggedIn()) {
|
||||
e.getComponent().setCursor(Cursor.getDefaultCursor());
|
||||
}
|
||||
@@ -165,7 +165,7 @@ public class PyStudyDirectoryProjectGenerator extends PythonProjectGenerator<PyN
|
||||
return mySettingsPanel;
|
||||
}
|
||||
|
||||
public void setSelectedCourse(CourseInfo course) {
|
||||
public void setSelectedCourse(Course course) {
|
||||
myGenerator.setSelectedCourse(course);
|
||||
}
|
||||
|
||||
@@ -183,13 +183,13 @@ public class PyStudyDirectoryProjectGenerator extends PythonProjectGenerator<PyN
|
||||
public BooleanFunction<PythonProjectGenerator> beforeProjectGenerated(@Nullable Sdk sdk) {
|
||||
return generator -> {
|
||||
final List<Integer> enrolledCoursesIds = myGenerator.getEnrolledCoursesIds();
|
||||
final CourseInfo course = (CourseInfo)mySettingsPanel.getCoursesComboBox().getSelectedItem();
|
||||
if (course == null) return true;
|
||||
if (course.getId() > 0 && !enrolledCoursesIds.contains(course.getId())) {
|
||||
final Course course = (Course)mySettingsPanel.getCoursesComboBox().getSelectedItem();
|
||||
if (course == null || !(course instanceof RemoteCourse)) return true;
|
||||
if (((RemoteCourse)course).getId() > 0 && !enrolledCoursesIds.contains(((RemoteCourse)course).getId())) {
|
||||
ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> {
|
||||
ProgressManager.getInstance().getProgressIndicator().setIndeterminate(true);
|
||||
return StudyUtils.execCancelable(() -> EduStepicConnector.enrollToCourse(course.getId(),
|
||||
StudySettings.getInstance().getUser()));
|
||||
return StudyUtils.execCancelable(() -> EduStepicConnector.enrollToCourse(((RemoteCourse)course).getId(),
|
||||
StepicSettings.getInstance().getUser()));
|
||||
}, "Creating Course", true, ProjectManager.getInstance().getDefaultProject());
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -21,7 +21,7 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.jetbrains.edu.learning.EduPluginConfigurator;
|
||||
import com.jetbrains.edu.learning.PyStudyDirectoryProjectGenerator;
|
||||
import com.jetbrains.edu.learning.courseFormat.CourseInfo;
|
||||
import com.jetbrains.edu.learning.courseFormat.Course;
|
||||
import com.jetbrains.python.PythonLanguage;
|
||||
import com.jetbrains.python.newProject.steps.ProjectSpecificSettingsStep;
|
||||
import com.jetbrains.python.newProject.steps.PythonGenerateProjectCallback;
|
||||
@@ -64,7 +64,7 @@ public class PyStudyIntroductionCourseAction extends AnAction {
|
||||
final PyStudyDirectoryProjectGenerator generator = new PyStudyDirectoryProjectGenerator(true);
|
||||
final EduPluginConfigurator configurator = EduPluginConfigurator.INSTANCE.forLanguage(PythonLanguage.getInstance());
|
||||
final String bundledCoursePath = configurator.getBundledCoursePath();
|
||||
CourseInfo introCourse = generator.getGenerator().getCourseInfo(bundledCoursePath);
|
||||
Course introCourse = generator.getGenerator().getCourse(bundledCoursePath);
|
||||
if (introCourse == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user