fix: conflicts
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_rename": 1,
|
||||
"autoname": "format:{####} {title}",
|
||||
"creation": "2021-05-03 05:49:08.383057",
|
||||
"doctype": "DocType",
|
||||
@@ -38,7 +39,7 @@
|
||||
"fieldname": "lessons",
|
||||
"fieldtype": "Table",
|
||||
"label": "Lessons",
|
||||
"options": "Lessons"
|
||||
"options": "Lesson Reference"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_3",
|
||||
@@ -57,10 +58,11 @@
|
||||
"link_fieldname": "chapter"
|
||||
}
|
||||
],
|
||||
"modified": "2021-08-31 10:43:45.866864",
|
||||
"modified": "2021-09-20 10:58:47.241660",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "Chapter",
|
||||
"naming_rule": "Expression",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"modified": "2021-07-27 16:25:02.903245",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "Chapters",
|
||||
"name": "Chapter Reference",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
@@ -4,5 +4,5 @@
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class Lessons(Document):
|
||||
class ChapterReference(Document):
|
||||
pass
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_rename": 1,
|
||||
"autoname": "format:{####} {title}",
|
||||
"creation": "2021-05-03 06:21:12.995987",
|
||||
"doctype": "DocType",
|
||||
@@ -70,10 +71,11 @@
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2021-08-31 10:44:14.168257",
|
||||
"modified": "2021-09-20 10:52:29.116536",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "Lesson",
|
||||
"naming_rule": "Expression",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"modified": "2021-08-31 10:44:42.048232",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "Lessons",
|
||||
"name": "Lesson Reference",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"sort_field": "modified",
|
||||
@@ -4,5 +4,5 @@
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class Chapters(Document):
|
||||
class LessonReference(Document):
|
||||
pass
|
||||
@@ -100,7 +100,7 @@
|
||||
"fieldname": "chapters",
|
||||
"fieldtype": "Table",
|
||||
"label": "Chapters",
|
||||
"options": "Chapters"
|
||||
"options": "Chapter Reference"
|
||||
},
|
||||
{
|
||||
"fieldname": "instructor",
|
||||
@@ -160,9 +160,14 @@
|
||||
"group": "Mentors",
|
||||
"link_doctype": "LMS Course Mentor Mapping",
|
||||
"link_fieldname": "course"
|
||||
},
|
||||
{
|
||||
"group": "Interests",
|
||||
"link_doctype": "LMS Course Interest",
|
||||
"link_fieldname": "course"
|
||||
}
|
||||
],
|
||||
"modified": "2021-08-25 11:04:57.211898",
|
||||
"modified": "2021-09-20 12:00:18.325579",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Course",
|
||||
|
||||
@@ -176,7 +176,7 @@ class LMSCourse(Document):
|
||||
|
||||
def get_lesson_details(self, chapter):
|
||||
lessons = []
|
||||
lesson_list = frappe.get_all("Lessons", {"parent": chapter.name},
|
||||
lesson_list = frappe.get_all("Lesson Reference", {"parent": chapter.name},
|
||||
["lesson", "idx"], order_by="idx")
|
||||
for row in lesson_list:
|
||||
lesson_details = frappe.get_doc("Lesson", row.lesson)
|
||||
@@ -213,7 +213,7 @@ class LMSCourse(Document):
|
||||
def get_lesson_index(self, lesson_name):
|
||||
"""Returns the {chapter_index}.{lesson_index} for the lesson.
|
||||
"""
|
||||
lesson = frappe.db.get_value("Lessons", {"lesson": lesson_name}, ["idx", "parent"], as_dict=True)
|
||||
lesson = frappe.db.get_value("Lesson Reference", {"lesson": lesson_name}, ["idx", "parent"], as_dict=True)
|
||||
if not lesson:
|
||||
return None
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:title",
|
||||
"creation": "2021-06-07 10:50:17.893625",
|
||||
"doctype": "DocType",
|
||||
@@ -33,10 +34,11 @@
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2021-07-23 19:06:12.551633",
|
||||
"modified": "2021-09-20 10:44:15.930892",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Quiz",
|
||||
"naming_rule": "By fieldname",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
<div class="lesson-info {% if membership.current_lesson == lesson.name %} active-lesson {% endif %}">
|
||||
|
||||
{% if membership or lesson.include_in_preview or is_instructor %}
|
||||
{% if membership or lesson.include_in_preview %}
|
||||
<a class="lesson-links" href="{{ course.get_learn_url(lesson.number) }}{{course.query_parameter}}"
|
||||
data-course="{{ course.name }}">
|
||||
{{ lesson.title }}
|
||||
@@ -33,6 +33,15 @@
|
||||
|
||||
</a>
|
||||
|
||||
{% elif is_instructor and not lesson.include_in_preview %}
|
||||
<a class="lesson-links"
|
||||
title="This lesson is not available for preview but as an instructor you can access it."
|
||||
href="{{ course.get_learn_url(lesson.number) }}{{course.query_parameter}}"
|
||||
data-course="{{ course.name }}">
|
||||
{{ lesson.title }}
|
||||
<img class="ml-2" src="/assets/community/icons/lock.svg">
|
||||
</a>
|
||||
|
||||
{% else %}
|
||||
<div class="no-preview" title="This lesson is not available for preview">
|
||||
<div class="lesson-links">
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
{% if not course.upcoming %}
|
||||
<div class="reviews-parent">
|
||||
{% set reviews = course.get_reviews() %}
|
||||
{% if reviews | length or course.is_eligible_to_review(membership) %}
|
||||
<div class="mb-5">
|
||||
<span class="course-home-headings">Reviews</span>
|
||||
{% if course.is_eligible_to_review(membership) %}
|
||||
{% if course.is_eligible_to_review(membership) and reviews | length %}
|
||||
<span class="review-link button is-secondary pull-right">
|
||||
Write a review
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if reviews | length %}
|
||||
<div class="reviews-section">
|
||||
{% for review in reviews %}
|
||||
@@ -36,9 +35,20 @@
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% else %}
|
||||
<div class="common-card-style thread-card">
|
||||
<span class="text-center"> No Reviews <img src="/assets/community/icons/slash.svg"></span>
|
||||
<div class="w-25 text-center" style="margin: 0 auto;">
|
||||
<span class="font-weight-bold"> No Reviews </span>
|
||||
<div class="small">
|
||||
There are no reviews for this course.
|
||||
</div>
|
||||
{% if course.is_eligible_to_review(membership) %}
|
||||
<span class="review-link button is-secondary ml-auto mr-auto mt-3">
|
||||
Write a review
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -48,7 +58,7 @@
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<div class="course-home-headings modal-headings">Review</div>
|
||||
<div class="font-weight-bold">Write a Review</div>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
|
||||
@@ -18,6 +18,8 @@ class CustomUser(User):
|
||||
else:
|
||||
underscore_condition = ''
|
||||
|
||||
regex = re.compile('[@!#$%^&*()<>?/\|}{~:-]')
|
||||
|
||||
if self.is_new():
|
||||
if not self.username:
|
||||
self.username = self.get_username_from_first_name()
|
||||
@@ -25,7 +27,7 @@ class CustomUser(User):
|
||||
if self.username.find(" "):
|
||||
self.username.replace(" ", "")
|
||||
|
||||
if not re.match("^[A-Za-z0-9_]*$", self.username) or underscore_condition:
|
||||
if regex.search(self.username) or underscore_condition:
|
||||
self.username = self.remove_illegal_characters()
|
||||
|
||||
if len(self.username) < 4:
|
||||
@@ -38,8 +40,8 @@ class CustomUser(User):
|
||||
if not self.username:
|
||||
frappe.throw(_("Username already exists."))
|
||||
|
||||
if not re.match("^[A-Za-z0-9_]*$", self.username):
|
||||
frappe.throw(_("Username can only contain alphabets, numbers and unedrscore."))
|
||||
if regex.search(self.username):
|
||||
frappe.throw(_("Username can only contain alphabets, numbers and underscore."))
|
||||
|
||||
if underscore_condition:
|
||||
frappe.throw(_("First and Last character of username cannot be Underscore(_)."))
|
||||
|
||||
@@ -31,7 +31,7 @@ def get_profile_url_prefix():
|
||||
hooks = frappe.get_hooks("profile_url_prefix") or ["/users/"]
|
||||
return hooks[-1]
|
||||
|
||||
RE_USERNAME = re.compile("[a-zA-Z0-9_]{4,}")
|
||||
RE_INVALID_USERNAME = re.compile("[@!#$%^&*()<>?/\\|}{~:-]")
|
||||
|
||||
class ProfileRedirectPage(BaseRenderer):
|
||||
"""Renderer to redirect /profile_/foo to <profile_prefix>/foo.
|
||||
@@ -63,9 +63,8 @@ class ProfilePage(BaseRenderer):
|
||||
|
||||
# not a userpage?
|
||||
username = self.get_username()
|
||||
if not RE_USERNAME.match(username):
|
||||
if RE_INVALID_USERNAME.search(username):
|
||||
return False
|
||||
|
||||
# if there is prefix then we can allow all usernames
|
||||
if prefix:
|
||||
return True
|
||||
|
||||
@@ -11,3 +11,4 @@ execute:frappe.delete_doc("DocType", "LMS Message")
|
||||
community.patches.v0_0.course_instructor_update
|
||||
execute:frappe.delete_doc("DocType", "Discussion Message")
|
||||
execute:frappe.delete_doc("DocType", "Discussion Thread")
|
||||
community.patches.v0_0.rename_chapters_and_lessons_doctype
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
frappe.reload_doc("lms", "doctype", "lms_course")
|
||||
frappe.reload_doc("lms", "doctype", "chapter")
|
||||
frappe.reload_doc("lms", "doctype", "lesson")
|
||||
frappe.reload_doc("lms", "doctype", "chapter_reference")
|
||||
frappe.reload_doc("lms", "doctype", "lesson_reference")
|
||||
|
||||
if not frappe.db.count("Chapter Reference"):
|
||||
move_chapters()
|
||||
|
||||
if not frappe.db.count("Lesson Reference"):
|
||||
move_lessons()
|
||||
|
||||
def move_chapters():
|
||||
docs = frappe.get_all("Chapters", fields=["*"])
|
||||
for doc in docs:
|
||||
keys = doc
|
||||
keys.update({"doctype": "Chapter Reference"})
|
||||
del keys["name"]
|
||||
frappe.get_doc(keys).save()
|
||||
|
||||
def move_lessons():
|
||||
docs = frappe.get_all("Lessons", fields=["*"])
|
||||
for doc in docs:
|
||||
keys = doc
|
||||
keys.update({"doctype": "Lesson Reference"})
|
||||
del keys["name"]
|
||||
frappe.get_doc(keys).save()
|
||||
|
||||
|
||||
@@ -330,6 +330,11 @@ input[type=checkbox] {
|
||||
|
||||
.quiz-label {
|
||||
margin-bottom: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.quiz-label p {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.course-card-wide {
|
||||
@@ -519,7 +524,7 @@ input[type=checkbox] {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-bottom: 0.5rem;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.chapter-description {
|
||||
@@ -637,7 +642,7 @@ input[type=checkbox] {
|
||||
|
||||
.course-outline {
|
||||
flex-direction: column;
|
||||
padding: 16px 12px 16px;
|
||||
padding: 1rem 0.75rem 0;
|
||||
}
|
||||
|
||||
.lessons {
|
||||
@@ -881,8 +886,8 @@ input[type=checkbox] {
|
||||
|
||||
.question {
|
||||
flex-direction: column;
|
||||
width: 688px;
|
||||
margin: auto;
|
||||
width: 85%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.question p {
|
||||
@@ -919,6 +924,10 @@ input[type=checkbox] {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.lesson-content-card .alert-dismissible .close {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.course-content-parent {
|
||||
display: grid;
|
||||
grid-gap: 2rem;
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
data-correct="{{ question['is_correct_' + loop.index | string] }}" {% if question.multiple %}
|
||||
type="checkbox" {% else %} type="radio" name="{{ question.question | urlencode }}" {% endif %}>
|
||||
<img class="empty-checkbox mr-3" />
|
||||
<span class="label-area">{{ frappe.utils.md_to_html(option) }}</span>
|
||||
</label>
|
||||
<span class="label-area">{{ frappe.utils.md_to_html(option) }}</span>
|
||||
</div>
|
||||
|
||||
{% set explanation = question['explanation_' + loop.index | string] %}
|
||||
|
||||
@@ -45,11 +45,18 @@
|
||||
|
||||
|
||||
{% if membership or lesson.include_in_preview or is_instructor %}
|
||||
<div class="common-card-style lesson-content-card markdown-source">{{ lesson.render_html() }}</div>
|
||||
<div class="common-card-style lesson-content-card markdown-source">
|
||||
{% if is_instructor %}
|
||||
<small class="alert alert-secondary alert-dismissible">
|
||||
This lesson is not available for preview. As you are the Instructor of the course only you can see it.
|
||||
<a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>
|
||||
</small>
|
||||
{% endif %}
|
||||
{{ lesson.render_html() }}</div>
|
||||
{% else %}
|
||||
<div class="common-card-style lesson-content-card">
|
||||
<div class="w-25 text-center" style="margin: 0 auto;">
|
||||
<small>This lesson is not available for preview. Please join the course to access this lesson.</small>
|
||||
<small>This lesson is not available for preview. Please join the course to access it.</small>
|
||||
<a class="button is-primary ml-auto mr-auto mt-3" href="/courses/{{ course.name }}"> Start Learning </a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -169,7 +169,8 @@ var parse_options = () => {
|
||||
}
|
||||
|
||||
var add_icon = (element, icon) => {
|
||||
$(element).parent().empty().html(`<img class="mr-3" src="/assets/community/icons/${icon}.svg">`);
|
||||
var label = $(element).parent().find(".label-area p").text();
|
||||
$(element).parent().empty().html(`<img class="mr-3" src="/assets/community/icons/${icon}.svg"> ${label}`);
|
||||
}
|
||||
|
||||
var add_to_local_storage = (quiz_name, current_index, answer, is_correct) => {
|
||||
|
||||
@@ -11,7 +11,7 @@ def get_context(context):
|
||||
}
|
||||
|
||||
def get_courses():
|
||||
course_names = frappe.get_all("LMS Course", filters={"is_published": True}, pluck="name")
|
||||
course_names = frappe.get_all("LMS Course", filters={"is_published": True}, order_by="upcoming", pluck="name")
|
||||
courses = []
|
||||
for course in course_names:
|
||||
courses.append(frappe.get_doc("LMS Course", course))
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import frappe
|
||||
from community.page_renderers import get_profile_url_prefix
|
||||
from urllib.parse import urlencode
|
||||
|
||||
def get_context(context):
|
||||
context.no_cache = 1
|
||||
@@ -9,14 +10,13 @@ def get_context(context):
|
||||
except KeyError:
|
||||
username = frappe.db.get_value("User", frappe.session.user, ["username"])
|
||||
if username:
|
||||
frappe.local.flags.redirect_location = get_profile_url_prefix() + username
|
||||
frappe.local.flags.redirect_location = get_profile_url_prefix() + urlencode({"username": username})
|
||||
raise frappe.Redirect
|
||||
try:
|
||||
context.member = frappe.get_doc("User", {"username": username})
|
||||
except:
|
||||
context.template = "www/404.html"
|
||||
return
|
||||
|
||||
context.profile_tabs = get_profile_tabs(context.member)
|
||||
|
||||
def get_profile_tabs(user):
|
||||
|
||||
Reference in New Issue
Block a user