diff --git a/community/lms/api.py b/community/lms/api.py index 1ed198e1..089ad86d 100644 --- a/community/lms/api.py +++ b/community/lms/api.py @@ -15,13 +15,6 @@ def autosave_section(section, code): doc.insert() return {"name": doc.name} -@frappe.whitelist() -def get_section(name): - """Saves the code edited in one of the sections. - """ - doc = frappe.get_doc("LMS Section", name) - return doc and doc.as_dict() - @frappe.whitelist() def submit_solution(exercise, code): """Submits a solution. diff --git a/community/lms/doctype/chapter/chapter.py b/community/lms/doctype/chapter/chapter.py index 6c160455..b616de2c 100644 --- a/community/lms/doctype/chapter/chapter.py +++ b/community/lms/doctype/chapter/chapter.py @@ -12,5 +12,4 @@ class Chapter(Document): filters={"chapter": self.name}, fields='name', order_by="index_") - print("rows", rows) return [frappe.get_doc('Lesson', row['name']) for row in rows] diff --git a/community/lms/doctype/invite_request/invite_request.py b/community/lms/doctype/invite_request/invite_request.py index 00bc18c2..325f2611 100644 --- a/community/lms/doctype/invite_request/invite_request.py +++ b/community/lms/doctype/invite_request/invite_request.py @@ -58,7 +58,8 @@ def create_invite_request(invite_email): frappe.get_doc({ "doctype": "Invite Request", - "invite_email": invite_email + "invite_email": invite_email, + "status": "Approved" }).save(ignore_permissions=True) return "OK" diff --git a/community/lms/doctype/lesson/lesson.json b/community/lms/doctype/lesson/lesson.json index 59df2394..18c20147 100644 --- a/community/lms/doctype/lesson/lesson.json +++ b/community/lms/doctype/lesson/lesson.json @@ -8,12 +8,13 @@ "field_order": [ "chapter", "lesson_type", + "include_in_preview", + "column_break_4", "title", "index_", "index_label", - "body", - "sections", - "include_in_preview" + "section_break_6", + "body" ], "fields": [ { @@ -48,12 +49,6 @@ "fieldtype": "Markdown Editor", "label": "Body" }, - { - "fieldname": "sections", - "fieldtype": "Table", - "label": "Sections", - "options": "LMS Section" - }, { "fieldname": "index_label", "fieldtype": "Data", @@ -66,11 +61,19 @@ "fieldname": "include_in_preview", "fieldtype": "Check", "label": "Include In Preview" + }, + { + "fieldname": "section_break_6", + "fieldtype": "Section Break" + }, + { + "fieldname": "column_break_4", + "fieldtype": "Column Break" } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2021-06-10 10:06:39.176891", + "modified": "2021-06-11 19:03:23.138165", "modified_by": "Administrator", "module": "LMS", "name": "Lesson", diff --git a/community/lms/doctype/lesson/lesson.py b/community/lms/doctype/lesson/lesson.py index 52d8bf28..49abb2d7 100644 --- a/community/lms/doctype/lesson/lesson.py +++ b/community/lms/doctype/lesson/lesson.py @@ -5,7 +5,6 @@ from __future__ import unicode_literals import frappe from frappe.model.document import Document -from ...section_parser import SectionParser from ...md import markdown_to_html, find_macros class Lesson(Document): @@ -39,9 +38,6 @@ class Lesson(Document): def render_html(self): return markdown_to_html(self.body) - def get_sections(self): - return sorted(self.get('sections'), key=lambda s: s.index) - def get_exercises(self): if not self.body: return [] @@ -50,30 +46,6 @@ class Lesson(Document): exercises = [value for name, value in macros if name == "Exercise"] return [frappe.get_doc("Exercise", name) for name in exercises] - 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 - return s - - def get_next(self): - """Returns the number for the next lesson. - - The return value would be like 1.2, 2.1 etc. - It will be None if there is no next lesson. - """ - - - def get_prev(self): - """Returns the number for the prev lesson. - - The return value would be like 1.2, 2.1 etc. - It will be None if there is no next lesson. - """ - def get_progress(self): return frappe.db.get_value("LMS Course Progress", {"lesson": self.name, "owner": frappe.session.user}, "status") @@ -98,11 +70,7 @@ def save_progress(lesson, batch): return lesson_details = frappe.get_doc("Lesson", lesson) - dynamic_content = frappe.db.count("LMS Section", - filters={ - "type": ["not in", ["example", "text"]], - "parent": lesson_details.name - }) + dynamic_content = find_macros(lesson_details.body) status = "Complete" if dynamic_content: @@ -121,12 +89,11 @@ def update_progress(lesson): if frappe.db.exists("LMS Course Progress", {"lesson": lesson, "owner": user}): course_progress = frappe.get_doc("LMS Course Progress", {"lesson": lesson, "owner": user}) course_progress.status = "Complete" - course_progress.save() + course_progress.save(ignore_permissions=True) def all_dynamic_content_submitted(lesson, user): - exercise_names = frappe.get_list("Exercise", {"lesson": lesson}, ["name"], pluck="name") + exercise_names = frappe.get_list("Exercise", {"lesson": lesson}, pluck="name") all_exercises_submitted = False - print(exercise_names) query = { "exercise": ["in", exercise_names], "owner": user diff --git a/community/lms/doctype/lms_batch/lms_batch.py b/community/lms/doctype/lms_batch/lms_batch.py index 93ed20bd..391eac7e 100644 --- a/community/lms/doctype/lms_batch/lms_batch.py +++ b/community/lms/doctype/lms_batch/lms_batch.py @@ -80,11 +80,6 @@ class LMSBatch(Document): membership = self.get_membership(user) return membership and membership.current_lesson - def get_learn_url(self, lesson_number): - if not lesson_number: - return - return f"/courses/{self.course}/learn/{lesson_number}" - @frappe.whitelist() def save_message(message, batch): doc = frappe.get_doc({ diff --git a/community/lms/doctype/lms_batch_membership/lms_batch_membership.json b/community/lms/doctype/lms_batch_membership/lms_batch_membership.json index 68d2eaed..6a0cc143 100644 --- a/community/lms/doctype/lms_batch_membership/lms_batch_membership.json +++ b/community/lms/doctype/lms_batch_membership/lms_batch_membership.json @@ -13,7 +13,8 @@ "course", "member_type", "role", - "current_lesson" + "current_lesson", + "is_current" ], "fields": [ { @@ -80,11 +81,19 @@ "fieldtype": "Data", "label": "Memeber Username", "read_only": 1 + }, + { + "default": "0", + "fieldname": "is_current", + "fieldtype": "Check", + "hidden": 1, + "label": "Is Currently Being Used", + "read_only": 1 } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2021-05-24 12:40:57.125694", + "modified": "2021-06-14 10:24:35.425498", "modified_by": "Administrator", "module": "LMS", "name": "LMS Batch Membership", diff --git a/community/lms/doctype/lms_batch_membership/lms_batch_membership.py b/community/lms/doctype/lms_batch_membership/lms_batch_membership.py index cda7c53b..f7a39b74 100644 --- a/community/lms/doctype/lms_batch_membership/lms_batch_membership.py +++ b/community/lms/doctype/lms_batch_membership/lms_batch_membership.py @@ -43,9 +43,6 @@ class LMSBatchMembership(Document): member_name = frappe.db.get_value("User", self.member, "full_name") frappe.throw(_("{0} is already a {1} of {2} course through {3} batch").format(member_name, membership.member_type, course, membership.batch)) - def get_user_batch(course, user=frappe.session.user): - return frappe.db.get_value("LMS Batch Membership", {"member": user, "course": course}, "batch") - @frappe.whitelist() def create_membership(batch, member=None, member_type="Student", role="Member"): frappe.get_doc({ @@ -56,3 +53,13 @@ def create_membership(batch, member=None, member_type="Student", role="Member"): "member": member or frappe.session.user }).save(ignore_permissions=True) return "OK" + +@frappe.whitelist() +def update_current_membership(batch, course, member=frappe.session.user): + all_memberships = frappe.get_all("LMS Batch Membership", {"member": member, "course": course}) + for membership in all_memberships: + frappe.db.set_value("LMS Batch Membership", membership.name, "is_current", 0) + + current_membership = frappe.get_all("LMS Batch Membership", {"batch": batch, "member": member}) + if len(current_membership): + frappe.db.set_value("LMS Batch Membership", current_membership[0].name, "is_current", 1) diff --git a/community/lms/doctype/lms_course/lms_course.py b/community/lms/doctype/lms_course/lms_course.py index 315a9092..30e25b85 100644 --- a/community/lms/doctype/lms_course/lms_course.py +++ b/community/lms/doctype/lms_course/lms_course.py @@ -187,6 +187,22 @@ class LMSCourse(Document): exercise.save() i += 1 + def get_learn_url(self, lesson_number): + if not lesson_number: + return + return f"/courses/{self.name}/learn/{lesson_number}" + + def get_current_batch(self, member=frappe.session.user): + current_membership = frappe.get_all("LMS Batch Membership", {"member": member, "course": self.name, "is_current": 1}, pluck="batch") + if len(current_membership): + return current_membership[0] + return frappe.db.get_value("LMS Batch Membership", {"member": member, "course": self.name}, "batch") + + def get_all_memberships(self, member=frappe.session.user): + all_memberships = frappe.get_all("LMS Batch Membership", {"member": member, "course": self.name}, ["batch", "is_current"]) + for membership in all_memberships: + membership.batch_title = frappe.db.get_value("LMS Batch", membership.batch, "title") + return all_memberships def get_outline(self): return CourseOutline(self) diff --git a/community/lms/doctype/lms_section/__init__.py b/community/lms/doctype/lms_section/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/community/lms/doctype/lms_section/lms_section.json b/community/lms/doctype/lms_section/lms_section.json deleted file mode 100644 index 3b056485..00000000 --- a/community/lms/doctype/lms_section/lms_section.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "actions": [], - "creation": "2021-03-05 15:10:53.906006", - "doctype": "DocType", - "engine": "InnoDB", - "field_order": [ - "label", - "type", - "contents", - "code", - "attrs", - "index", - "id" - ], - "fields": [ - { - "fieldname": "label", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Label" - }, - { - "fieldname": "type", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Type" - }, - { - "fieldname": "contents", - "fieldtype": "Markdown Editor", - "label": "Contents" - }, - { - "fieldname": "code", - "fieldtype": "Code", - "label": "Code" - }, - { - "fieldname": "attrs", - "fieldtype": "Long Text", - "label": "attrs" - }, - { - "fieldname": "index", - "fieldtype": "Int", - "label": "Index" - }, - { - "fieldname": "id", - "fieldtype": "Data", - "label": "id" - } - ], - "index_web_pages_for_search": 1, - "istable": 1, - "links": [], - "modified": "2021-05-19 18:55:26.019625", - "modified_by": "Administrator", - "module": "LMS", - "name": "LMS Section", - "owner": "Administrator", - "permissions": [], - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/community/lms/doctype/lms_section/lms_section.py b/community/lms/doctype/lms_section/lms_section.py deleted file mode 100644 index 65c33f46..00000000 --- a/community/lms/doctype/lms_section/lms_section.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2021, FOSS United and contributors -# For license information, please see license.txt - -from __future__ import unicode_literals -import frappe -from frappe.model.document import Document - -class LMSSection(Document): - def __repr__(self): - return f"" - - 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. - """ - if not frappe.session.user or frappe.session.user == "Guest": - return self.contents - result = frappe.get_all('Code Revision', - fields=["code"], - filters={ - "author": frappe.session.user, - "section": self.name - }, - order_by="creation desc", - page_length=1) - if result: - return result[0]['code'] - else: - return self.contents diff --git a/community/lms/section_parser.py b/community/lms/section_parser.py deleted file mode 100644 index 183a7c6b..00000000 --- a/community/lms/section_parser.py +++ /dev/null @@ -1,84 +0,0 @@ -"""Utility to split the text in the topic into multiple sections. - -{{ section(type="example", id="foo") }} -circle(100, 100, 50) -{{ end }} - -""" -from __future__ import annotations -from dataclasses import dataclass -import re -from typing import List, Tuple, Dict, Iterator - -RE_SECTION = re.compile(r"^\{\{\s(\w+)\s*(?:\((.*)\))?\s*\}\}\s*") -class SectionParser: - def parse(self, text: str) -> Iterator[Section]: - """Parses given text into sections and return an iterator over sections. - """ - lines = text.splitlines() - marked_lines = self.parse_lines(lines) - return self.group_sections(marked_lines) - - def parse_lines(self, lines: List[str]) -> List[Tuple[str, str, str]]: - for line in lines: - m = RE_SECTION.match(line) - if m: - yield m.group(1), self.parse_attrs(m.group(2)), None - else: - yield None, None, line - - def parse_attrs(self, attrs_str: str) -> Dict[str, str]: - # XXX-Anand: Hack - code = "dict({})".format(attrs_str or "") - return eval(code) - - def group_sections(self, marked_lines) -> Iterator[Section]: - index = 0 - - def make_section(type='text', id=None, label=None, **attrs): - nonlocal index - index += 1 - - id = id or f"section-{index}" - label = label or id - return Section( - type=type, - id=id, - label=label, - attrs=attrs) - - section = make_section("text") - - for mark, attrs, line in marked_lines: - if not mark: - section.append(line) - continue - - yield section - - if mark == 'end': - section = make_section(type='text') - else: - section = make_section(**attrs) - - yield section - -@dataclass -class Section: - """One section of the Topic. - """ - type: str - id: str - label: str - contents: str = "" - attrs: dict = None - - def append(self, line): - if not line.endswith("\n"): - line = line + "\n" - self.contents += line - - def __repr__(self): - attrs = dict(type=self.type, id=self.id, label=self.label, **self.attrs) - attrs_str = ", ".join(f'{k}="{v}"' for k, v in attrs.items()) - return f'' diff --git a/community/lms/web_form/add_a_new_batch/add_a_new_batch.json b/community/lms/web_form/add_a_new_batch/add_a_new_batch.json index 76735390..caf901ff 100644 --- a/community/lms/web_form/add_a_new_batch/add_a_new_batch.json +++ b/community/lms/web_form/add_a_new_batch/add_a_new_batch.json @@ -11,7 +11,7 @@ "apply_document_permissions": 0, "button_label": "Save", "creation": "2021-04-20 11:37:49.135114", - "custom_css": ".datepicker.active {\n background-color: white;\n}", + "custom_css": ".datepicker.active {\n background-color: white;\n}\n\n[data-doctype=\"Web Form\"] {\n max-width: 720px;\n margin: 6rem auto;\n}", "doc_type": "LMS Batch", "docstatus": 0, "doctype": "Web Form", @@ -19,7 +19,7 @@ "is_standard": 1, "login_required": 1, "max_attachment_size": 0, - "modified": "2021-06-02 15:52:06.383260", + "modified": "2021-06-14 15:28:08.206622", "modified_by": "Administrator", "module": "LMS", "name": "add-a-new-batch", diff --git a/community/lms/web_form/join_a_batch/__init__.py b/community/lms/web_form/join_a_batch/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/community/lms/web_form/join_a_batch/join_a_batch.js b/community/lms/web_form/join_a_batch/join_a_batch.js deleted file mode 100644 index 699703c5..00000000 --- a/community/lms/web_form/join_a_batch/join_a_batch.js +++ /dev/null @@ -1,3 +0,0 @@ -frappe.ready(function() { - // bind events here -}) \ No newline at end of file diff --git a/community/lms/web_form/join_a_batch/join_a_batch.json b/community/lms/web_form/join_a_batch/join_a_batch.json deleted file mode 100644 index 9afd7801..00000000 --- a/community/lms/web_form/join_a_batch/join_a_batch.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "accept_payment": 0, - "allow_comments": 0, - "allow_delete": 0, - "allow_edit": 0, - "allow_incomplete": 0, - "allow_multiple": 0, - "allow_print": 0, - "amount": 0.0, - "amount_based_on_field": 0, - "apply_document_permissions": 0, - "button_label": "Save", - "creation": "2021-04-15 13:32:14.171328", - "doc_type": "LMS Batch Membership", - "docstatus": 0, - "doctype": "Web Form", - "idx": 0, - "is_standard": 1, - "login_required": 1, - "max_attachment_size": 0, - "modified": "2021-04-15 13:32:14.171328", - "modified_by": "Administrator", - "module": "LMS", - "name": "join-a-batch", - "owner": "Administrator", - "payment_button_label": "Buy Now", - "published": 1, - "route": "join-a-batch", - "route_to_success_link": 0, - "show_attachments": 0, - "show_in_grid": 0, - "show_sidebar": 0, - "sidebar_items": [], - "success_url": "/join-a-batch", - "title": "Join a Batch", - "web_form_fields": [ - { - "allow_read_on_all_link_options": 0, - "fieldtype": "Attach", - "hidden": 0, - "max_length": 0, - "max_value": 0, - "read_only": 0, - "reqd": 0, - "show_in_filter": 0 - } - ] -} \ No newline at end of file diff --git a/community/lms/web_form/join_a_batch/join_a_batch.py b/community/lms/web_form/join_a_batch/join_a_batch.py deleted file mode 100644 index 2334f8b2..00000000 --- a/community/lms/web_form/join_a_batch/join_a_batch.py +++ /dev/null @@ -1,7 +0,0 @@ -from __future__ import unicode_literals - -import frappe - -def get_context(context): - # do your magic here - pass diff --git a/community/lms/widgets/BatchTabs.html b/community/lms/widgets/BatchTabs.html index 983b5655..5a3b8a0f 100644 --- a/community/lms/widgets/BatchTabs.html +++ b/community/lms/widgets/BatchTabs.html @@ -2,9 +2,28 @@ Courses /{% if course.is_mentor(frappe.session.user) %} {{ course.title }} {% else %} {{ course.title }} {% endif %} + {% set all_memberships = course.get_all_memberships() %} + {% if all_memberships | length > 1 %} + + + {% endif %} +{% if not batch %} +{% set display_class = "hide" %} +{% else %} +{% set display_class = "" %} +{% endif %}