blob: bb5daaf02a979ca228f71e1cb5144050c8ad8f02 [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)
100 course = frappe.get_doc("Course", enrollment.course)
101 last_activity = enrollment.get_last_activity()
102
103 if last_activity == None:
104 next_content = course.get_first_content()
105 return dict(content=next_content.name, content_type=next_content.doctype, flag="Start")
106
107 if last_activity.doctype == "Quiz Activity":
108 next_content = get_next_content(last_activity.quiz, "Quiz", course.name)
109 else:
110 next_content = get_next_content(last_activity.content, last_activity.content_type, course.name)
111
112 if next_content == None:
113 next_content = course.get_first_content()
114 return dict(content=next_content.name, content_type=next_content.doctype, flag="Complete")
115 else:
116 next_content['flag'] = "Continue"
117 return next_content
118
119
120@frappe.whitelist()
121def get_starting_content(course_name):
122 course = frappe.get_doc('Course', course_name)
123 content = course.course_content[0].content
124 content_type = course.course_content[0].content_type
125 return dict(content=content, content_type=content_type)
126
127# Functions to get content details
128@frappe.whitelist()
129def get_content(content_name, content_type):
130 try:
131 content = frappe.get_doc(content_type, content_name)
132 return content
133 except:
134 frappe.throw("{0} with name {1} does not exist".format(content_type, content_name))
135 return None
136
137@frappe.whitelist()
138def get_next_content(content, content_type, course):
139 if frappe.session.user == "Guest":
140 return None
141 course_doc = frappe.get_doc("Course", course)
142 content_list = [{'content_type':item.content_type, 'content':item.content} for item in course_doc.get_all_children()]
143 current_index = content_list.index({'content': content, 'content_type': content_type})
144 try:
145 return content_list[current_index + 1]
146 except IndexError:
147 return None
148
149def get_quiz_with_answers(quiz_name):
150 try:
151 quiz = frappe.get_doc("Quiz", quiz_name).get_questions()
152 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]
153 return quiz_output
154 except:
155 frappe.throw("Quiz {0} does not exist".format(quiz_name))
156 return None
157
158@frappe.whitelist()
159def get_quiz_without_answers(quiz_name):
160 try:
161 quiz = frappe.get_doc("Quiz", quiz_name).get_questions()
162 quiz_output = [{'name':question.name, 'question':question.question, 'options':[{'name': option.name, 'option':option.option} for option in question.options]} for question in quiz]
163 return quiz_output
164 except:
165 frappe.throw("Quiz {0} does not exist".format(quiz_name))
166 return None
167
168@frappe.whitelist()
169def evaluate_quiz(enrollment, quiz_response, quiz_name):
170 """LMS Function: Evaluates a simple multiple choice quiz.
171
172
173 :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.
174 """
175 import json
176 quiz_response = json.loads(quiz_response)
177 quiz = frappe.get_doc("Quiz", quiz_name)
178 answers, score, status = quiz.evaluate(quiz_response, quiz_name)
179
180 result = {k: ('Correct' if v else 'Wrong') for k,v in answers.items()}
181 result_data = []
182 for key in answers:
183 item = {}
184 item['question'] = key
185 item['quiz_result'] = result[key]
186 try:
187 item['selected_option'] = frappe.get_value('Options', quiz_response[key], 'option')
188 except:
189 item['selected_option'] = "Unattempted"
190 result_data.append(item)
191 # result_data = [{'question': key, 'selected_option': frappe.get_value('Options', quiz_response[key], 'option'), 'quiz_result': result[key]} for key in answers]
192
193 add_quiz_activity(enrollment, quiz_name, result_data, score, status)
194 return(score)
195
196@frappe.whitelist()
197def get_completed_courses():
198 student = get_student_id(frappe.session.user)
199 if student == None:
200 return None
201 try:
202 student = frappe.get_doc("Student", student)
203 return student.get_completed_courses()
204 except:
205 return None
206
207@frappe.whitelist()
208def get_continue_data(program_name):
209 program = frappe.get_doc("Program", program_name)
210 courses = program.get_all_children()
211 try:
212 continue_data = get_starting_content(courses[0].course)
213 continue_data['course'] = courses[0].course
214 return continue_data
215 except:
216 return None
217
218@frappe.whitelist()
219def enroll_all_courses_in_program(program_enrollment, student):
220 program = frappe.get_doc("Program", program_enrollment.program)
221 course_list = [course.course for course in program.get_all_children()]
222 for course_name in course_list:
223 student.enroll_in_course(course_name=course_name, program_enrollment=program_enrollment.name)
224
225@frappe.whitelist()
226def enroll_in_program(program_name):
227 if(not get_student_id(frappe.session.user)):
228 create_student(frappe.session.user)
229 student = frappe.get_doc("Student", get_student_id(frappe.session.user))
230 program_enrollment = student.enroll_in_program(program_name)
231 enroll_all_courses_in_program(program_enrollment, student)
232
233@frappe.whitelist()
234def get_program_enrollments(email=frappe.session.user):
235 if get_student_id(email) == None:
236 return None
237 try:
238 student = frappe.get_doc("Student", get_student_id(email))
239 return student.get_program_enrollments()
240 except:
241 return None
242
243@frappe.whitelist()
244def get_course_enrollments():
245 student = get_student_id(frappe.session.user)
246 if student == None:
247 return None
248 try:
249 student = frappe.get_doc("Student", student)
250 return student.get_course_enrollments()
251 except:
252 return None
253
254
255# Academty Activity
256@frappe.whitelist()
257def add_activity(enrollment, content_type, content):
258 if(check_activity_exists(enrollment, content_type, content)):
259 pass
260 else:
261 activity = frappe.get_doc({
262 "doctype": "Course Activity",
263 "enrollment": enrollment,
264 "content_type": content_type,
265 "content": content,
266 "activity_date": frappe.utils.datetime.datetime.now()
267 })
268 activity.save()
269 frappe.db.commit()
270
271def check_activity_exists(enrollment, content_type, content):
272 activity = frappe.get_all("Course Activity", filters={'enrollment': enrollment, 'content_type': content_type, 'content': content})
273 return bool(activity)
274
275def add_quiz_activity(enrollment, quiz_name, result_data, score, status):
276 quiz_activity = frappe.get_doc({
277 "doctype": "Quiz Activity",
278 "enrollment": enrollment,
279 "quiz": quiz_name,
280 "result": result_data,
281 "score": score,
282 "status": status
283 })
284 quiz_activity.save()
285 frappe.db.commit()
286
287@frappe.whitelist()
288def mark_course_complete(enrollment):
289 course_enrollment = frappe.get_doc("Course Enrollment", enrollment)
290 course_enrollment.completed = True
291 course_enrollment.save()
292 frappe.db.commit()