Пример #1
0
    def GET(self, courseid):
        """ GET request """

        if User.is_logged_in():
            try:
                course = FrontendCourse(courseid)
                if not course.is_open_to_user(User.get_username()):
                    return renderer.course_unavailable()

                last_submissions = course.get_user_last_submissions(one_per_task=True)
                except_free_last_submissions = []
                for submission in last_submissions:
                    try:
                        submission["task"] = course.get_task(submission['taskid'])
                        except_free_last_submissions.append(submission)
                    except:
                        pass
                return renderer.course(course, except_free_last_submissions)
            except:
                if web.config.debug:
                    raise
                else:
                    raise web.notfound()
        else:
            return renderer.index(False)
Пример #2
0
def add_job(task, inputdata, debug=False):
    """ Add a job in the queue and returns a submission id.
        task is a Task instance and inputdata is the input as a dictionary
        If debug is true, more debug data will be saved
    """
    if not User.is_logged_in():
        raise Exception("A user must be logged in to submit an object")

    username = User.get_username()
    course = FrontendCourse(task.get_course_id())

    obj = {
        "courseid": task.get_course_id(),
        "taskid": task.get_id(),
        "input": get_gridfs().put(
            json.dumps(inputdata)),
        "status": "waiting",
        "submitted_on": datetime.now()}

    if course.is_group_course() and username not in course.get_staff(True):
        group = get_database().groups.find_one({"course_id": task.get_course_id(), "users": username})
        obj.update({"username": group["users"]})
    else:
        obj.update({"username": [username]})

    submissionid = get_database().submissions.insert(obj)

    PluginManager.get_instance().call_hook("new_submission", submissionid=submissionid, submission=obj, inputdata=inputdata)

    get_job_manager().new_job(task, inputdata, (lambda job: _job_done_callback(submissionid, task, job)), "Frontend - {}".format(username), debug)

    return submissionid
Пример #3
0
    def GET(self, courseid, taskid, path):
        """ GET request """
        if User.is_logged_in():
            try:
                course = FrontendCourse(courseid)
                if not course.is_open_to_user(User.get_username()):
                    return renderer.course_unavailable()

                task = course.get_task(taskid)
                if not task.is_visible_by_user(User.get_username()):
                    return renderer.task_unavailable()

                path_norm = posixpath.normpath(urllib.unquote(path))
                public_folder_path = os.path.normpath(os.path.realpath(os.path.join(INGIniousConfiguration["tasks_directory"], courseid, taskid, "public")))
                file_path = os.path.normpath(os.path.realpath(os.path.join(public_folder_path, path_norm)))

                # Verify that we are still inside the public directory
                if os.path.normpath(os.path.commonprefix([public_folder_path, file_path])) != public_folder_path:
                    raise web.notfound()

                if os.path.isfile(file_path):
                    mimetypes.init()
                    mime_type = mimetypes.guess_type(file_path)
                    web.header('Content-Type', mime_type[0])
                    with open(file_path) as static_file:
                        return static_file.read()
                else:
                    raise web.notfound()
            except:
                if web.config.debug:
                    raise
                else:
                    raise web.notfound()
        else:
            return renderer.index(False)
def get_user_submissions(task):
    """ Get all the user's submissions for a given task """
    if not User.is_logged_in():
        raise Exception("A user must be logged in to get his submissions")
    cursor = get_database().submissions.find({"username": User.get_username(), "taskid": task.get_id(), "courseid": task.get_course_id()})
    cursor.sort([("submitted_on", -1)])
    return list(cursor)
def add_job(task, inputdata, debug=False):
    """ Add a job in the queue and returns a submission id.
        task is a Task instance and inputdata is the input as a dictionary
        If debug is true, more debug data will be saved
    """
    if not User.is_logged_in():
        raise Exception("A user must be logged in to submit an object")

    username = User.get_username()

    jobid = get_job_manager().new_job_id()

    obj = {
        "username": username,
        "courseid": task.get_course_id(),
        "taskid": task.get_id(),
        "input": get_gridfs().put(
            json.dumps(inputdata)),
        "status": "waiting",
        "jobid": jobid,
        "submitted_on": datetime.now()}
    submissionid = get_database().submissions.insert(obj)

    PluginManager.get_instance().call_hook("new_submission", submissionid=submissionid, submission=obj, jobid=jobid, inputdata=inputdata)

    get_job_manager().new_job(task, inputdata, job_done_callback, "Frontend - {}".format(username), jobid, debug)

    return submissionid
Пример #6
0
def get_course_and_check_rights(courseid, taskid=None, allow_all_staff=True):
    """ Returns the course with id ```courseid``` and the task with id ```taskid```, and verify the rights of the user.
        Raise web.notfound() when there is no such course of if the users has not enough rights.

        :param courseid: the course on which to check rights
        :param taskid: If not None, returns also the task with id ```taskid```
        :param allow_all_staff: allow admins AND tutors to see the page. If false, all only admins.
        :returns (Course, Task)
    """

    try:
        if User.is_logged_in():
            course = FrontendCourse(courseid)
            if allow_all_staff:
                if User.get_username() not in course.get_staff():
                    raise web.notfound()
            else:
                if User.get_username() not in course.get_admins():
                    raise web.notfound()

            if taskid is None:
                return (course, None)
            else:
                return (course, course.get_task(taskid))
        else:
            raise web.notfound()
    except:
        raise web.notfound()
Пример #7
0
    def GET(self, courseid):
        """ GET request """

        if User.is_logged_in():
            try:
                course = FrontendCourse(courseid)
                registration_uncomplete = not course.is_open_to_user(User.get_username(), course.is_group_course())
                if registration_uncomplete and course.can_students_choose_group():
                    raise web.seeother("/group/"+courseid)
                elif registration_uncomplete:
                    return renderer.course_unavailable()

                last_submissions = course.get_user_last_submissions(one_per_task=True)
                except_free_last_submissions = []
                for submission in last_submissions:
                    try:
                        submission["task"] = course.get_task(submission['taskid'])
                        except_free_last_submissions.append(submission)
                    except:
                        pass

                return renderer.course(course, except_free_last_submissions)
            except:
                if web.config.debug:
                    raise
                else:
                    raise web.notfound()
        else:
            return renderer.index(False)
Пример #8
0
 def GET(self):
     """ GET request """
     if User.is_logged_in():
         user_input = web.input()
         if "logoff" in user_input:
             User.disconnect()
             return renderer.index(False)
         else:
             return self.call_main()
     else:
         return renderer.index(False)
Пример #9
0
 def POST(self):
     """ POST request: login """
     user_input = web.input()
     if "@authid" in user_input:  # connect
         if User.connect(int(user_input["@authid"]), user_input):
             return self.call_main()
         else:
             return renderer.index(True)
     elif User.is_logged_in():  # register for a course
         return self.call_main()
     else:
         return renderer.index(False)
Пример #10
0
def get_course_and_check_rights(courseid, taskid=None):
    """ Return the course with id, and verify the rights of the user to administer it.
        Raise web.notfound() when there is no such course of if the users has not enough rights.
        If taskid is not None, also returns tyhe tuple (course, task). """
    try:
        if User.is_logged_in():
            course = FrontendCourse(courseid)
            if User.get_username() not in course.get_admins():
                raise web.notfound()

            if taskid is None:
                return course
            else:
                return (course, course.get_task(taskid))
        else:
            raise web.notfound()
    except:
        raise web.notfound()
Пример #11
0
    def GET(self, courseid, taskid):
        """ GET request """
        if User.is_logged_in():
            try:
                course = FrontendCourse(courseid)
                if not course.is_open_to_user(User.get_username()):
                    return renderer.course_unavailable()

                task = course.get_task(taskid)
                if not task.is_visible_by_user(User.get_username()):
                    return renderer.task_unavailable()

                User.get_data().view_task(courseid, taskid)

                userinput = web.input()
                if "submissionid" in userinput and "questionid" in userinput:
                    # Download a previously submitted file
                    submission = submission_manager.get_submission(userinput["submissionid"], True)
                    if submission is None:
                        raise web.notfound()
                    sinput = submission_manager.get_input_from_submission(submission, True)
                    if userinput["questionid"] not in sinput:
                        raise web.notfound()

                    if isinstance(sinput[userinput["questionid"]], dict):
                        # File uploaded previously
                        mimetypes.init()
                        mime_type = mimetypes.guess_type(urllib.pathname2url(sinput[userinput["questionid"]]['filename']))
                        web.header('Content-Type', mime_type[0])
                        return base64.b64decode(sinput[userinput["questionid"]]['value'])
                    else:
                        # Other file, download it as text
                        web.header('Content-Type', 'text/plain')
                        return sinput[userinput["questionid"]]
                else:
                    # Display the task itself
                    return renderer.task(course, task, submission_manager.get_user_submissions(task))
            except:
                if web.config.debug:
                    raise
                else:
                    raise web.notfound()
        else:
            return renderer.index(False)
Пример #12
0
def add_batch_job(course, container_name, inputdata, launcher_name=None, skip_permission=False):
    """
        Add a job in the queue and returns a batch job id.
        inputdata is a dict containing all the keys of get_batch_container_metadata(container_name)[2] BUT the keys "course" and "submission" IF their
        type is "file". (the content of the course and the submission will be automatically included by this function.)
        The values associated are file-like objects for "file" types and  strings for "text" types.
    """

    if not skip_permission:
        if not User.is_logged_in():
            raise Exception("A user must be logged in to submit an object")

        username = User.get_username()
        launcher_name = launcher_name or username

        if username not in course.get_admins():
            raise Exception("The user must be an administrator to start a batch job")

    if container_name not in INGIniousConfiguration.get("batch_containers", []):
        raise Exception("This batch container is not allowed to be started")

    container_args = get_job_manager().get_batch_container_metadata(container_name)[2]
    if container_args is None:
        raise Exception("This batch container is not available")

    # Download the course content and submissions and add them to the input
    if "course" in container_args and container_args["course"]["type"] == "file" and "course" not in inputdata:
        inputdata["course"] = _get_course_data(course)
    if "submissions" in container_args and container_args["submissions"]["type"] == "file" and "submissions" not in inputdata:
        inputdata["submissions"] = _get_submissions_data(course)

    obj = {"courseid": course.get_id(), 'container_name': container_name, "submitted_on": datetime.now()}

    batch_job_id = get_database().batch_jobs.insert(obj)

    launcher_name = launcher_name or "plugin"

    get_job_manager().new_batch_job(container_name, inputdata, lambda r: _batch_job_done_callback(batch_job_id, r),
                                    launcher_name="Frontend - {}".format(launcher_name))

    return batch_job_id
def get_user_last_submissions(query, limit, one_per_task=False):
    """ Get last submissions of a user """
    if not User.is_logged_in():
        raise Exception("A user must be logged in to get his submissions")
    request = query.copy()
    request.update({"username": User.get_username()})

    # We only want the last x task tried, modify the request
    if one_per_task is True:
        data = get_database().submissions.aggregate([
            {"$match": request},
            {"$sort": {"submitted_on": pymongo.DESCENDING}},
            {"$group": {"_id": {"courseid": "$courseid", "taskid": "$taskid"}, "orig_id": {"$first": "$_id"}, "submitted_on": {"$first": "$submitted_on"}}},
            {"$sort": {"submitted_on": pymongo.DESCENDING}},
            {"$limit": limit}
        ])
        request = {"_id": {"$in": [d["orig_id"] for d in list(data)]}}

    cursor = get_database().submissions.find(request)
    cursor.sort([("submitted_on", -1)]).limit(limit)
    return list(cursor)
Пример #14
0
def user_is_submission_owner(submission):
    """ Returns true if the current user is the owner of this jobid, false else """
    if not User.is_logged_in():
        raise Exception("A user must be logged in to verify if he owns a jobid")

    return User.get_username() in submission["username"]
Пример #15
0
    def POST(self, courseid, taskid):
        """ POST a new submission """
        if User.is_logged_in():
            try:
                course = FrontendCourse(courseid)
                if not course.is_open_to_user(User.get_username()):
                    return renderer.course_unavailable()

                task = course.get_task(taskid)
                if not task.is_visible_by_user(User.get_username()):
                    return renderer.task_unavailable()

                User.get_data().view_task(courseid, taskid)
                userinput = web.input()
                if "@action" in userinput and userinput["@action"] == "submit":
                    # Verify rights
                    if not task.can_user_submit(User.get_username()):
                        return json.dumps({"status": "error", "text": "The deadline is over"})

                    # Reparse user input with array for multiple choices
                    init_var = self.list_multiple_multiple_choices_and_files(task)
                    userinput = task.adapt_input_for_backend(web.input(**init_var))

                    if not task.input_is_consistent(userinput):
                        web.header('Content-Type', 'application/json')
                        return json.dumps({"status": "error", "text": "Please answer to all the questions. Your responses were not tested."})
                    del userinput['@action']

                    # Get debug info if the current user is an admin
                    debug = User.get_username() in course.get_admins()

                    # Start the submission
                    submissionid = submission_manager.add_job(task, userinput, debug)

                    web.header('Content-Type', 'application/json')
                    return json.dumps({"status": "ok", "submissionid": str(submissionid)})
                elif "@action" in userinput and userinput["@action"] == "check" and "submissionid" in userinput:
                    if submission_manager.is_done(userinput['submissionid']):
                        web.header('Content-Type', 'application/json')
                        result = submission_manager.get_submission(userinput['submissionid'])
                        result = submission_manager.get_input_from_submission(result)
                        return self.submission_to_json(result, User.get_username() in course.get_admins())
                    else:
                        web.header('Content-Type', 'application/json')
                        return json.dumps({'status': "waiting"})
                elif "@action" in userinput and userinput["@action"] == "load_submission_input" and "submissionid" in userinput:
                    submission = submission_manager.get_submission(userinput["submissionid"])
                    submission = submission_manager.get_input_from_submission(submission)
                    if not submission:
                        raise web.notfound()
                    web.header('Content-Type', 'application/json')
                    return self.submission_to_json(submission, (User.get_username() in course.get_admins()), True)
                else:
                    raise web.notfound()
            except:
                if web.config.debug:
                    raise
                else:
                    raise web.notfound()
        else:
            return renderer.index(False)