def post(self) -> Response: """ POST response method for endorsing a course. :return: JSON object """ data = request.get_json() user_id=get_jwt_identity() course_id = data["courseId"] authorized: bool = Users.objects.get(id=user_id).roles.organization if authorized: # don't let an organization endorse the same course twice if Courses.objects(id=course_id, endorsedBy=ObjectId(user_id)): return conflict("You already endorsed this course!") # add the organization the course's endorsedBy list try: endorse = Courses.objects(id=course_id).update(push__endorsedBy=ObjectId(user_id)) if endorse == 0: return not_found("404 Error: The requested course does not exist") except InvalidId as e: print(e.__class__.__name__) print(dir(e)) return bad_request(str(e)) except ValidationError as e: return bad_request(e.message) output = {'id': user_id} return jsonify(output) else: return forbidden()
def get(self, course_id: str) -> Response: """ GET response method for all documents in course collection. JSON Web Token is required. """ authorized: bool = True #Users.objects.get(id=get_jwt_identity()).access.admin user_id = get_jwt_identity() # make sure the course exists try: course = Courses.objects.get(id=course_id) except DoesNotExist: return not_found() if authorized: inst_id = getattr(getattr(course, 'instructor'), 'id') if (str(inst_id) != str(user_id)): query = Feedback.objects(course=course_id, public=True) else: query = Feedback.objects(course=course_id) res = [] for fb in query: img_b64 = base64.b64encode(fb.user.image.thumbnail.read()) fb_json = { 'comment': fb.comment, 'user': fb.user.name, 'image': img_b64.decode('utf-8') } res.append(fb_json) return jsonify(res) else: return forbidden()
def post(self) -> Response: """ POST response method for enrolling in a course. :return: JSON object """ data = request.get_json() user_id=get_jwt_identity() if Courses.objects(id=data["courseId"], students=ObjectId(user_id)): return conflict("You cannot enrol in the same course twice!") try: enroll = Courses.objects(id=data["courseId"]).update(push__students=ObjectId(user_id)) if enroll == 0: return not_found("404 Error: The requested course does not exist") except InvalidId as e: print(e.__class__.__name__) print(dir(e)) return bad_request(str(e)) except ValidationError as e: return bad_request(e.message) output = {'id': user_id} return jsonify(output)
def get(self, course_id) -> Response: # get the view count for a course page # get the instructor for the course try: inst = Courses.objects.get(id=course_id).instructor except DoesNotExist: return not_found("could not find the specified course") authorized = (str(inst.id) == get_jwt_identity()) if not authorized: return forbidden() # get the page with the given name (might not be registered yet) try: page_name = '~courses~' + course_id page = Pages.objects.get(name=page_name) output = {'views': page.views} return jsonify(output) except DoesNotExist: return not_found("this page has no views yet")
def get(self, course_id: str) -> Response: """ GET response method for a specific course in course collection with published=true. Returns a 404 error if the course is not published or doesn't exist. :return: JSON object """ try: output = Courses.objects.get(id=course_id) except DoesNotExist: return not_found() if output.published == False: return not_found() fields = { 'id', 'name', 'objective', 'learningOutcomes' } embedded = {'instructor': {'name': 'instructor'}} converted = convert_embedded_doc(output, fields, embedded) return jsonify(converted)
def post(self) -> Response: """ POST response method for creating a quiz submission. JSON Web Token is required. Student must be in the course. Student may only have one submission per quiz. """ user = get_jwt_identity() data = request.get_json() quiz_id = data['quiz'] # already a submission from this user if len(Submissions.objects(quiz=quiz_id, user=user)) != 0: return forbidden() # quiz doesn't exist try: quiz = Quizzes.objects.get(id=quiz_id) course = Courses.objects.get(id=quiz.course.id) except DoesNotExist as e: return not_found() # student must be enrolled in the course of the quiz courses = Courses.objects(students=user) if course not in courses: return forbidden() # student is in course and has not submitted # generate the answer key answer_key = {} for question in quiz.quizQuestions: answer_key[question.index] = question.answer # compare answer key to student responses student_responses = data['answers'] grade = 0 for response in student_responses: index = response['question'] if index in answer_key and answer_key[index] == response['answer']: grade += 1 try: data['user'] = user data['grade'] = grade submission = Submissions(**data).save() except ValidationError as e: return bad_request(e.to_dict()) output = {'id': str(submission.id)} return jsonify(output)
def get(self, course_id) -> Response: # get the number of people enrolled in a course # get the instructor for the course try: course = Courses.objects.get(id=course_id) inst = course.instructor except DoesNotExist: return not_found("could not find the specified course") authorized = (str(inst.id) == get_jwt_identity()) if not authorized: return forbidden() output = {'students': len(course.students)} return jsonify(output)
def get(self, course_id: str) -> Response: """ GET response method for single documents in course collection. :return: JSON object """ # check if the given course id is valid or not try: course = Courses.objects.get(id=course_id) except DoesNotExist as e: return not_found() except ValidationError as e: return bad_request() user = get_jwt_identity() try: # check if the user is enrolled in the course queryCourse = Courses.objects.get(id=course_id, students=ObjectId(user)) student = True except DoesNotExist as e: student = False # check if the user is the instructor of the course or if they are an admin inst = str(course.instructor.id) == user admin = Users.objects.get(id=user).roles.admin authorized = student or inst or admin if authorized: if inst or admin: query = Quizzes.objects(course=course) elif student: query = Quizzes.objects(course=course, published=True) fields = { 'id', 'name', 'quizQuestions', 'published', } embedded = {'course': {'id': 'course'}} converted = convert_embedded_query(query, fields, embedded) return jsonify(converted) else: return forbidden()
def get(self, quiz_id: str) -> Response: """ GET response method for single document in Submission collection. :return: JSON object """ query = Submissions.objects(quiz=quiz_id) # quiz doesn't exist or no one has taken it if len(query) == 0: return not_found() total = 0 for submission in query: total += submission.grade response = {'average': total / len(query)} return jsonify(response)
def get(self, course_id) -> Response: # get the number of *published* quizzes in a course # get the instructor for the course try: course = Courses.objects.get(id=course_id) inst = course.instructor except DoesNotExist: return not_found("could not find the specified course") authorized = (str(inst.id) == get_jwt_identity()) if not authorized: return forbidden() # get all the quizzes for this course that are published quizzes = Quizzes.objects(course=course, published=True) output = {'quizzes': len(quizzes)} return jsonify(output)
def get(self, course_id) -> Response: # get the number of *published* quizzes in a course # get the instructor for the course try: course = Courses.objects.get(id=course_id) inst = course.instructor except DoesNotExist: return not_found("could not find the specified course") authorized = (str(inst.id) == get_jwt_identity()) if not authorized: return forbidden() # get all the quizzes for this course that are published quizzes = Quizzes.objects(course=course, published=True) # output will be a list of quiz objects (name, # of submissions, and average) output = [] for quiz in quizzes: query = Submissions.objects(quiz=quiz.id) if (len(query) > 0 and len(quiz.quizQuestions) > 0): total = 0 for submission in query: total += submission.grade average = total / (len(query) * len(quiz.quizQuestions)) # the following two lines take the decimal average and convert it to whole number with 2 digits remaining # examples: # 0.01 -> 100.0 -> 1 # 0.234 -> 234.0 -> 23 average *= 10000 average //= 100 totalSubs = len(query) else: average = 0 totalSubs = 0 output.append({ 'quiz': quiz.name, 'average': average, 'totalSubmissions': totalSubs, }) return jsonify(output)
def get(self, quiz_id: str) -> Response: """ GET response method for single document in Submission collection. :return: JSON object """ user = get_jwt_identity() try: query = Submissions.objects.get(user=user, quiz=quiz_id) except DoesNotExist as e: return not_found() fields = { 'id', 'grade', 'answers', } response = convert_doc(query, include=fields) return jsonify(response)
def get(self, course_id: str) -> Response: """ GET response method a list of organizations endorsing a course. :return: JSON object """ # get the course try: course = Courses.objects().get(id=course_id) except DoesNotExist: return not_found("404 Error: The requested course does not exist") # get the names and pictures of the organizations endorsing the course orgs = [] for org in course.endorsedBy: img_b64 = base64.b64encode(org.image.thumbnail.read()) org_json = { 'name': org.name, 'image': img_b64.decode('utf-8') } orgs.append(org_json) return jsonify(orgs)
def delete(self, course_id: str) -> Response: """ DELETE response method for disenrolling in a course. :return: JSON object """ user_id=get_jwt_identity() try: disenroll = Courses.objects(id=course_id).update(pull__students=ObjectId(user_id)) if disenroll == 0: return not_found("404 Error: The requested course does not exist") except InvalidId as e: print(e.__class__.__name__) print(dir(e)) return bad_request(str(e)) except ValidationError as e: return bad_request(e.message) output = {'id': user_id} return jsonify(output)
def get(self, quiz_id: str) -> Response: """ GET response method for single document in Quizzes collection. :return: JSON object """ try: quiz = Quizzes.objects.get(id=quiz_id) except DoesNotExist as e: return not_found() fields = { 'id', 'name', 'quizQuestions', 'published', } embedded = {'course': {'id': 'course'}} converted = convert_embedded_doc(quiz, fields, embedded) return jsonify(converted)
def delete(self, course_id: str) -> Response: """ DELETE response method for deleting single course. JSON Web Token is required. Authorization is required: Access(admin=true) """ queryCourse = Courses.objects.get(id=course_id) user = get_jwt_identity() # only the course instructor can delete courses authorized: bool = queryCourse['instructor']['id'] == ObjectId(user) # or an admin authorized = authorized or Users.objects.get(id=user).roles.admin if authorized: output = Courses.objects(id=course_id).delete() if output == 0: return not_found() else: return jsonify(output) else: return forbidden()
def post(self) -> Response: authorized: bool = True #Users.objects.get(id=get_jwt_identity()).access.admin if authorized: data = request.get_json() # make sure the course exists try: course = Courses.objects.get(id=data["course"]) except DoesNotExist: return not_found() # get the user id based off of jwt token identity data['user'] = get_jwt_identity() try: feedback = Feedback(**data).save() except ValidationError as e: return bad_request(e.to_dict()) output = {'id': str(feedback.id)} return jsonify(output) else: return forbidden()