blob: 625c66cd796a64a0ddbd26c12881577178881dd0 [file] [log] [blame]
scmmishra35bf5612018-11-13 16:36:22 +05301from __future__ import unicode_literals
2import frappe
3
4# Academy Utils
5@frappe.whitelist(allow_guest=True)
6def 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
12def check_program_enrollment(program_name):
13 if frappe.session.user in ("Guest", "Administrator"):
14 return False
15 student = get_student_id(frappe.session.user)
16 enrollment = frappe.get_list("Program Enrollment", filters={'student':student, 'program': program_name})
17 if enrollment:
18 return True
19 else:
20 return False
21
22@frappe.whitelist(allow_guest=True)
23def get_featured_programs():
24 featured_program_names = frappe.get_all("Program", filters={"is_published": True, "is_featured": True})
25 if featured_program_names:
26 featured_list = [get_program(program['name']) for program in featured_program_names]
27 return featured_list
28 else:
29 return None
30
scmmishra85c2fee2018-11-14 14:23:06 +053031@frappe.whitelist(allow_guest=True)
32def get_all_programs():
33 program_names = frappe.get_all("Program", filters={"is_published": True})
34 if program_names:
35 featured_list = [get_program(program['name']) for program in program_names]
36 return featured_list
37 else:
38 return None
39
scmmishra35bf5612018-11-13 16:36:22 +053040def get_program(program_name):
41 program = frappe.get_doc('Program', program_name)
42 is_enrolled = check_program_enrollment(program_name)
43 return {'program': program, 'is_enrolled': is_enrolled}
44
45@frappe.whitelist(allow_guest=True)
46def get_program_details(program_name):
47 try:
48 program = frappe.get_doc('Program', program_name)
49 return program
50 except:
51 return None
52
53
54def get_enrollment(course_name):
55 student = get_student_id(frappe.session.user)
56 enrollment_name = frappe.get_all("Course Enrollment", filters={'student': student, 'course':course_name})
57 try:
58 name = enrollment_name[0].name
59 enrollment = frappe.get_doc("Course Enrollment", name)
60 return enrollment
61 except:
62 return None
63
64@frappe.whitelist()
65def get_student_id(email=None):
66 """Returns student user name, example EDU-STU-2018-00001 (Based on the naming series).
67
68 :param user: a user email address
69 """
70 try:
71 student_id = frappe.db.get_all("Student", {"student_email_id": email}, ["name"])[0].name
72 return student_id
73 except IndexError:
74 return None
75
76def create_student():
77 student_name=frappe.session.user
78 student = frappe.get_doc({
79 "doctype": "Student",
80 "first_name": student_name,
81 "student_email_id": student_name,
82 })
83 student.save(ignore_permissions=True)
84 frappe.db.commit()
85 return student_name
86
87# Functions to get program & course details
88@frappe.whitelist(allow_guest=True)
89def get_courses(program_name):
90 program = frappe.get_doc('Program', program_name)
91 courses = program.get_course_list()
92 course_data = [{'meta':get_continue_content(item.name), 'course':item} for item in courses]
93 return course_data
94
95@frappe.whitelist()
96def get_continue_content(course_name):
97 if frappe.session.user == "Guest":
98 return dict(content=None, content_type=None, flag=None)
99 enrollment = get_enrollment(course_name)
scmmishra0a4902f2018-11-15 11:16:53 +0530100 print(enrollment)
scmmishra35bf5612018-11-13 16:36:22 +0530101 course = frappe.get_doc("Course", enrollment.course)
102 last_activity = enrollment.get_last_activity()
103
104 if last_activity == None:
105 next_content = course.get_first_content()
106 return dict(content=next_content.name, content_type=next_content.doctype, flag="Start")
107
108 if last_activity.doctype == "Quiz Activity":
109 next_content = get_next_content(last_activity.quiz, "Quiz", course.name)
110 else:
111 next_content = get_next_content(last_activity.content, last_activity.content_type, course.name)
112
113 if next_content == None:
114 next_content = course.get_first_content()
115 return dict(content=next_content.name, content_type=next_content.doctype, flag="Complete")
116 else:
117 next_content['flag'] = "Continue"
118 return next_content
119
120
121@frappe.whitelist()
122def get_starting_content(course_name):
123 course = frappe.get_doc('Course', course_name)
124 content = course.course_content[0].content
125 content_type = course.course_content[0].content_type
126 return dict(content=content, content_type=content_type)
127
128# Functions to get content details
129@frappe.whitelist()
130def get_content(content_name, content_type):
131 try:
132 content = frappe.get_doc(content_type, content_name)
133 return content
134 except:
135 frappe.throw("{0} with name {1} does not exist".format(content_type, content_name))
136 return None
137
138@frappe.whitelist()
139def get_next_content(content, content_type, course):
140 if frappe.session.user == "Guest":
141 return None
142 course_doc = frappe.get_doc("Course", course)
143 content_list = [{'content_type':item.content_type, 'content':item.content} for item in course_doc.get_all_children()]
144 current_index = content_list.index({'content': content, 'content_type': content_type})
145 try:
146 return content_list[current_index + 1]
147 except IndexError:
148 return None
149
150def get_quiz_with_answers(quiz_name):
151 try:
152 quiz = frappe.get_doc("Quiz", quiz_name).get_questions()
153 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]
154 return quiz_output
155 except:
156 frappe.throw("Quiz {0} does not exist".format(quiz_name))
157 return None
158
159@frappe.whitelist()
160def get_quiz_without_answers(quiz_name):
161 try:
162 quiz = frappe.get_doc("Quiz", quiz_name).get_questions()
163 quiz_output = [{'name':question.name, 'question':question.question, 'options':[{'name': option.name, 'option':option.option} for option in question.options]} for question in quiz]
164 return quiz_output
165 except:
166 frappe.throw("Quiz {0} does not exist".format(quiz_name))
167 return None
168
169@frappe.whitelist()
170def evaluate_quiz(enrollment, quiz_response, quiz_name):
171 """LMS Function: Evaluates a simple multiple choice quiz.
172
173
174 :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.
175 """
176 import json
177 quiz_response = json.loads(quiz_response)
178 quiz = frappe.get_doc("Quiz", quiz_name)
179 answers, score, status = quiz.evaluate(quiz_response, quiz_name)
180
181 result = {k: ('Correct' if v else 'Wrong') for k,v in answers.items()}
182 result_data = []
183 for key in answers:
184 item = {}
185 item['question'] = key
186 item['quiz_result'] = result[key]
187 try:
188 item['selected_option'] = frappe.get_value('Options', quiz_response[key], 'option')
189 except:
190 item['selected_option'] = "Unattempted"
191 result_data.append(item)
192 # result_data = [{'question': key, 'selected_option': frappe.get_value('Options', quiz_response[key], 'option'), 'quiz_result': result[key]} for key in answers]
193
194 add_quiz_activity(enrollment, quiz_name, result_data, score, status)
195 return(score)
196
197@frappe.whitelist()
198def get_completed_courses():
199 student = get_student_id(frappe.session.user)
200 if student == None:
201 return None
202 try:
203 student = frappe.get_doc("Student", student)
204 return student.get_completed_courses()
205 except:
206 return None
207
208@frappe.whitelist()
209def get_continue_data(program_name):
210 program = frappe.get_doc("Program", program_name)
211 courses = program.get_all_children()
212 try:
213 continue_data = get_starting_content(courses[0].course)
214 continue_data['course'] = courses[0].course
215 return continue_data
216 except:
217 return None
218
219@frappe.whitelist()
220def enroll_all_courses_in_program(program_enrollment, student):
221 program = frappe.get_doc("Program", program_enrollment.program)
222 course_list = [course.course for course in program.get_all_children()]
223 for course_name in course_list:
224 student.enroll_in_course(course_name=course_name, program_enrollment=program_enrollment.name)
225
226@frappe.whitelist()
227def enroll_in_program(program_name):
228 if(not get_student_id(frappe.session.user)):
229 create_student(frappe.session.user)
230 student = frappe.get_doc("Student", get_student_id(frappe.session.user))
231 program_enrollment = student.enroll_in_program(program_name)
232 enroll_all_courses_in_program(program_enrollment, student)
scmmishra0a4902f2018-11-15 11:16:53 +0530233 return program_name
scmmishra35bf5612018-11-13 16:36:22 +0530234
235@frappe.whitelist()
236def get_program_enrollments(email=frappe.session.user):
237 if get_student_id(email) == None:
238 return None
239 try:
240 student = frappe.get_doc("Student", get_student_id(email))
241 return student.get_program_enrollments()
242 except:
243 return None
244
245@frappe.whitelist()
246def get_course_enrollments():
247 student = get_student_id(frappe.session.user)
248 if student == None:
249 return None
250 try:
251 student = frappe.get_doc("Student", student)
252 return student.get_course_enrollments()
253 except:
254 return None
255
256
257# Academty Activity
258@frappe.whitelist()
259def add_activity(enrollment, content_type, content):
260 if(check_activity_exists(enrollment, content_type, content)):
261 pass
262 else:
263 activity = frappe.get_doc({
264 "doctype": "Course Activity",
265 "enrollment": enrollment,
266 "content_type": content_type,
267 "content": content,
268 "activity_date": frappe.utils.datetime.datetime.now()
269 })
270 activity.save()
271 frappe.db.commit()
272
273def check_activity_exists(enrollment, content_type, content):
274 activity = frappe.get_all("Course Activity", filters={'enrollment': enrollment, 'content_type': content_type, 'content': content})
275 return bool(activity)
276
277def add_quiz_activity(enrollment, quiz_name, result_data, score, status):
278 quiz_activity = frappe.get_doc({
279 "doctype": "Quiz Activity",
280 "enrollment": enrollment,
281 "quiz": quiz_name,
282 "result": result_data,
283 "score": score,
284 "status": status
285 })
286 quiz_activity.save()
287 frappe.db.commit()
288
289@frappe.whitelist()
290def mark_course_complete(enrollment):
291 course_enrollment = frappe.get_doc("Course Enrollment", enrollment)
292 course_enrollment.completed = True
293 course_enrollment.save()
294 frappe.db.commit()