Example #1
0
    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
Example #2
0
    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, ""
Example #3
0
    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
Example #4
0
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
Example #5
0
    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)
Example #6
0
    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
Example #7
0
    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
Example #8
0
    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, ""
Example #10
0
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]
Example #11
0
    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"}
Example #12
0
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"))