blob: 94a0a71687764e3da2748eaa27e74c2ed320b78c [file] [log] [blame]
scmmishra1778b592018-10-30 18:25:49 +05301from __future__ import unicode_literals
2import frappe
scmmishra1778b592018-10-30 18:25:49 +05303
scmmishra9c642ac2018-11-01 17:17:49 +05304# Functions to get homepage details
scmmishrabcafe842018-11-03 14:48:42 +05305@frappe.whitelist(allow_guest=True)
scmmishra1778b592018-10-30 18:25:49 +05306def get_portal_details():
7 settings = frappe.get_doc("Education Settings")
8 title = settings.portal_title
9 description = settings.description
10 return dict(title=title, description=description)
11
scmmishrabcafe842018-11-03 14:48:42 +053012@frappe.whitelist(allow_guest=True)
scmmishra1778b592018-10-30 18:25:49 +053013def get_featured_programs():
scmmishrabcafe842018-11-03 14:48:42 +053014 featured_program_names = frappe.get_all("Program", filters={"is_published": True, "is_featured": True})
scmmishra1778b592018-10-30 18:25:49 +053015 featured_list = [program["name"] for program in featured_program_names]
16 if featured_list:
17 return featured_list
18 else:
19 return None
20
scmmishra9c642ac2018-11-01 17:17:49 +053021# Functions to get program & course details
scmmishrabcafe842018-11-03 14:48:42 +053022@frappe.whitelist(allow_guest=True)
scmmishra1778b592018-10-30 18:25:49 +053023def get_program_details(program_name):
24 try:
25 program = frappe.get_doc('Program', program_name)
26 return program
27 except:
28 return None
scmmishra9c642ac2018-11-01 17:17:49 +053029
scmmishrabcafe842018-11-03 14:48:42 +053030@frappe.whitelist(allow_guest=True)
scmmishra9c642ac2018-11-01 17:17:49 +053031def get_courses(program_name):
32 program = frappe.get_doc('Program', program_name)
33 courses = program.get_course_list()
34 return courses
35
36@frappe.whitelist()
37def get_starting_content(course_name):
38 course = frappe.get_doc('Course', course_name)
39 content = course.course_content[0].content
40 content_type = course.course_content[0].content_type
41 return dict(content=content, content_type=content_type)
42
43
44# Functions to get content details
45@frappe.whitelist()
46def get_content(content_name, content_type):
47 try:
48 content = frappe.get_doc(content_type, content_name)
49 return content
50 except:
51 frappe.throw("{0} with name {1} does not exist".format(content_type, content_name))
52 return None
53
54@frappe.whitelist()
55def get_next_content(content, content_type, course):
56 course_doc = frappe.get_doc("Course", course)
57 content_list = [{'content_type':item.content_type, 'content':item.content} for item in course_doc.get_all_children()]
58 current_index = content_list.index({'content': content, 'content_type': content_type})
59 try:
60 return content_list[current_index + 1]
61 except IndexError:
scmmishra37418442018-11-01 19:50:47 +053062 return None
63
64def get_quiz_with_answers(quiz_name):
65 try:
66 quiz = frappe.get_doc("Quiz", quiz_name).get_questions()
67 quiz_output = [{'name':question.name, 'question':question.question, 'options':[{'name': option.name, 'option':option.option, 'is_correct':option.is_correct} for option in question.options]} for question in quiz]
68 return quiz_output
69 except:
70 frappe.throw("Quiz {0} does not exist".format(quiz_name))
71 return None
72
73@frappe.whitelist()
74def get_quiz_without_answers(quiz_name):
75 try:
76 quiz = frappe.get_doc("Quiz", quiz_name).get_questions()
77 quiz_output = [{'name':question.name, 'question':question.question, 'options':[{'name': option.name, 'option':option.option} for option in question.options]} for question in quiz]
78 return quiz_output
79 except:
80 frappe.throw("Quiz {0} does not exist".format(quiz_name))
scmmishraf7029f02018-11-02 13:15:49 +053081 return None
82
83@frappe.whitelist()
scmmishra0187b182018-11-05 12:16:02 +053084def evaluate_quiz(enrollment, quiz_response, quiz_name):
scmmishraef9a75e2018-11-02 16:35:46 +053085 """LMS Function: Evaluates a simple multiple choice quiz.
scmmishraf7029f02018-11-02 13:15:49 +053086
87
88 :param quiz_response: contains user selected choices for a quiz in the form of a string formatted as a dictionary. The function uses `json.loads()` to convert it to a python dictionary.
scmmishraf7029f02018-11-02 13:15:49 +053089 """
90 import json
scmmishraf7029f02018-11-02 13:15:49 +053091 quiz_response = json.loads(quiz_response)
scmmishraef9a75e2018-11-02 16:35:46 +053092 quiz = frappe.get_doc("Quiz", quiz_name)
scmmishra0187b182018-11-05 12:16:02 +053093 answers, score, status = quiz.evaluate(quiz_response, quiz_name)
scmmishra0187b182018-11-05 12:16:02 +053094
95 result = {k: ('Correct' if v else 'Wrong') for k,v in answers.items()}
96 result_data = []
97 for key in answers:
98 item = {}
99 item['question'] = key
100 item['quiz_result'] = result[key]
101 try:
102 item['selected_option'] = frappe.get_value('Options', quiz_response[key], 'option')
103 except:
104 item['selected_option'] = "Unattempted"
105 result_data.append(item)
106 # result_data = [{'question': key, 'selected_option': frappe.get_value('Options', quiz_response[key], 'option'), 'quiz_result': result[key]} for key in answers]
107
108 add_quiz_activity(enrollment, quiz_name, result_data, score, status)
scmmishraef9a75e2018-11-02 16:35:46 +0530109 return(score)
scmmishrabcafe842018-11-03 14:48:42 +0530110
111@frappe.whitelist()
scmmishra73a31ec2018-11-03 19:31:53 +0530112def get_completed_courses(email=frappe.session.user):
scmmishrab409f7a2018-11-07 22:12:55 +0530113 if get_student_id(email) == None:
114 return None
scmmishra73a31ec2018-11-03 19:31:53 +0530115 try:
scmmishra73a31ec2018-11-03 19:31:53 +0530116 student = frappe.get_doc("Student", get_student_id(email))
117 return student.get_completed_courses()
118 except:
119 return None
scmmishra8b8db542018-11-03 18:03:24 +0530120
121@frappe.whitelist()
122def get_continue_data(program_name):
123 program = frappe.get_doc("Program", program_name)
124 courses = program.get_all_children()
scmmishra8fa9ade2018-11-08 13:01:55 +0530125 try:
126 continue_data = get_starting_content(courses[0].course)
127 continue_data['course'] = courses[0].course
128 return continue_data
129 except:
130 return None
scmmishra8b8db542018-11-03 18:03:24 +0530131
132def create_student(student_name=frappe.session.user):
133 student = frappe.get_doc({
134 "doctype": "Student",
135 "first_name": student_name,
136 "student_email_id": student_name,
137 })
scmmishra8fa9ade2018-11-08 13:01:55 +0530138 student.save(ignore_permissions=True)
scmmishra8b8db542018-11-03 18:03:24 +0530139 frappe.db.commit()
140 return student_name
141
142@frappe.whitelist()
scmmishra73a31ec2018-11-03 19:31:53 +0530143def enroll_all_courses_in_program(program_enrollment, student):
144 course_list = [course.name for course in get_courses(program_enrollment.program)]
145 for course_name in course_list:
146 student.enroll_in_course(course_name=course_name, program_enrollment=program_enrollment.name)
147
148@frappe.whitelist()
149def enroll_in_program(program_name, student_email_id):
scmmishra8b8db542018-11-03 18:03:24 +0530150 if(not get_student_id(student_email_id)):
151 create_student(student_email_id)
152 student = frappe.get_doc("Student", get_student_id(student_email_id))
scmmishra73a31ec2018-11-03 19:31:53 +0530153 program_enrollment = student.enroll_in_program(program_name)
154 enroll_all_courses_in_program(program_enrollment, student)
scmmishra8b8db542018-11-03 18:03:24 +0530155
scmmishra73a31ec2018-11-03 19:31:53 +0530156@frappe.whitelist()
scmmishra8b8db542018-11-03 18:03:24 +0530157def get_student_id(email=None):
158 """Returns student user name, example EDU-STU-2018-00001 (Based on the naming series).
159
160 :param user: a user email address
161 """
162 try:
scmmishra8fa9ade2018-11-08 13:01:55 +0530163 student_id = frappe.db.get_all("Student", {"student_email_id": email}, ["name"])[0].name
164 return student_id
scmmishra8b8db542018-11-03 18:03:24 +0530165 except IndexError:
scmmishra73a31ec2018-11-03 19:31:53 +0530166 return None
167
168@frappe.whitelist()
169def get_program_enrollments(email=frappe.session.user):
scmmishrab409f7a2018-11-07 22:12:55 +0530170 if get_student_id(email) == None:
171 return None
scmmishra73a31ec2018-11-03 19:31:53 +0530172 try:
173 student = frappe.get_doc("Student", get_student_id(email))
174 return student.get_program_enrollments()
175 except:
176 return None
177
178@frappe.whitelist()
179def get_course_enrollments(email=frappe.session.user):
scmmishrab409f7a2018-11-07 22:12:55 +0530180 if get_student_id(email) == None:
181 return None
scmmishra73a31ec2018-11-03 19:31:53 +0530182 try:
183 student = frappe.get_doc("Student", get_student_id(email))
184 return student.get_course_enrollments()
185 except:
scmmishra1a04f772018-11-03 20:43:59 +0530186 return None
187
188@frappe.whitelist()
189def add_activity(enrollment, content_type, content):
scmmishra76222f72018-11-05 11:02:14 +0530190 if(check_activity_exists(enrollment, content_type, content)):
191 pass
192 else:
193 activity = frappe.get_doc({
194 "doctype": "Course Activity",
195 "enrollment": enrollment,
196 "content_type": content_type,
197 "content": content,
198 "activity_date": frappe.utils.datetime.datetime.now()
199 })
200 activity.save()
201 frappe.db.commit()
202
203def check_activity_exists(enrollment, content_type, content):
204 activity = frappe.get_all("Course Activity", filters={'enrollment': enrollment, 'content_type': content_type, 'content': content})
scmmishra0187b182018-11-05 12:16:02 +0530205 return bool(activity)
scmmishra76222f72018-11-05 11:02:14 +0530206
scmmishra0187b182018-11-05 12:16:02 +0530207def add_quiz_activity(enrollment, quiz_name, result_data, score, status):
208 quiz_activity = frappe.get_doc({
209 "doctype": "Quiz Activity",
210 "enrollment": enrollment,
211 "quiz": quiz_name,
212 "result": result_data,
213 "score": score,
214 "status": status
215 })
216 quiz_activity.save()
scmmishra25e42ba2018-11-05 13:11:37 +0530217 frappe.db.commit()
218
219@frappe.whitelist()
220def mark_course_complete(enrollment):
221 course_enrollment = frappe.get_doc("Course Enrollment", enrollment)
222 course_enrollment.completed = True
223 course_enrollment.save()
224 frappe.db.commit()