blob: 4aec61488ad363a3dc17ccd818115511f8403149 [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()
125 continue_data = get_starting_content(courses[0].course)
126 continue_data['course'] = courses[0].course
127 return continue_data
128
129def create_student(student_name=frappe.session.user):
130 student = frappe.get_doc({
131 "doctype": "Student",
132 "first_name": student_name,
133 "student_email_id": student_name,
134 })
135 student.save()
136 frappe.db.commit()
137 return student_name
138
139@frappe.whitelist()
scmmishra73a31ec2018-11-03 19:31:53 +0530140def enroll_all_courses_in_program(program_enrollment, student):
141 course_list = [course.name for course in get_courses(program_enrollment.program)]
142 for course_name in course_list:
143 student.enroll_in_course(course_name=course_name, program_enrollment=program_enrollment.name)
144
145@frappe.whitelist()
146def enroll_in_program(program_name, student_email_id):
scmmishra8b8db542018-11-03 18:03:24 +0530147 if(not get_student_id(student_email_id)):
148 create_student(student_email_id)
149 student = frappe.get_doc("Student", get_student_id(student_email_id))
scmmishra73a31ec2018-11-03 19:31:53 +0530150 program_enrollment = student.enroll_in_program(program_name)
151 enroll_all_courses_in_program(program_enrollment, student)
scmmishra8b8db542018-11-03 18:03:24 +0530152
scmmishra73a31ec2018-11-03 19:31:53 +0530153@frappe.whitelist()
scmmishra8b8db542018-11-03 18:03:24 +0530154def get_student_id(email=None):
155 """Returns student user name, example EDU-STU-2018-00001 (Based on the naming series).
156
157 :param user: a user email address
158 """
159 try:
160 return frappe.get_all('Student', filters={'student_email_id': email}, fields=['name'])[0].name
161 except IndexError:
scmmishra73a31ec2018-11-03 19:31:53 +0530162 return None
163
164@frappe.whitelist()
165def get_program_enrollments(email=frappe.session.user):
scmmishrab409f7a2018-11-07 22:12:55 +0530166 if get_student_id(email) == None:
167 return None
scmmishra73a31ec2018-11-03 19:31:53 +0530168 try:
169 student = frappe.get_doc("Student", get_student_id(email))
170 return student.get_program_enrollments()
171 except:
172 return None
173
174@frappe.whitelist()
175def get_course_enrollments(email=frappe.session.user):
scmmishrab409f7a2018-11-07 22:12:55 +0530176 if get_student_id(email) == None:
177 return None
scmmishra73a31ec2018-11-03 19:31:53 +0530178 try:
179 student = frappe.get_doc("Student", get_student_id(email))
180 return student.get_course_enrollments()
181 except:
scmmishra1a04f772018-11-03 20:43:59 +0530182 return None
183
184@frappe.whitelist()
185def add_activity(enrollment, content_type, content):
scmmishra76222f72018-11-05 11:02:14 +0530186 if(check_activity_exists(enrollment, content_type, content)):
187 pass
188 else:
189 activity = frappe.get_doc({
190 "doctype": "Course Activity",
191 "enrollment": enrollment,
192 "content_type": content_type,
193 "content": content,
194 "activity_date": frappe.utils.datetime.datetime.now()
195 })
196 activity.save()
197 frappe.db.commit()
198
199def check_activity_exists(enrollment, content_type, content):
200 activity = frappe.get_all("Course Activity", filters={'enrollment': enrollment, 'content_type': content_type, 'content': content})
scmmishra0187b182018-11-05 12:16:02 +0530201 return bool(activity)
scmmishra76222f72018-11-05 11:02:14 +0530202
scmmishra0187b182018-11-05 12:16:02 +0530203def add_quiz_activity(enrollment, quiz_name, result_data, score, status):
204 quiz_activity = frappe.get_doc({
205 "doctype": "Quiz Activity",
206 "enrollment": enrollment,
207 "quiz": quiz_name,
208 "result": result_data,
209 "score": score,
210 "status": status
211 })
212 quiz_activity.save()
scmmishra25e42ba2018-11-05 13:11:37 +0530213 frappe.db.commit()
214
215@frappe.whitelist()
216def mark_course_complete(enrollment):
217 course_enrollment = frappe.get_doc("Course Enrollment", enrollment)
218 course_enrollment.completed = True
219 course_enrollment.save()
220 frappe.db.commit()