feat: integrated exercises into lessons

- an exercise can now be added to a lesson
- it is rendered using livecode editor with submit button
- remembers the submitted code and shows the submission time

Issue #90
This commit is contained in:
Anand Chitipothu
2021-05-19 20:04:20 +05:30
parent d61acb552a
commit 6f7011ca58
7 changed files with 99 additions and 8 deletions

View File

@@ -21,3 +21,13 @@ def get_section(name):
"""
doc = frappe.get_doc("LMS Section", name)
return doc and doc.as_dict()
@frappe.whitelist()
def submit_solution(exercise, code):
"""Submits a solution.
"""
ex = frappe.get_doc("Exercise", exercise)
if not ex:
return
doc = ex.submit(code)
return {"name": doc.name, "creation": doc.creation}

View File

@@ -18,6 +18,7 @@ class Lesson(Document):
def make_lms_section(self, index, section):
s = frappe.new_doc('LMS Section', parent_doc=self, parentfield='sections')
s.type = section.type
s.id = section.id
s.label = section.label
s.contents = section.contents
s.index = index

View File

@@ -9,7 +9,8 @@
"contents",
"code",
"attrs",
"index"
"index",
"id"
],
"fields": [
{
@@ -43,12 +44,17 @@
"fieldname": "index",
"fieldtype": "Int",
"label": "Index"
},
{
"fieldname": "id",
"fieldtype": "Data",
"label": "id"
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2021-03-12 17:56:23.118854",
"modified": "2021-05-19 18:55:26.019625",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Section",

View File

@@ -10,6 +10,10 @@ class LMSSection(Document):
def __repr__(self):
return f"<LMSSection {self.label!r}>"
def get_exercise(self):
if self.type == "exercise":
return frappe.get_doc("Exercise", self.id)
def get_latest_code_for_user(self):
"""Returns the latest code for the logged in user.
"""

View File

@@ -0,0 +1,14 @@
{% from "www/macros/livecode.html" import LiveCodeEditorJS, LiveCodeEditor with context %}
<div class="exercise">
<h2>{{ exercise.title }}</h2>
<div class="exercise-description">{{frappe.utils.md_to_html(exercise.description)}}</div>
{% set submission = exercise.get_user_submission() %}
{{ LiveCodeEditor(exercise.name,
code=exercise.code,
reset_code=exercise.code,
is_exercise=True,
last_submitted=submission and submission.creation) }}
</div>