blob: d68dee43c5328dc3d8007a5d4dab402e21a11bc5 [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):
113 try:
scmmishra73a31ec2018-11-03 19:31:53 +0530114 student = frappe.get_doc("Student", get_student_id(email))
115 return student.get_completed_courses()
116 except:
117 return None
scmmishra8b8db542018-11-03 18:03:24 +0530118
119@frappe.whitelist()
120def get_continue_data(program_name):
121 program = frappe.get_doc("Program", program_name)
122 courses = program.get_all_children()
123 continue_data = get_starting_content(courses[0].course)
124 continue_data['course'] = courses[0].course
125 return continue_data
126
127def create_student(student_name=frappe.session.user):
128 student = frappe.get_doc({
129 "doctype": "Student",
130 "first_name": student_name,
131 "student_email_id": student_name,
132 })
133 student.save()
134 frappe.db.commit()
135 return student_name
136
137@frappe.whitelist()
scmmishra73a31ec2018-11-03 19:31:53 +0530138def enroll_all_courses_in_program(program_enrollment, student):
139 course_list = [course.name for course in get_courses(program_enrollment.program)]
140 for course_name in course_list:
141 student.enroll_in_course(course_name=course_name, program_enrollment=program_enrollment.name)
142
143@frappe.whitelist()
144def enroll_in_program(program_name, student_email_id):
scmmishra8b8db542018-11-03 18:03:24 +0530145 if(not get_student_id(student_email_id)):
146 create_student(student_email_id)
147 student = frappe.get_doc("Student", get_student_id(student_email_id))
scmmishra73a31ec2018-11-03 19:31:53 +0530148 program_enrollment = student.enroll_in_program(program_name)
149 enroll_all_courses_in_program(program_enrollment, student)
scmmishra8b8db542018-11-03 18:03:24 +0530150
scmmishra73a31ec2018-11-03 19:31:53 +0530151@frappe.whitelist()
scmmishra8b8db542018-11-03 18:03:24 +0530152def get_student_id(email=None):
153 """Returns student user name, example EDU-STU-2018-00001 (Based on the naming series).
154
155 :param user: a user email address
156 """
157 try:
158 return frappe.get_all('Student', filters={'student_email_id': email}, fields=['name'])[0].name
159 except IndexError:
scmmishra73a31ec2018-11-03 19:31:53 +0530160 return None
161
162@frappe.whitelist()
163def get_program_enrollments(email=frappe.session.user):
164 try:
165 student = frappe.get_doc("Student", get_student_id(email))
166 return student.get_program_enrollments()
167 except:
168 return None
169
170@frappe.whitelist()
171def get_course_enrollments(email=frappe.session.user):
172 try:
173 student = frappe.get_doc("Student", get_student_id(email))
174 return student.get_course_enrollments()
175 except:
scmmishra1a04f772018-11-03 20:43:59 +0530176 return None
177
178@frappe.whitelist()
179def add_activity(enrollment, content_type, content):
scmmishra76222f72018-11-05 11:02:14 +0530180 if(check_activity_exists(enrollment, content_type, content)):
181 pass
182 else:
183 activity = frappe.get_doc({
184 "doctype": "Course Activity",
185 "enrollment": enrollment,
186 "content_type": content_type,
187 "content": content,
188 "activity_date": frappe.utils.datetime.datetime.now()
189 })
190 activity.save()
191 frappe.db.commit()
192
193def check_activity_exists(enrollment, content_type, content):
194 activity = frappe.get_all("Course Activity", filters={'enrollment': enrollment, 'content_type': content_type, 'content': content})
scmmishra0187b182018-11-05 12:16:02 +0530195 return bool(activity)
scmmishra76222f72018-11-05 11:02:14 +0530196
scmmishra0187b182018-11-05 12:16:02 +0530197def add_quiz_activity(enrollment, quiz_name, result_data, score, status):
198 quiz_activity = frappe.get_doc({
199 "doctype": "Quiz Activity",
200 "enrollment": enrollment,
201 "quiz": quiz_name,
202 "result": result_data,
203 "score": score,
204 "status": status
205 })
206 quiz_activity.save()
scmmishra25e42ba2018-11-05 13:11:37 +0530207 frappe.db.commit()
208
209@frappe.whitelist()
210def mark_course_complete(enrollment):
211 course_enrollment = frappe.get_doc("Course Enrollment", enrollment)
212 course_enrollment.completed = True
213 course_enrollment.save()
214 frappe.db.commit()