Merge branch 'main' of https://github.com/fossunited/community into discussions-shift
This commit is contained in:
@@ -1,16 +0,0 @@
|
|||||||
// Copyright (c) 2021, FOSS United and contributors
|
|
||||||
// For license information, please see license.txt
|
|
||||||
|
|
||||||
frappe.ui.form.on('Chapter', {
|
|
||||||
|
|
||||||
onload: function (frm) {
|
|
||||||
frm.set_query("lesson", "lessons", function () {
|
|
||||||
return {
|
|
||||||
filters: {
|
|
||||||
"chapter": frm.doc.name,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
{
|
|
||||||
"actions": [],
|
|
||||||
"allow_rename": 1,
|
|
||||||
"autoname": "format:{####} {title}",
|
|
||||||
"creation": "2021-05-03 05:49:08.383057",
|
|
||||||
"doctype": "DocType",
|
|
||||||
"editable_grid": 1,
|
|
||||||
"engine": "InnoDB",
|
|
||||||
"field_order": [
|
|
||||||
"course",
|
|
||||||
"title",
|
|
||||||
"column_break_3",
|
|
||||||
"description",
|
|
||||||
"section_break_5",
|
|
||||||
"lessons"
|
|
||||||
],
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"fieldname": "title",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Title",
|
|
||||||
"reqd": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "description",
|
|
||||||
"fieldtype": "Small Text",
|
|
||||||
"label": "Description"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "course",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Course",
|
|
||||||
"options": "LMS Course",
|
|
||||||
"reqd": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "lessons",
|
|
||||||
"fieldtype": "Table",
|
|
||||||
"label": "Lessons",
|
|
||||||
"options": "Lesson Reference"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "column_break_3",
|
|
||||||
"fieldtype": "Column Break"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "section_break_5",
|
|
||||||
"fieldtype": "Section Break"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"index_web_pages_for_search": 1,
|
|
||||||
"links": [
|
|
||||||
{
|
|
||||||
"group": "Lessons",
|
|
||||||
"link_doctype": "Lesson",
|
|
||||||
"link_fieldname": "chapter"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"modified": "2021-09-20 10:58:47.241660",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "LMS",
|
|
||||||
"name": "Chapter",
|
|
||||||
"naming_rule": "Expression",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
|
||||||
{
|
|
||||||
"create": 1,
|
|
||||||
"delete": 1,
|
|
||||||
"email": 1,
|
|
||||||
"export": 1,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "System Manager",
|
|
||||||
"share": 1,
|
|
||||||
"write": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"search_fields": "title",
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"title_field": "title",
|
|
||||||
"track_changes": 1
|
|
||||||
}
|
|
||||||
@@ -1,10 +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 Chapter(Document):
|
|
||||||
pass
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2021, FOSS United and Contributors
|
|
||||||
# See license.txt
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
# import frappe
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
class TestChapter(unittest.TestCase):
|
|
||||||
pass
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
// Copyright (c) 2021, FOSS United and contributors
|
|
||||||
// For license information, please see license.txt
|
|
||||||
|
|
||||||
frappe.ui.form.on('Lesson', {
|
|
||||||
setup: function (frm) {
|
|
||||||
frm.trigger('setup_help');
|
|
||||||
},
|
|
||||||
setup_help(frm) {
|
|
||||||
frm.get_field('help').html(`
|
|
||||||
<p>You can add some more additional content to the lesson using a special syntax. The table below mentions all types of dynamic content that you can add to the lessons and the syntax for the same.</p>
|
|
||||||
<div class="row font-weight-bold mb-3">
|
|
||||||
<div class="col-sm-4">
|
|
||||||
Content Type
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-4">
|
|
||||||
Syntax
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<div class="col-sm-4">
|
|
||||||
Video
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-4">
|
|
||||||
{{ Video("url_of_source") }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<div class="col-sm-4">
|
|
||||||
YouTube Video
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-4">
|
|
||||||
{{ YouTubeVideo("unique_embed_id") }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<div class="col-sm-4">
|
|
||||||
Exercise
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-4">
|
|
||||||
{{ Exercise("exercise_name") }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<div class="col-sm-4">
|
|
||||||
Quiz
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-4">
|
|
||||||
{{ Quiz("lms_quiz_name") }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
{
|
|
||||||
"actions": [],
|
|
||||||
"allow_rename": 1,
|
|
||||||
"autoname": "format:{####} {title}",
|
|
||||||
"creation": "2021-05-03 06:21:12.995987",
|
|
||||||
"doctype": "DocType",
|
|
||||||
"editable_grid": 1,
|
|
||||||
"engine": "InnoDB",
|
|
||||||
"field_order": [
|
|
||||||
"chapter",
|
|
||||||
"include_in_preview",
|
|
||||||
"column_break_4",
|
|
||||||
"title",
|
|
||||||
"index_label",
|
|
||||||
"section_break_6",
|
|
||||||
"body",
|
|
||||||
"help_section",
|
|
||||||
"help"
|
|
||||||
],
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"fieldname": "chapter",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Chapter",
|
|
||||||
"options": "Chapter",
|
|
||||||
"reqd": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "title",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Title",
|
|
||||||
"reqd": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "body",
|
|
||||||
"fieldtype": "Markdown Editor",
|
|
||||||
"label": "Body",
|
|
||||||
"reqd": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "index_label",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"label": "Index Label",
|
|
||||||
"read_only": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "0",
|
|
||||||
"fieldname": "include_in_preview",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Include In Preview"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "section_break_6",
|
|
||||||
"fieldtype": "Section Break"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "column_break_4",
|
|
||||||
"fieldtype": "Column Break"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "help_section",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"label": "Help"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "help",
|
|
||||||
"fieldtype": "HTML"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"index_web_pages_for_search": 1,
|
|
||||||
"links": [],
|
|
||||||
"modified": "2021-09-20 10:52:29.116536",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "LMS",
|
|
||||||
"name": "Lesson",
|
|
||||||
"naming_rule": "Expression",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
|
||||||
{
|
|
||||||
"create": 1,
|
|
||||||
"delete": 1,
|
|
||||||
"email": 1,
|
|
||||||
"export": 1,
|
|
||||||
"print": 1,
|
|
||||||
"read": 1,
|
|
||||||
"report": 1,
|
|
||||||
"role": "System Manager",
|
|
||||||
"share": 1,
|
|
||||||
"write": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 1
|
|
||||||
}
|
|
||||||
@@ -1,96 +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
|
|
||||||
from ...md import markdown_to_html, find_macros
|
|
||||||
|
|
||||||
class Lesson(Document):
|
|
||||||
def on_update(self):
|
|
||||||
dynamic_documents = ["Exercise", "Quiz"]
|
|
||||||
for section in dynamic_documents:
|
|
||||||
self.update_lesson_name_in_document(section)
|
|
||||||
|
|
||||||
def update_lesson_name_in_document(self, section):
|
|
||||||
doctype_map= {
|
|
||||||
"Exercise": "Exercise",
|
|
||||||
"Quiz": "LMS Quiz"
|
|
||||||
}
|
|
||||||
macros = find_macros(self.body)
|
|
||||||
documents = [value for name, value in macros if name == section]
|
|
||||||
index = 1
|
|
||||||
for name in documents:
|
|
||||||
e = frappe.get_doc(doctype_map[section], name)
|
|
||||||
e.lesson = self.name
|
|
||||||
e.index_ = index
|
|
||||||
e.save()
|
|
||||||
index += 1
|
|
||||||
self.update_orphan_documents(doctype_map[section], documents)
|
|
||||||
|
|
||||||
def update_orphan_documents(self, doctype, documents):
|
|
||||||
"""Updates the documents that were previously part of this lesson,
|
|
||||||
but not any more.
|
|
||||||
"""
|
|
||||||
linked_documents = {row['name'] for row in frappe.get_all(doctype, {"lesson": self.name})}
|
|
||||||
active_documents = set(documents)
|
|
||||||
orphan_documents = linked_documents - active_documents
|
|
||||||
for name in orphan_documents:
|
|
||||||
ex = frappe.get_doc(doctype, name)
|
|
||||||
ex.lesson = None
|
|
||||||
ex.index_ = 0
|
|
||||||
ex.index_label = ""
|
|
||||||
ex.save()
|
|
||||||
|
|
||||||
def render_html(self):
|
|
||||||
return markdown_to_html(self.body)
|
|
||||||
|
|
||||||
def get_exercises(self):
|
|
||||||
if not self.body:
|
|
||||||
return []
|
|
||||||
|
|
||||||
macros = find_macros(self.body)
|
|
||||||
exercises = [value for name, value in macros if name == "Exercise"]
|
|
||||||
return [frappe.get_doc("Exercise", name) for name in exercises]
|
|
||||||
|
|
||||||
def get_progress(self):
|
|
||||||
return frappe.db.get_value("LMS Course Progress",
|
|
||||||
{"lesson": self.name, "owner": frappe.session.user}, "status")
|
|
||||||
|
|
||||||
def get_slugified_class(self):
|
|
||||||
if self.get_progress():
|
|
||||||
return ("").join([ s for s in self.get_progress().lower().split() ])
|
|
||||||
return
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
|
||||||
def save_progress(lesson, course, status):
|
|
||||||
if not frappe.db.exists("LMS Batch Membership",
|
|
||||||
{
|
|
||||||
"member": frappe.session.user,
|
|
||||||
"course": course
|
|
||||||
}):
|
|
||||||
return
|
|
||||||
|
|
||||||
if frappe.db.exists("LMS Course Progress",
|
|
||||||
{
|
|
||||||
"lesson": lesson,
|
|
||||||
"owner": frappe.session.user,
|
|
||||||
"course": course
|
|
||||||
}):
|
|
||||||
doc = frappe.get_doc("LMS Course Progress",
|
|
||||||
{
|
|
||||||
"lesson": lesson,
|
|
||||||
"owner": frappe.session.user,
|
|
||||||
"course": course
|
|
||||||
})
|
|
||||||
doc.status = status
|
|
||||||
doc.save(ignore_permissions=True)
|
|
||||||
else:
|
|
||||||
frappe.get_doc({
|
|
||||||
"doctype": "LMS Course Progress",
|
|
||||||
"lesson": lesson,
|
|
||||||
"status": status,
|
|
||||||
}).save(ignore_permissions=True)
|
|
||||||
course_details = frappe.get_doc("LMS Course", course)
|
|
||||||
return course_details.get_course_progress()
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2021, FOSS United and Contributors
|
|
||||||
# See license.txt
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
# import frappe
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
class TestLesson(unittest.TestCase):
|
|
||||||
pass
|
|
||||||
@@ -12,4 +12,9 @@ community.patches.v0_0.course_instructor_update
|
|||||||
execute:frappe.delete_doc("DocType", "Discussion Message")
|
execute:frappe.delete_doc("DocType", "Discussion Message")
|
||||||
execute:frappe.delete_doc("DocType", "Discussion Thread")
|
execute:frappe.delete_doc("DocType", "Discussion Thread")
|
||||||
community.patches.v0_0.rename_chapters_and_lessons_doctype
|
community.patches.v0_0.rename_chapters_and_lessons_doctype
|
||||||
community.patches.v0_0.rename_chapter_and_lesson_doctype #29-09-2021
|
execute:frappe.delete_doc("DocType", "Chapters")
|
||||||
|
execute:frappe.delete_doc("DocType", "Lessons")
|
||||||
|
execute:frappe.delete_doc("DocType", "Chapter")
|
||||||
|
execute:frappe.delete_doc("DocType", "Lesson")
|
||||||
|
execute:frappe.delete_doc("DocType", "LMS Topic")
|
||||||
|
community.patches.v0_0.rename_chapter_and_lesson_doctype #30-09-2021
|
||||||
|
|||||||
@@ -3,6 +3,14 @@ import frappe
|
|||||||
def execute():
|
def execute():
|
||||||
frappe.reload_doc("lms", "doctype", "course_chapter")
|
frappe.reload_doc("lms", "doctype", "course_chapter")
|
||||||
frappe.reload_doc("lms", "doctype", "course_lesson")
|
frappe.reload_doc("lms", "doctype", "course_lesson")
|
||||||
|
frappe.reload_doc("lms", "doctype", "chapter_reference")
|
||||||
|
frappe.reload_doc("lms", "doctype", "lesson_reference")
|
||||||
|
frappe.reload_doc("lms", "doctype", "exercise")
|
||||||
|
frappe.reload_doc("lms", "doctype", "exercise_submission")
|
||||||
|
frappe.reload_doc("lms", "doctype", "lms_batch_membership")
|
||||||
|
frappe.reload_doc("lms", "doctype", "lms_course")
|
||||||
|
frappe.reload_doc("lms", "doctype", "lms_course_progress")
|
||||||
|
frappe.reload_doc("lms", "doctype", "lms_quiz")
|
||||||
|
|
||||||
if not frappe.db.count("Course Chapter"):
|
if not frappe.db.count("Course Chapter"):
|
||||||
move_chapters()
|
move_chapters()
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ var mark_active_question = (e = undefined) => {
|
|||||||
var mark_progress = (e) => {
|
var mark_progress = (e) => {
|
||||||
var status = $(e.currentTarget).attr("data-progress");
|
var status = $(e.currentTarget).attr("data-progress");
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "community.lms.doctype.lesson.lesson.save_progress",
|
method: "community.lms.doctype.course_lesson.course_lesson.save_progress",
|
||||||
args: {
|
args: {
|
||||||
lesson: $(".title").attr("data-lesson"),
|
lesson: $(".title").attr("data-lesson"),
|
||||||
course: $(".title").attr("data-course"),
|
course: $(".title").attr("data-course"),
|
||||||
|
|||||||
@@ -9,14 +9,29 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="common-page-style">
|
<div class="common-page-style">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
|
{% if live_courses | length %}
|
||||||
<div class="courses-header">
|
<div class="courses-header">
|
||||||
{{ 'All Courses' }}
|
{{ _('Live Courses') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="cards-parent">
|
<div class="cards-parent">
|
||||||
{% for course in courses %}
|
{% for course in live_courses %}
|
||||||
{{ widgets.CourseCard(course=course, read_only=False) }}
|
{{ widgets.CourseCard(course=course, read_only=False) }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if upcoming_courses | length %}
|
||||||
|
<div class="courses-header mt-12">
|
||||||
|
{{ _('Upcoming Courses') }}
|
||||||
|
</div>
|
||||||
|
<div class="cards-parent">
|
||||||
|
{% for course in upcoming_courses %}
|
||||||
|
{{ widgets.CourseCard(course=course, read_only=False) }}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import frappe
|
|||||||
|
|
||||||
def get_context(context):
|
def get_context(context):
|
||||||
context.no_cache = 1
|
context.no_cache = 1
|
||||||
context.courses = get_courses()
|
context.live_courses, context.upcoming_courses = get_courses()
|
||||||
context.metatags = {
|
context.metatags = {
|
||||||
"title": "All Courses",
|
"title": "All Courses",
|
||||||
"image": frappe.db.get_single_value("Website Settings", "banner_image"),
|
"image": frappe.db.get_single_value("Website Settings", "banner_image"),
|
||||||
@@ -11,8 +11,14 @@ def get_context(context):
|
|||||||
}
|
}
|
||||||
|
|
||||||
def get_courses():
|
def get_courses():
|
||||||
course_names = frappe.get_all("LMS Course", filters={"is_published": True}, order_by="upcoming", pluck="name")
|
course_names = frappe.get_all("LMS Course",
|
||||||
courses = []
|
filters={"is_published": True},
|
||||||
|
fields=["name", "upcoming"])
|
||||||
|
|
||||||
|
live_courses, upcoming_courses = [], []
|
||||||
for course in course_names:
|
for course in course_names:
|
||||||
courses.append(frappe.get_doc("LMS Course", course))
|
if course.upcoming:
|
||||||
return courses
|
upcoming_courses.append(frappe.get_doc("LMS Course", course.name))
|
||||||
|
else:
|
||||||
|
live_courses.append(frappe.get_doc("LMS Course", course.name))
|
||||||
|
return live_courses, upcoming_courses
|
||||||
|
|||||||
Reference in New Issue
Block a user