def _parse_and_validate_input(self): request_params = web.input() course_name = get_mandatory_parameter(request_params, "course_name") course_year = get_mandatory_parameter(request_params, "course_year") course_period = get_mandatory_parameter(request_params, "course_period") course_group = request_params.get("course_group", None) course_to_copy_id = request_params.get("course_to_copy_id", None) if not course_name: raise api.APIError(400, _("The course name cannot be empty.")) if not course_year: raise api.APIError(400, _("The year field cannot be empty.")) if not course_year.isnumeric(): raise api.APIError(400, _("The year must be a number.")) if not course_period: raise api.APIError(400, _("The period field cannot be empty.")) data = {"name": course_name, "group": course_group, "year": course_year, "period": course_period} all_courses = set(self.course_factory.get_all_courses().keys()) course_to_copy_default_value = "-1" if course_to_copy_id and course_to_copy_id != course_to_copy_default_value: if course_to_copy_id not in all_courses: raise api.APIError(400, _("The selected course to copy tasks from does not exist.")) data["course_to_copy"] = course_to_copy_id return data
def API_GET(self): # Validate parameters username = self.user_manager.session_username() course_id = web.input(course_id=None).course_id task_id = web.input(task_id=None).task_id if course_id is None: raise api.APIError(400, {"error" : "course_id is mandatory"}) if task_id is None: raise api.APIError(400, {"error": "task_id is mandatory"}) try: course = self.course_factory.get_course(course_id) except (CourseNotFoundException, InvalidNameException, CourseUnreadableException): raise api.APIError(400, {"error", "The course does not exists or the user does not have permissions"}) if not self.user_manager.course_is_user_registered(course, username): raise api.APIError(400, {"error", "The course does not exists or the user does not have permissions"}) try: task = course.get_task(task_id) except: raise api.APIError(400, {"error", "The task does not exists in the course"}) # Asks for file try: file_preview = open(os.path.join(task.get_fs().prefix + 'preview'), 'r') return 200, file_preview.read() except: return 200, ""
def get_course_and_check_rights(self, course_id): try: course = self.course_factory.get_course(course_id) except (CourseNotFoundException, InvalidNameException, CourseUnreadableException): raise api.APIError(400, {"error": "Invalid course"}) if not self.user_manager.has_staff_rights_on_course(course): raise api.APIError(400, {"error": "Invalid course"}) return course
def get_api_query_parameters(input_dict): username = input_dict.get('username', None) service = input_dict.get('service', None) start_date = input_dict.get('start_date', None) end_date = input_dict.get('end_date', None) course_id = input_dict.get('course_id', None) # Generate query query_parameters = {} if username: query_parameters['username'] = username if service: query_parameters['service'] = _parse_list_for_query(service) if course_id: query_parameters['course_id'] = _parse_list_for_query(course_id) if start_date or end_date: query_parameters['date'] = {} if start_date: start_date = _convert_string_to_date(start_date) query_parameters['date']['$gte'] = start_date if end_date: end_date = _convert_string_to_date(end_date) query_parameters['date']['$lte'] = end_date.replace(hour=23, minute=59, second=59) if start_date and end_date and (end_date < start_date): raise api.APIError( 400, _("The start date must be greater than end date.")) return query_parameters
def statistics(self): username = self.user_manager.session_username() course_id = web.input().course_id best_submissions = self.database.user_tasks.aggregate([{ "$match": { "username": username, "courseid": course_id } }, { "$lookup": { "from": "submissions", "localField": "submissionid", "foreignField": "_id", "as": "submission" } }, { "$unwind": { "path": "$submission" } }, { "$sort": { "submission.submitted_on": 1 } }, { "$project": { "_id": 0, "result": "$submission.custom.custom_summary_result", "taskid": 1, "tried": 1, "grade": 1 } }, { "$match": { "result": { "$ne": None } } }]) # Add the tasks names best_submissions_with_name = [] for sub in list(best_submissions): try: course = self.course_factory.get_course(course_id) task = course.get_task(sub['taskid']) sub['task_name'] = task.get_name( self.user_manager.session_language()) best_submissions_with_name.append(sub) except (CourseNotFoundException, InvalidNameException, CourseUnreadableException): raise api.APIError( 400, { "error": "The course does not exist or the user does not have permissions" }) return 200, list(best_submissions_with_name)
def get_course_and_check_rights(self, course_id): try: course = self.course_factory.get_course(course_id) except (CourseNotFoundException, InvalidNameException, CourseUnreadableException): raise api.APIError( 400, { "error": "The course does not exist or the user does not have permissions." }) if not self.user_manager.has_admin_rights_on_course(course): raise api.APIError( 400, { "error": "The course does not exist or the user does not have permissions." }) return course
def _parse_rubric(self, rubric): if not len(rubric) or not rubric: raise api.APIError( 400, _("The rubric is not well formatted. The uploaded rubric is empty." )) column_names = list(rubric.keys()) categories = sorted(list(rubric[column_names[0]])) if not (len(column_names) or len(categories)): raise api.APIError( 400, _("The rubric is not well formatted. There are missing categories or grade levels in the rubric." )) parsed_rubric = OrderedDict() for column_name in column_names: categories_column = rubric[column_name].keys() if not categories_column or len(categories_column) != len( categories): raise api.APIError( 400, _("The rubric is not well formatted. The number of categories (rows) must be the same for each grade level." )) if sorted(list(categories_column)) != categories: raise api.APIError( 400, _("The rubric is not well formatted. Not all the categories (rows) have the same name." )) for value_cell in rubric[column_name].values(): if not value_cell: raise api.APIError( 400, _("The rubric is not well formatted. There some values for the cells empty." )) parsed_rubric[column_name] = OrderedDict( sorted(rubric[column_name].items())) return parsed_rubric
def validate_parameters(self): username = self.user_manager.session_username() course_id = web.input(course_id=None).course_id if course_id is None: raise api.APIError(400, {"error": "course_id is mandatory"}) try: course = self.course_factory.get_course(course_id) except (CourseNotFoundException, InvalidNameException, CourseUnreadableException): raise api.APIError( 400, { "error": "The course does not exist or the user does not have permissions" }) if not self.user_manager.course_is_user_registered(course, username): raise api.APIError( 400, { "error": "The course does not exist or the user does not have permissions" })
def API_GET(self): # Validate parameters username = self.user_manager.session_username() course_id = web.input(course_id=None).course_id task_id = web.input(task_id=None).task_id language = web.input(language=None).language if course_id is None: raise api.APIError(400, {"error": "course_id is mandatory"}) if task_id is None: raise api.APIError(400, {"error": "task_id is mandatory"}) if language is None: raise api.APIError(400, {'error': 'language is mandatory'}) try: course = self.course_factory.get_course(course_id) except (CourseNotFoundException, InvalidNameException, CourseUnreadableException): raise api.APIError( 400, { "error", "The course does not exists or the user does not have permissions" }) if not self.user_manager.course_is_user_registered(course, username): raise api.APIError( 400, { "error", "The course does not exists or the user does not have permissions" }) try: task = course.get_task(task_id) except: raise api.APIError( 400, {"error", "The task does not exists in the course"}) try: # file_preview = open(os.path.join(task.get_fs().prefix, 'preview'), 'r') task_yaml = open(os.path.join(task.get_fs().prefix, 'task.yaml'), 'r') try: data = yaml.safe_load(task_yaml) filename = data['code_preview_pairs'][language] file_preview = open( os.path.join(task.get_fs().prefix, filename), 'r') return 200, file_preview.read() except yaml.YAMLError as exc: print(exc) return 200, "" except: return 200, ""
def get_mandatory_parameter(parameters, parameter_name): if parameter_name not in parameters: raise api.APIError(400, {"error": parameter_name + " is mandatory"}) return parameters[parameter_name]
def API_POST(self): parameters = web.input() target_id = get_mandatory_parameter(parameters, "target_id") bank_id = get_mandatory_parameter(parameters, "bank_id") task_id = get_mandatory_parameter(parameters, "task_id") target_course = self.get_course_and_check_rights(target_id) target_course_tasks_ids = [key for key in target_course.get_tasks()] copy_id = str(uuid.uuid4()) while copy_id in target_course_tasks_ids: copy_id = str(uuid.uuid4()) try: bank_course = self.course_factory.get_course(bank_id) except (CourseNotFoundException, InvalidNameException, CourseUnreadableException): raise api.APIError(400, {"error": "Invalid bank"}) if not self.is_a_bank( bank_id) and not self.user_manager.has_admin_rights_on_course( bank_course): raise api.APIError(400, {"error": "Invalid bank"}) try: task = bank_course.get_task(task_id) except (TaskNotFoundException, InvalidNameException): raise api.APIError(400, {"error": "Invalid task"}) target_fs = self.course_factory.get_course_fs(target_id) try: target_fs.copy_to(task.get_fs().prefix, copy_id) if "tasks_cache" in self.database.collection_names(): task_to_copy = self.database.tasks_cache.find_one({ "course_id": bank_id, "task_id": task_id }) self.database.tasks_cache.insert({ "course_id": target_id, "task_id": copy_id, "task_name": task_to_copy["task_name"], "tags": task_to_copy["tags"], "task_context": task_to_copy["task_context"], "task_author": task_to_copy["task_author"], "course_name": target_course.get_name( self.user_manager.session_language()) }) except NotFoundException: raise api.APIError(400, {"error": "the copy_id made an invalid path"}) return 200, {"message": "Copied successfully"}
def _convert_string_to_date(string_date): """ Convert a string in datetime object """ try: return datetime.datetime(*map(int, string_date.split('-'))) except (ValueError, TypeError): raise api.APIError(400, _("Invalid date format"))