Beispiel #1
0
    def __init__(self, task, problemid, content):
        if not id_checker(problemid):
            raise Exception("Invalid problem _id: " + problemid)

        self._id = problemid
        self._task = task
        self._name = content['name'] if "name" in content else ""
        self._header = content['header'] if "header" in content else ""
    def __init__(self, task, problemid, content):
        if not id_checker(problemid):
            raise Exception("Invalid problem _id: " + problemid)

        self._id = problemid
        self._task = task
        self._name = content['name'] if "name" in content else ""
        self._header = ParsableText((content['header'] if "header" in content else ""), ("HTML" if "headerIsHTML" in content and content["headerIsHTML"] else "rst"))
Beispiel #3
0
    def _create_task_problem(self, task, problemid, problem_content):
        """Creates a new instance of the right class for a given problem."""
        # Basic checks
        if not id_checker(problemid):
            raise Exception("Invalid problem _id: " + problemid)
        if problem_content.get('type', "") not in self._problem_types:
            raise Exception("Invalid type for problem " + problemid)

        return self._problem_types.get(problem_content.get('type', ""))(task, problemid, problem_content)
Beispiel #4
0
 def _get_course_descriptor_path(cls, courseid):
     """Returns the path to the file that describes the course 'courseid'"""
     if not id_checker(courseid):
         raise Exception("Course with invalid name: " + courseid)
     base_file = os.path.join(get_tasks_directory(), courseid, "course")
     if os.path.isfile(base_file + ".yaml"):
         return base_file + ".yaml"
     else:
         return base_file + ".json"
Beispiel #5
0
 def _get_course_descriptor_path(cls, courseid):
     """Returns the path to the file that describes the course 'courseid'"""
     if not id_checker(courseid):
         raise Exception("Course with invalid name: " + courseid)
     base_file = os.path.join(INGIniousConfiguration["tasks_directory"], courseid, "course")
     if os.path.isfile(base_file + ".yaml"):
         return base_file + ".yaml"
     else:
         return base_file + ".json"
     return base_file + ".yaml"  # by default, YAML.
 def _create_box(self, boxid, box_content):
     """ Create adequate box """
     if not id_checker(boxid) and not boxid == "":
         raise Exception("Invalid box _id " + boxid)
     if "type" not in box_content:
         raise Exception("Box " + boxid + " does not have a type")
     try:
         return self._box_types[box_content["type"]](self, boxid, box_content)
     except:
         raise Exception("Unknow box type " + box_content["type"] + "for box _id " + boxid)
Beispiel #7
0
    def POST(self, courseid, taskid):
        """ Upload or modify a file """
        if not id_checker(taskid):
            raise Exception("Invalid task id")

        get_course_and_check_rights(courseid, allow_all_staff=False)

        request = web.input(file={})
        if request.get("action") == "upload" and request.get('path') is not None and request.get('file') is not None:
            return self.action_upload(courseid, taskid, request.get('path'), request.get('file'))
        elif request.get("action") == "edit_save" and request.get('path') is not None and request.get('content') is not None:
            return self.action_edit_save(courseid, taskid, request.get('path'), request.get('content'))
        else:
            return self.show_tab_file(courseid, taskid)
Beispiel #8
0
    def GET(self, courseid, taskid):
        """ Edit a task """
        if not id_checker(taskid):
            raise Exception("Invalid task id")

        course, _ = get_course_and_check_rights(courseid, allow_all_staff=False)

        try:
            task_data = get_task_file_manager(courseid, taskid).read()
        except:
            task_data = None
        if task_data is None:
            task_data = {}
        environments = INGIniousConfiguration["containers"].keys()

        current_filetype = None
        try:
            current_filetype = get_task_file_manager(courseid, taskid).get_ext()
        except:
            pass
        available_filetypes = get_available_task_file_managers().keys()

        # custom problem-type:
        for pid in task_data.get("problems", {}):
            problem = task_data["problems"][pid]
            if (problem["type"] == "code" and "boxes" in problem) or problem["type"] not in (
            "code", "code-single-line", "code-file", "match", "multiple-choice"):
                problem_copy = copy.deepcopy(problem)
                for i in ["name", "header", "headerIsHTML"]:
                    if i in problem_copy:
                        del problem_copy[i]
                problem["custom"] = common.custom_yaml.dump(problem_copy)

        return renderer.course_admin.edit_task(
            course,
            taskid,
            task_data,
            environments,
            json.dumps(
                task_data.get(
                    'problems',
                    {})),
            self.contains_is_html(task_data),
            current_filetype,
            available_filetypes,
            AccessibleTime,
            CourseTaskFiles.get_task_filelist(courseid, taskid))
Beispiel #9
0
    def __init__(self, course, taskid, init_data=None):
        """
            Init the task. course is a Course object, taskid the task id, and init_data is a dictionnary containing the data needed to initialize the Task object.
            If init_data is None, the data will be taken from the course tasks' directory.
        """

        if not id_checker(taskid):
            raise Exception("Task with invalid id: " + course.get_id() + "/" + taskid)

        self._course = course
        self._taskid = taskid

        if init_data is None:
            try:
                self._data = get_task_file_manager(self.get_course_id(), self.get_id()).read()
            except Exception as inst:
                raise Exception("Error while reading task file: " + self._course.get_id() + "/" + self._taskid + " :\n" + str(inst))
        else:
            self._data = init_data

        self._environment = self._data.get('environment', None)

        #Response is HTML
        self._response_is_html = self._data.get("responseIsHTML", False)

        # Limits
        self._limits = {"time": 20, "memory": 1024, "disk": 1024}
        if "limits" in self._data:
            try:
                self._limits['time'] = int(self._data["limits"].get("time", 20))
                self._limits['memory'] = int(self._data["limits"].get("memory", 1024))
                self._limits['disk'] = int(self._data["limits"].get("disk", 1024))
            except:
                raise Exception("Invalid limit")

        if "problems" not in self._data:
            raise Exception("Tasks must have some problems descriptions")

        # Check all problems
        self._problems = []

        for problemid in self._data['problems']:
            self._problems.append(self._create_task_problem(self, problemid, self._data['problems'][problemid]))
Beispiel #10
0
    def GET(self, courseid, taskid):
        """ Edit a task """
        if not id_checker(taskid):
            raise Exception("Invalid task id")

        get_course_and_check_rights(courseid, allow_all_staff=False)

        request = web.input()
        if request.get("action") == "download" and request.get('path') is not None:
            return self.action_download(courseid, taskid, request.get('path'))
        elif request.get("action") == "delete" and request.get('path') is not None:
            return self.action_delete(courseid, taskid, request.get('path'))
        elif request.get("action") == "rename" and request.get('path') is not None and request.get('new_path') is not None:
            return self.action_rename(courseid, taskid, request.get('path'), request.get('new_path'))
        elif request.get("action") == "create" and request.get('path') is not None:
            return self.action_create(courseid, taskid, request.get('path'))
        elif request.get("action") == "edit" and request.get('path') is not None:
            return self.action_edit(courseid, taskid, request.get('path'))
        else:
            return self.show_tab_file(courseid, taskid)
Beispiel #11
0
    def __init__(self, course, taskid, init_data=None):
        # We load the descriptor of the task here to allow plugins to modify settings of the task before it is read by the Task constructor
        if not id_checker(taskid):
            raise Exception("Task with invalid id: " + course.get_id() + "/" + taskid)
        if init_data is None:
            try:
                init_data = get_task_file_manager(course.get_id(), taskid).read()
            except Exception as inst:
                raise Exception("Error while reading task file: " + self._course.get_id() + "/" + self._taskid + " :\n" + str(inst))
        PluginManager.get_instance().call_hook('modify_task_data', course=course, taskid=taskid, data=init_data)

        # Now init the task
        common.tasks.Task.__init__(self, course, taskid, init_data)

        self._name = self._data.get('name', 'Task {}'.format(taskid))

        self._context = ParsableText(self._data.get('context', ""), "HTML" if self._data.get("contextIsHTML", False) else "rst")

        # Authors
        if isinstance(self._data.get('author'), basestring):  # verify if author is a string
            self._author = [self._data['author']]
        elif isinstance(self._data.get('author'), list):  # verify if author is a list
            for author in self._data['author']:
                if not isinstance(author, basestring):  # authors must be strings
                    raise Exception("This task has an invalid author")
            self._author = self._data['author']
        else:
            self._author = []

        # Grade weight
        self._weight = float(self._data.get("weight", 1.0))

        # _accessible
        self._accessible = AccessibleTime(self._data.get("accessible", None))

        # Order
        self._order = int(self._data.get('order', -1))
Beispiel #12
0
 def test_id_checker_invalid_3(self):
     assert id_checker("test/test") is False
Beispiel #13
0
 def test_id_checker_invalid_2(self):
     assert id_checker("") is False
Beispiel #14
0
 def test_id_checker_invalid_1(self):
     assert id_checker("a@a") is False
Beispiel #15
0
 def test_id_checker_valid_1(self):
     assert id_checker("azertyuiopZERTYUIO65456_5-a") is True
Beispiel #16
0
    def POST(self, courseid, taskid):
        """ Edit a task """
        if not id_checker(taskid) or not id_checker(courseid):
            raise Exception("Invalid course/task id")

        course, _ = get_course_and_check_rights(courseid, allow_all_staff=False)

        # Parse content
        try:
            data = web.input(task_file={})

            try:
                task_zip = data.get("task_file").file
            except:
                task_zip = None
            del data["task_file"]

            problems = self.dict_from_prefix("problem", data)
            limits = self.dict_from_prefix("limits", data)

            data = {key: val for key, val in data.iteritems() if not key.startswith("problem") and not key.startswith("limits")}
            del data["@action"]

            try:
                file_manager = get_available_task_file_managers()[data["@filetype"]](courseid, taskid)
            except Exception as inst:
                return json.dumps({"status": "error", "message": "Invalid file type: {}".format(str(inst))})
            del data["@filetype"]

            if problems is None:
                return json.dumps({"status": "error", "message": "You cannot create a task without subproblems"})

            # Order the problems (this line also deletes @order from the result)
            data["problems"] = OrderedDict([(key, self.parse_problem(val))
                                            for key, val in sorted(problems.iteritems(), key=lambda x: int(x[1]['@order']))])
            data["limits"] = limits
            if "hard_time" in data["limits"] and data["limits"]["hard_time"] == "":
                del data["limits"]["hard_time"]

            # Weight
            try:
                data["weight"] = float(data["weight"])
            except:
                return json.dumps({"status": "error", "message": "Grade weight must be a floating-point number"})

            # Accessible
            if data["accessible"] == "custom":
                data["accessible"] = "{}/{}".format(data["accessible_start"], data["accessible_end"])
            elif data["accessible"] == "true":
                data["accessible"] = True
            else:
                data["accessible"] = False
            del data["accessible_start"]
            del data["accessible_end"]

            # Checkboxes
            if data.get("responseIsHTML"):
                data["responseIsHTML"] = True
            if data.get("contextIsHTML"):
                data["contextIsHTML"] = True
        except Exception as message:
            return json.dumps({"status": "error", "message": "Your browser returned an invalid form ({})".format(str(message))})

        # Get the course
        try:
            course = FrontendCourse(courseid)
        except:
            return json.dumps({"status": "error", "message": "Error while reading course's informations"})

        # Get original data
        try:
            orig_data = get_task_file_manager(courseid, taskid).read()
            data["order"] = orig_data["order"]
        except:
            pass

        try:
            FrontendTask(course, taskid, data)
        except Exception as message:
            return json.dumps({"status": "error", "message": "Invalid data: {}".format(str(message))})

        if not os.path.exists(os.path.join(get_tasks_directory(), courseid, taskid)):
            os.mkdir(os.path.join(get_tasks_directory(), courseid, taskid))

        if task_zip:
            try:
                zipfile = ZipFile(task_zip)
            except Exception as message:
                return json.dumps({"status": "error", "message": "Cannot read zip file. Files were not modified"})

            try:
                zipfile.extractall(os.path.join(get_tasks_directory(), courseid, taskid))
            except Exception as message:
                return json.dumps(
                    {"status": "error", "message": "There was a problem while extracting the zip archive. Some files may have been modified"})

        delete_all_possible_task_files(courseid, taskid)
        file_manager.write(data)

        return json.dumps({"status": "ok"})