Exemplo n.º 1
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)
Exemplo n.º 2
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)
Exemplo n.º 3
0
    def download_submission_set(self, submissions, filename, sub_folders):
        """ Create a tar archive with all the submissions """
        if len(submissions) == 0:
            raise web.notfound(renderer.notfound("There's no submission that matches your request"))
        try:
            tmpfile = tempfile.TemporaryFile()
            tar = tarfile.open(fileobj=tmpfile, mode='w:gz')

            for submission in submissions:
                submission = get_input_from_submission(submission)

                # Compute base path in the tar file
                base_path = "/"
                for sub_folder in sub_folders:
                    if sub_folder == 'taskid':
                        base_path = submission['taskid'] + '/' + base_path
                    elif sub_folder == 'username':
                        base_path = submission['username'] + '/' + base_path

                submission_yaml = StringIO.StringIO(common.custom_yaml.dump(submission).encode('utf-8'))
                submission_yaml_fname = base_path + str(submission["_id"]) + '.test'
                info = tarfile.TarInfo(name=submission_yaml_fname)
                info.size = submission_yaml.len
                info.mtime = time.mktime(submission["submitted_on"].timetuple())

                # Add file in tar archive
                tar.addfile(info, fileobj=submission_yaml)

                # If there is an archive, add it too
                if 'archive' in submission and submission['archive'] is not None and submission['archive'] != "":
                    subfile = get_gridfs().get(submission['archive'])
                    taskfname = base_path + str(submission["_id"]) + '.tgz'

                    # Generate file info
                    info = tarfile.TarInfo(name=taskfname)
                    info.size = subfile.length
                    info.mtime = time.mktime(submission["submitted_on"].timetuple())

                    # Add file in tar archive
                    tar.addfile(info, fileobj=subfile)

                # If there files that were uploaded by the student, add them
                if submission['input'] is not None:
                    for pid, problem in submission['input'].iteritems():
                        # If problem is a dict, it is a file (from the specification of the problems)
                        if isinstance(problem, dict):
                            # Get the extension (match extensions with more than one dot too)
                            DOUBLE_EXTENSIONS = ['.tar.gz', '.tar.bz2', '.tar.bz', '.tar.xz']
                            if not problem['filename'].endswith(tuple(DOUBLE_EXTENSIONS)):
                                _, ext = os.path.splitext(problem['filename'])
                            else:
                                for t_ext in DOUBLE_EXTENSIONS:
                                    if problem['filename'].endswith(t_ext):
                                        ext = t_ext

                            subfile = StringIO.StringIO(base64.b64decode(problem['value']))
                            taskfname = base_path + str(submission["_id"]) + '_uploaded_files/' + pid + ext

                            # Generate file info
                            info = tarfile.TarInfo(name=taskfname)
                            info.size = subfile.len
                            info.mtime = time.mktime(submission["submitted_on"].timetuple())

                            # Add file in tar archive
                            tar.addfile(info, fileobj=subfile)

            # Close tarfile and put tempfile cursor at 0
            tar.close()
            tmpfile.seek(0)

            web.header('Content-Type', 'application/x-gzip', unique=True)
            web.header('Content-Disposition', 'attachment; filename="' + filename + '"', unique=True)
            return tmpfile
        except Exception as e:
            print e
            raise web.notfound()