From 1cb81de5c0d35303f7f688f9027ef737dc0e8591 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Wed, 9 Jun 2021 13:17:42 +0530 Subject: [PATCH] feat: lms quizzes --- community/lms/api.py | 2 +- community/lms/doctype/lesson/lesson.json | 4 +- community/lms/doctype/lms_option/__init__.py | 0 .../lms/doctype/lms_option/lms_option.json | 36 ++++++++++ .../lms/doctype/lms_option/lms_option.py | 8 +++ community/lms/doctype/lms_quiz/__init__.py | 0 community/lms/doctype/lms_quiz/lms_quiz.js | 8 +++ community/lms/doctype/lms_quiz/lms_quiz.json | 50 ++++++++++++++ community/lms/doctype/lms_quiz/lms_quiz.py | 36 ++++++++++ .../lms/doctype/lms_quiz/test_lms_quiz.py | 8 +++ .../lms/doctype/lms_quiz_question/__init__.py | 0 .../lms_quiz_question/lms_quiz_question.json | 52 ++++++++++++++ .../lms_quiz_question/lms_quiz_question.py | 8 +++ .../doctype/lms_quiz_questions/__init__.py | 0 .../lms_quiz_questions.json | 43 ++++++++++++ .../lms_quiz_questions/lms_quiz_questions.py | 8 +++ .../lms/doctype/lms_quiz_result/__init__.py | 0 .../lms_quiz_result/lms_quiz_result.json | 45 +++++++++++++ .../lms_quiz_result/lms_quiz_result.py | 8 +++ .../doctype/lms_quiz_submission/__init__.py | 0 .../lms_quiz_submission.js | 8 +++ .../lms_quiz_submission.json | 55 +++++++++++++++ .../lms_quiz_submission.py | 8 +++ .../test_lms_quiz_submission.py | 8 +++ .../lms/doctype/lms_section/lms_section.py | 4 ++ community/lms/widgets/Quiz.html | 67 +++++++++++++++++++ community/public/css/style.css | 5 ++ community/www/batch/learn.html | 2 + 28 files changed, 470 insertions(+), 3 deletions(-) create mode 100644 community/lms/doctype/lms_option/__init__.py create mode 100644 community/lms/doctype/lms_option/lms_option.json create mode 100644 community/lms/doctype/lms_option/lms_option.py create mode 100644 community/lms/doctype/lms_quiz/__init__.py create mode 100644 community/lms/doctype/lms_quiz/lms_quiz.js create mode 100644 community/lms/doctype/lms_quiz/lms_quiz.json create mode 100644 community/lms/doctype/lms_quiz/lms_quiz.py create mode 100644 community/lms/doctype/lms_quiz/test_lms_quiz.py create mode 100644 community/lms/doctype/lms_quiz_question/__init__.py create mode 100644 community/lms/doctype/lms_quiz_question/lms_quiz_question.json create mode 100644 community/lms/doctype/lms_quiz_question/lms_quiz_question.py create mode 100644 community/lms/doctype/lms_quiz_questions/__init__.py create mode 100644 community/lms/doctype/lms_quiz_questions/lms_quiz_questions.json create mode 100644 community/lms/doctype/lms_quiz_questions/lms_quiz_questions.py create mode 100644 community/lms/doctype/lms_quiz_result/__init__.py create mode 100644 community/lms/doctype/lms_quiz_result/lms_quiz_result.json create mode 100644 community/lms/doctype/lms_quiz_result/lms_quiz_result.py create mode 100644 community/lms/doctype/lms_quiz_submission/__init__.py create mode 100644 community/lms/doctype/lms_quiz_submission/lms_quiz_submission.js create mode 100644 community/lms/doctype/lms_quiz_submission/lms_quiz_submission.json create mode 100644 community/lms/doctype/lms_quiz_submission/lms_quiz_submission.py create mode 100644 community/lms/doctype/lms_quiz_submission/test_lms_quiz_submission.py create mode 100644 community/lms/widgets/Quiz.html diff --git a/community/lms/api.py b/community/lms/api.py index 9cf2fc9d..1ed198e1 100644 --- a/community/lms/api.py +++ b/community/lms/api.py @@ -43,7 +43,7 @@ def save_current_lesson(batch_name, lesson_name): doctype="LMS Batch Membership", filters={ "batch": batch_name, - "member_email": frappe.session.user + "member": frappe.session.user }, fieldname="name") if not name: diff --git a/community/lms/doctype/lesson/lesson.json b/community/lms/doctype/lesson/lesson.json index 4772b255..6416db9a 100644 --- a/community/lms/doctype/lesson/lesson.json +++ b/community/lms/doctype/lesson/lesson.json @@ -40,6 +40,7 @@ "default": "1", "fieldname": "index_", "fieldtype": "Int", + "in_list_view": 1, "label": "Index" }, { @@ -56,14 +57,13 @@ { "fieldname": "index_label", "fieldtype": "Data", - "in_list_view": 1, "label": "Index Label", "read_only": 1 } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2021-06-01 05:30:48.127494", + "modified": "2021-06-07 11:58:13.395438", "modified_by": "Administrator", "module": "LMS", "name": "Lesson", diff --git a/community/lms/doctype/lms_option/__init__.py b/community/lms/doctype/lms_option/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/lms/doctype/lms_option/lms_option.json b/community/lms/doctype/lms_option/lms_option.json new file mode 100644 index 00000000..eee21142 --- /dev/null +++ b/community/lms/doctype/lms_option/lms_option.json @@ -0,0 +1,36 @@ +{ + "actions": [], + "creation": "2021-06-07 10:46:10.402684", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "option", + "is_correct" + ], + "fields": [ + { + "fieldname": "option", + "fieldtype": "Data", + "label": "Option" + }, + { + "default": "0", + "fieldname": "is_correct", + "fieldtype": "Check", + "label": "Is Correct" + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2021-06-07 10:48:45.290227", + "modified_by": "Administrator", + "module": "LMS", + "name": "LMS Option", + "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_option/lms_option.py b/community/lms/doctype/lms_option/lms_option.py new file mode 100644 index 00000000..d64d78b5 --- /dev/null +++ b/community/lms/doctype/lms_option/lms_option.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, FOSS United and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + +class LMSOption(Document): + pass diff --git a/community/lms/doctype/lms_quiz/__init__.py b/community/lms/doctype/lms_quiz/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/lms/doctype/lms_quiz/lms_quiz.js b/community/lms/doctype/lms_quiz/lms_quiz.js new file mode 100644 index 00000000..5f8fa5d3 --- /dev/null +++ b/community/lms/doctype/lms_quiz/lms_quiz.js @@ -0,0 +1,8 @@ +// Copyright (c) 2021, FOSS United and contributors +// For license information, please see license.txt + +frappe.ui.form.on('LMS Quiz', { + // refresh: function(frm) { + + // } +}); diff --git a/community/lms/doctype/lms_quiz/lms_quiz.json b/community/lms/doctype/lms_quiz/lms_quiz.json new file mode 100644 index 00000000..3eb1222d --- /dev/null +++ b/community/lms/doctype/lms_quiz/lms_quiz.json @@ -0,0 +1,50 @@ +{ + "actions": [], + "autoname": "field:title", + "creation": "2021-06-07 10:50:17.893625", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "title", + "questions" + ], + "fields": [ + { + "fieldname": "title", + "fieldtype": "Data", + "label": "Title", + "unique": 1 + }, + { + "fieldname": "questions", + "fieldtype": "Table", + "label": "Questions", + "options": "LMS Quiz Question" + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2021-06-07 12:22:37.333289", + "modified_by": "Administrator", + "module": "LMS", + "name": "LMS Quiz", + "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 +} \ No newline at end of file diff --git a/community/lms/doctype/lms_quiz/lms_quiz.py b/community/lms/doctype/lms_quiz/lms_quiz.py new file mode 100644 index 00000000..2d24280d --- /dev/null +++ b/community/lms/doctype/lms_quiz/lms_quiz.py @@ -0,0 +1,36 @@ +# Copyright (c) 2021, FOSS United and contributors +# For license information, please see license.txt + +import frappe +from frappe.model.document import Document +import json + +class LMSQuiz(Document): + pass + +@frappe.whitelist() +def submit(quiz, result): + score = 0 + result = json.loads(result) + quiz_details = frappe.get_doc("LMS Quiz", quiz) + print(result, type(result)) + for response in result: + match = list(filter(lambda x: x.question == response.get("question"), quiz_details.questions))[0] + response["users_response"] = ("").join([ ans for ans in response.get("answer") ]).replace(" ", ", ") + del response["answer"] + print(response.get("users_response"), match.answer) + if response.get("users_response") == match.answer: + response["result"] = "Right" + score += 1 + else: + response["result"] = "Wrong" + + frappe.get_doc({ + "doctype": "LMS Quiz Submission", + "quiz": quiz, + "result": result, + "score": score + }).save() + return score + + diff --git a/community/lms/doctype/lms_quiz/test_lms_quiz.py b/community/lms/doctype/lms_quiz/test_lms_quiz.py new file mode 100644 index 00000000..e2df8fda --- /dev/null +++ b/community/lms/doctype/lms_quiz/test_lms_quiz.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, FOSS United and Contributors +# See license.txt + +# import frappe +import unittest + +class TestLMSQuiz(unittest.TestCase): + pass diff --git a/community/lms/doctype/lms_quiz_question/__init__.py b/community/lms/doctype/lms_quiz_question/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/lms/doctype/lms_quiz_question/lms_quiz_question.json b/community/lms/doctype/lms_quiz_question/lms_quiz_question.json new file mode 100644 index 00000000..d861b138 --- /dev/null +++ b/community/lms/doctype/lms_quiz_question/lms_quiz_question.json @@ -0,0 +1,52 @@ +{ + "actions": [], + "creation": "2021-06-07 10:48:57.994714", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "question", + "options", + "answer", + "multiple_correct_answers" + ], + "fields": [ + { + "fieldname": "question", + "fieldtype": "Text", + "in_list_view": 1, + "label": "Question" + }, + { + "fieldname": "options", + "fieldtype": "Text", + "in_list_view": 1, + "label": "Options" + }, + { + "default": "0", + "fieldname": "multiple_correct_answers", + "fieldtype": "Check", + "in_list_view": 1, + "label": "Multiple Correct Answers" + }, + { + "fieldname": "answer", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Answer" + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2021-06-07 12:47:22.787160", + "modified_by": "Administrator", + "module": "LMS", + "name": "LMS Quiz Question", + "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_quiz_question/lms_quiz_question.py b/community/lms/doctype/lms_quiz_question/lms_quiz_question.py new file mode 100644 index 00000000..0435197b --- /dev/null +++ b/community/lms/doctype/lms_quiz_question/lms_quiz_question.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, FOSS United and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + +class LMSQuizQuestion(Document): + pass diff --git a/community/lms/doctype/lms_quiz_questions/__init__.py b/community/lms/doctype/lms_quiz_questions/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/lms/doctype/lms_quiz_questions/lms_quiz_questions.json b/community/lms/doctype/lms_quiz_questions/lms_quiz_questions.json new file mode 100644 index 00000000..4e147664 --- /dev/null +++ b/community/lms/doctype/lms_quiz_questions/lms_quiz_questions.json @@ -0,0 +1,43 @@ +{ + "actions": [], + "creation": "2021-06-07 10:48:57.994714", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "question", + "options", + "multiple_correct_answers" + ], + "fields": [ + { + "fieldname": "question", + "fieldtype": "Data", + "label": "Question" + }, + { + "fieldname": "options", + "fieldtype": "Table", + "label": "Options", + "options": "LMS Option" + }, + { + "default": "0", + "fieldname": "multiple_correct_answers", + "fieldtype": "Check", + "label": "Multiple Correct Answers" + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2021-06-07 10:48:57.994714", + "modified_by": "Administrator", + "module": "LMS", + "name": "LMS Quiz Questions", + "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_quiz_questions/lms_quiz_questions.py b/community/lms/doctype/lms_quiz_questions/lms_quiz_questions.py new file mode 100644 index 00000000..f1d7948e --- /dev/null +++ b/community/lms/doctype/lms_quiz_questions/lms_quiz_questions.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, FOSS United and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + +class LMSQuizQuestions(Document): + pass diff --git a/community/lms/doctype/lms_quiz_result/__init__.py b/community/lms/doctype/lms_quiz_result/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/lms/doctype/lms_quiz_result/lms_quiz_result.json b/community/lms/doctype/lms_quiz_result/lms_quiz_result.json new file mode 100644 index 00000000..12346e2f --- /dev/null +++ b/community/lms/doctype/lms_quiz_result/lms_quiz_result.json @@ -0,0 +1,45 @@ +{ + "actions": [], + "creation": "2021-06-07 14:19:23.683323", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "question", + "users_response", + "result" + ], + "fields": [ + { + "fieldname": "question", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Question" + }, + { + "fieldname": "users_response", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Users Response" + }, + { + "fieldname": "result", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Result", + "options": "Right\nWrong" + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2021-06-07 14:21:07.768039", + "modified_by": "Administrator", + "module": "LMS", + "name": "LMS Quiz Result", + "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_quiz_result/lms_quiz_result.py b/community/lms/doctype/lms_quiz_result/lms_quiz_result.py new file mode 100644 index 00000000..cfe9a9de --- /dev/null +++ b/community/lms/doctype/lms_quiz_result/lms_quiz_result.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, FOSS United and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + +class LMSQuizResult(Document): + pass diff --git a/community/lms/doctype/lms_quiz_submission/__init__.py b/community/lms/doctype/lms_quiz_submission/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/lms/doctype/lms_quiz_submission/lms_quiz_submission.js b/community/lms/doctype/lms_quiz_submission/lms_quiz_submission.js new file mode 100644 index 00000000..b4b0c176 --- /dev/null +++ b/community/lms/doctype/lms_quiz_submission/lms_quiz_submission.js @@ -0,0 +1,8 @@ +// Copyright (c) 2021, FOSS United and contributors +// For license information, please see license.txt + +frappe.ui.form.on('LMS Quiz Submission', { + // refresh: function(frm) { + + // } +}); diff --git a/community/lms/doctype/lms_quiz_submission/lms_quiz_submission.json b/community/lms/doctype/lms_quiz_submission/lms_quiz_submission.json new file mode 100644 index 00000000..63cd97ef --- /dev/null +++ b/community/lms/doctype/lms_quiz_submission/lms_quiz_submission.json @@ -0,0 +1,55 @@ +{ + "actions": [], + "creation": "2021-06-07 14:19:54.958989", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "quiz", + "result", + "score" + ], + "fields": [ + { + "fieldname": "quiz", + "fieldtype": "Link", + "label": "Quiz", + "options": "LMS Quiz" + }, + { + "fieldname": "result", + "fieldtype": "Table", + "label": "Result", + "options": "LMS Quiz Result" + }, + { + "fieldname": "score", + "fieldtype": "Data", + "label": "Score" + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2021-06-07 14:19:54.958989", + "modified_by": "Administrator", + "module": "LMS", + "name": "LMS Quiz Submission", + "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 +} \ No newline at end of file diff --git a/community/lms/doctype/lms_quiz_submission/lms_quiz_submission.py b/community/lms/doctype/lms_quiz_submission/lms_quiz_submission.py new file mode 100644 index 00000000..3d1e29c7 --- /dev/null +++ b/community/lms/doctype/lms_quiz_submission/lms_quiz_submission.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, FOSS United and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + +class LMSQuizSubmission(Document): + pass diff --git a/community/lms/doctype/lms_quiz_submission/test_lms_quiz_submission.py b/community/lms/doctype/lms_quiz_submission/test_lms_quiz_submission.py new file mode 100644 index 00000000..eddd8df4 --- /dev/null +++ b/community/lms/doctype/lms_quiz_submission/test_lms_quiz_submission.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, FOSS United and Contributors +# See license.txt + +# import frappe +import unittest + +class TestLMSQuizSubmission(unittest.TestCase): + pass diff --git a/community/lms/doctype/lms_section/lms_section.py b/community/lms/doctype/lms_section/lms_section.py index 65c33f46..a40f86c5 100644 --- a/community/lms/doctype/lms_section/lms_section.py +++ b/community/lms/doctype/lms_section/lms_section.py @@ -14,6 +14,10 @@ class LMSSection(Document): if self.type == "exercise": return frappe.get_doc("Exercise", self.id) + def get_quiz(self): + if self.type == "quiz": + return frappe.get_doc("LMS Quiz", self.id) + def get_latest_code_for_user(self): """Returns the latest code for the logged in user. """ diff --git a/community/lms/widgets/Quiz.html b/community/lms/widgets/Quiz.html new file mode 100644 index 00000000..683b0b51 --- /dev/null +++ b/community/lms/widgets/Quiz.html @@ -0,0 +1,67 @@ +

{{ quiz.title }}

+
+ {% for question in quiz.questions %} +
+

{{ loop.index }}. {{ question.question }}

+ {% set options = question.options.split(",") %} + {% for option in options %} +
+ + {{ option }} +
+ {% endfor %} +
+ {% endfor %} + + +

+
+
+ diff --git a/community/public/css/style.css b/community/public/css/style.css index 60eb4ed2..cbc796fc 100644 --- a/community/public/css/style.css +++ b/community/public/css/style.css @@ -23,6 +23,7 @@ --cta-color: var(--c4); --send-message: var(--c7); --received-message: var(--c8); + --checkbox-size: 14px; } body { @@ -238,3 +239,7 @@ section { .page-card .btn { margin-top: 30px; } + +input[type=checkbox] { + appearance: auto; +} diff --git a/community/www/batch/learn.html b/community/www/batch/learn.html index 36136ddb..24d5c6cc 100644 --- a/community/www/batch/learn.html +++ b/community/www/batch/learn.html @@ -53,6 +53,8 @@ }} {% elif s.type == "exercise" %} {{ widgets.Exercise(exercise=s.get_exercise())}} +{% elif s.type == "quiz" %} +{{ widgets.Quiz(quiz=s.get_quiz())}} {% else %}
Unknown section type: {{s.type}}
{% endif %}