예제 #1
0
def test_approve_sign_up_for_event(client_session):
    client, session = client_session

    with login_scope(client, 'test_iris_admin', 'test') as client:

        # check the redirection if the user or the event does not exist
        rv = client.get("/events/xxx/sign_up/test_user")
        session.commit()
        assert rv.status_code == 302
        assert rv.location == "http://localhost/problems"
        with client.session_transaction() as cs:
            flash_message = dict(cs['_flashes'])
        assert flash_message['message'] == 'No event xxx or no user test_user'

        rv = client.get("/events/iris_test/sign_up/xxxx")
        session.commit()
        assert rv.status_code == 302
        assert rv.location == "http://localhost/problems"
        with client.session_transaction() as cs:
            flash_message = dict(cs['_flashes'])
        assert flash_message['message'] == 'No event iris_test or no user xxxx'

        add_user(session, 'zz', 'zz', 'zz', 'zz', 'zz', access_level='user')
        _, _, event_team = ask_sign_up_team(session, 'iris_test', 'zz')
        assert not event_team.approved
        rv = client.get('/events/iris_test/sign_up/zz')
        assert rv.status_code == 302
        assert rv.location == "http://localhost/problems"
        session.commit()
        event_team = get_event_team_by_name(session, 'iris_test', 'zz')
        assert event_team.approved
        with client.session_transaction() as cs:
            flash_message = dict(cs['_flashes'])
        assert "is signed up for Event" in flash_message['Successful sign-up']
예제 #2
0
def test_sign_up_for_event(client_session):
    client, session = client_session

    # trigger that the event does not exist
    with login_scope(client, 'test_user', 'test') as client:
        rv = client.get('/events/xxx/sign_up')
        assert rv.status_code == 302
        assert rv.location == 'http://localhost/problems'
        with client.session_transaction() as cs:
            flash_message = dict(cs['_flashes'])
        assert "no event named" in flash_message['message']

    # GET: sign-up to a new controlled event
    add_user(session, 'yy', 'yy', 'yy', 'yy', 'yy', access_level='user')
    with login_scope(client, 'yy', 'yy') as client:
        rv = client.get('/events/iris_test/sign_up')
        assert rv.status_code == 302
        assert rv.location == 'http://localhost/problems'
        with client.session_transaction() as cs:
            flash_message = dict(cs['_flashes'])
        assert "Sign-up request is sent" in flash_message['Request sent']
        # make sure that the database has been updated for our session
        session.commit()
        event_team = get_event_team_by_name(session, 'iris_test', 'yy')
        assert not event_team.approved
        # check that we are informing the user that he has to wait for approval
        rv = client.get('/events/iris_test')
        assert rv.status_code == 200
        assert b'Waiting approval...' in rv.data

    # GET: sign-up to a new uncontrolled event
    event = get_event(session, 'boston_housing_test')
    event.is_controled_signup = False
    session.commit()
    with login_scope(client, 'yy', 'yy') as client:
        rv = client.get('/events/boston_housing_test/sign_up')
        assert rv.status_code == 302
        assert (rv.location ==
                'http://localhost/events/boston_housing_test/sandbox')
        with client.session_transaction() as cs:
            flash_message = dict(cs['_flashes'])
        assert "is signed up for" in flash_message['Successful sign-up']
        # make sure that the database has been updated for our session
        session.commit()
        event_team = get_event_team_by_name(session, 'boston_housing_test',
                                            'yy')
        assert event_team.approved
예제 #3
0
def my_submissions(event_name):
    """Landing page of all user's submission information.

    Parameters
    ----------
    event_name : str
        The name of the event.
    """
    event = get_event(db.session, event_name)
    if not is_accessible_event(db.session, event_name,
                               flask_login.current_user.name):
        return redirect_to_user(
            '{}: no event named "{}"'
            .format(flask_login.current_user.firstname, event_name)
        )
    if app.config['TRACK_USER_INTERACTION']:
        add_user_interaction(
            db.session, interaction='looking at my_submissions',
            user=flask_login.current_user, event=event
        )
    if not is_accessible_code(db.session, event_name,
                              flask_login.current_user.name):
        error_str = ('No access to my submissions for event {}. If you have '
                     'already signed up, please wait for approval.'
                     .format(event.name))
        return redirect_to_user(error_str)

    # Doesn't work if team mergers are allowed
    event_team = get_event_team_by_name(db.session, event_name,
                                        flask_login.current_user.name)
    leaderboard_html = event_team.leaderboard_html
    failed_leaderboard_html = event_team.failed_leaderboard_html
    new_leaderboard_html = event_team.new_leaderboard_html
    admin = is_admin(db.session, event_name, flask_login.current_user.name)
    if event.official_score_type.is_lower_the_better:
        sorting_direction = 'asc'
    else:
        sorting_direction = 'desc'
    return render_template('leaderboard.html',
                           leaderboard_title='Trained submissions',
                           leaderboard=leaderboard_html,
                           failed_leaderboard=failed_leaderboard_html,
                           new_leaderboard=new_leaderboard_html,
                           sorting_column_index=4,
                           sorting_direction=sorting_direction,
                           event=event,
                           admin=admin)
예제 #4
0
def test_approve_users_remove(client_session):
    client, session = client_session

    # create 2 new users
    add_user(session, 'xx', 'xx', 'xx', 'xx', 'xx', access_level='user')
    add_user(session, 'yy', 'yy', 'yy', 'yy', 'yy', access_level='asked')
    # ask for sign up for an event for the first user
    _, _, event_team = ask_sign_up_team(session, 'iris_test', 'xx')

    with login_scope(client, 'test_iris_admin', 'test') as client:

        # GET check that we get all new user to be approved
        rv = client.get('/approve_users')
        assert rv.status_code == 200
        # line for user approval
        assert b'yy: yy yy - yy' in rv.data
        # line for the event approval
        assert b'iris_test - xx'

        # POST check that we are able to approve a user and event
        data = ImmutableMultiDict([('submit_button', 'Remove!'),
                                   ('approve_users', 'yy'),
                                   ('approve_event_teams', str(event_team.id))
                                   ])
        rv = client.post('/approve_users', data=data)
        assert rv.status_code == 302
        assert rv.location == 'http://localhost/problems'

        # ensure that the previous change have been committed within our
        # session
        session.commit()
        user = get_user_by_name(session, 'yy')
        assert user is None
        event_team = get_event_team_by_name(session, 'iris_test', 'xx')
        assert event_team is None
        with client.session_transaction() as cs:
            flash_message = dict(cs['_flashes'])
            print(flash_message)
        assert re.match(
            r"Removed users:\nyy\nRemoved event_team:\n"
            r"Event\(iris_test\)/Team\(.*xx.*\)\n",
            flash_message['Removed users'])
예제 #5
0
파일: ramp.py 프로젝트: tomMoral/ramp-board
def problems():
    """Landing page showing all the RAMP problems."""
    user = (flask_login.current_user
            if flask_login.current_user.is_authenticated else None)
    admin = user.access_level == 'admin' if user is not None else False
    if app.config['TRACK_USER_INTERACTION']:
        add_user_interaction(
            db.session, interaction='looking at problems', user=user
        )
    problems = get_problem(db.session, None)

    for problem in problems:
        for event in problem.events:
            # check the state of the event
            now = datetime.datetime.now()
            start = event.opening_timestamp
            start_collab = event.public_opening_timestamp
            end = event.closing_timestamp
            if now < start or now >= end:
                event.state = 'close'
            elif now >= start and now < start_collab:
                event.state = 'competitive'
            elif now >= start and now >= start_collab and now < end:
                event.state = 'collab'
            if user:
                signed = get_event_team_by_name(
                                    db.session, event.name,
                                    flask_login.current_user.name)
                if not signed:
                    event.state_user = '******'
                elif signed.approved:
                    event.state_user = '******'
                elif signed:
                    event.state_user = '******'
            else:
                event.state_user = '******'

    # problems = Problem.query.order_by(Problem.id.desc())
    return render_template('problems.html',
                           problems=problems,
                           admin=admin)
예제 #6
0
def test_update_leaderboard_functions(session_toy_function):
    event_name = 'iris_test'
    user_name = 'test_user'
    for leaderboard_type in ['public', 'private', 'failed',
                             'public competition', 'private competition']:
        leaderboard = get_leaderboard(session_toy_function, leaderboard_type,
                                      event_name)
        assert leaderboard is None
    leaderboard = get_leaderboard(session_toy_function, 'new', event_name)
    assert leaderboard

    event = get_event(session_toy_function, event_name)
    assert event.private_leaderboard_html is None
    assert event.public_leaderboard_html_with_links is None
    assert event.public_leaderboard_html_no_links is None
    assert event.failed_leaderboard_html is None
    assert event.public_competition_leaderboard_html is None
    assert event.private_competition_leaderboard_html is None
    assert event.new_leaderboard_html

    event_team = get_event_team_by_name(session_toy_function, event_name,
                                        user_name)
    assert event_team.leaderboard_html is None
    assert event_team.failed_leaderboard_html is None
    assert event_team.new_leaderboard_html

    event_teams = (session_toy_function.query(EventTeam)
                                       .filter_by(event=event)
                                       .all())
    for et in event_teams:
        assert et.leaderboard_html is None
        assert et.failed_leaderboard_html is None
        assert et.new_leaderboard_html

    # run the dispatcher to process the different submissions
    config = read_config(database_config_template())
    event_config = read_config(ramp_config_template())
    dispatcher = Dispatcher(
        config, event_config, n_workers=-1, hunger_policy='exit'
    )
    dispatcher.launch()
    session_toy_function.commit()

    update_leaderboards(session_toy_function, event_name)
    event = get_event(session_toy_function, event_name)
    assert event.private_leaderboard_html
    assert event.public_leaderboard_html_with_links
    assert event.public_leaderboard_html_no_links
    assert event.failed_leaderboard_html
    assert event.public_competition_leaderboard_html
    assert event.private_competition_leaderboard_html
    assert event.new_leaderboard_html is None

    update_user_leaderboards(session_toy_function, event_name, user_name)
    event_team = get_event_team_by_name(session_toy_function, event_name,
                                        user_name)
    assert event_team.leaderboard_html
    assert event_team.failed_leaderboard_html
    assert event_team.new_leaderboard_html is None

    update_all_user_leaderboards(session_toy_function, event_name)
    event_teams = (session_toy_function.query(EventTeam)
                                       .filter_by(event=event)
                                       .all())
    for et in event_teams:
        assert et.leaderboard_html
        assert et.failed_leaderboard_html
        assert et.new_leaderboard_html is None
예제 #7
0
파일: ramp.py 프로젝트: mehdidc/ramp-board
def sandbox(event_name):
    """Landing page for the user's sandbox.

    Parameters
    ----------
    event_name : str
        The event name.
    """
    event = get_event(db.session, event_name)
    if not is_accessible_event(db.session, event_name,
                               flask_login.current_user.name):
        return redirect_to_user(u'{}: no event named "{}"'.format(
            flask_login.current_user.firstname, event_name))
    if not is_accessible_code(db.session, event_name,
                              flask_login.current_user.name):
        error_str = ('No access to sandbox for event {}. If you have '
                     'already signed up, please wait for approval.'.format(
                         event.name))
        return redirect_to_user(error_str)
    # setup the webpage when loading
    # we use the code store in the sandbox to show to the user
    sandbox_submission = get_submission_by_name(db.session, event_name,
                                                flask_login.current_user.name,
                                                event.ramp_sandbox_name)
    event_team = get_event_team_by_name(db.session, event_name,
                                        flask_login.current_user.name)
    # initialize the form for the code
    # The amount of python magic we have to do for rendering a variable
    # number of textareas, named and populated at run time, is mind
    # boggling.

    # First we need to make sure CodeForm is empty
    # for name_code in CodeForm.names_codes:
    #     name, _ = name_code
    #     delattr(CodeForm, name)
    CodeForm.names_codes = []

    # Then we create named fields in the CodeForm class for each editable
    # submission file. They have to be populated when the code_form object
    # is created, so we also create a code_form_kwargs dictionary and
    # populate it with the codes.
    code_form_kwargs = {}
    for submission_file in sandbox_submission.files:
        if submission_file.is_editable:
            f_field = submission_file.name
            setattr(CodeForm, f_field, StringField(u'Text', widget=TextArea()))
            code_form_kwargs[f_field] = submission_file.get_code()
    code_form_kwargs['prefix'] = 'code'
    code_form = CodeForm(**code_form_kwargs)
    # Then, to be able to iterate over the files in the sandbox.html
    # template, we also fill a separate table of pairs (file name, code).
    # The text areas in the template will then have to be created manually.
    for submission_file in sandbox_submission.files:
        if submission_file.is_editable:
            code_form.names_codes.append(
                (submission_file.name, submission_file.get_code()))

    # initialize the submission field and the the uploading form
    submit_form = SubmitForm(submission_name=event_team.last_submission_name,
                             prefix='submit')
    upload_form = UploadForm(prefix='upload')

    admin = is_admin(db.session, event_name, flask_login.current_user.name)
    if request.method == 'GET':
        return render_template('sandbox.html',
                               submission_names=sandbox_submission.f_names,
                               code_form=code_form,
                               submit_form=submit_form,
                               upload_form=upload_form,
                               event=event,
                               admin=admin)

    if request.method == 'POST':
        if ('code-csrf_token' in request.form
                and code_form.validate_on_submit()):
            try:
                for submission_file in sandbox_submission.files:
                    if submission_file.is_editable:
                        old_code = submission_file.get_code()
                        submission_file.set_code(
                            request.form[submission_file.name])
                        new_code = submission_file.get_code()
                        diff = '\n'.join(
                            difflib.unified_diff(old_code.splitlines(),
                                                 new_code.splitlines()))
                        similarity = difflib.SequenceMatcher(
                            a=old_code, b=new_code).ratio()
                        if app.config['TRACK_USER_INTERACTION']:
                            add_user_interaction(
                                db.session,
                                interaction='save',
                                user=flask_login.current_user,
                                event=event,
                                submission_file=submission_file,
                                diff=diff,
                                similarity=similarity)
            except Exception as e:
                return redirect_to_sandbox(event, u'Error: {}'.format(e))
            return redirect_to_sandbox(
                event,
                'You submission has been saved. You can safely comeback to '
                'your sandbox later.',
                is_error=False,
                category='File saved')

        elif request.files:
            upload_f_name = secure_filename(request.files['file'].filename)
            upload_name = upload_f_name.split('.')[0]
            # TODO: create a get_function
            upload_workflow_element = WorkflowElement.query.filter_by(
                name=upload_name, workflow=event.workflow).one_or_none()
            if upload_workflow_element is None:
                return redirect_to_sandbox(
                    event,
                    u'{} is not in the file list.'.format(upload_f_name))

            # TODO: create a get_function
            submission_file = SubmissionFile.query.filter_by(
                submission=sandbox_submission,
                workflow_element=upload_workflow_element).one()
            if submission_file.is_editable:
                old_code = submission_file.get_code()

            tmp_f_name = os.path.join(tempfile.gettempdir(), upload_f_name)
            request.files['file'].save(tmp_f_name)
            file_length = os.stat(tmp_f_name).st_size
            if (upload_workflow_element.max_size is not None
                    and file_length > upload_workflow_element.max_size):
                return redirect_to_sandbox(
                    event, u'File is too big: {} exceeds max size {}'.format(
                        file_length, upload_workflow_element.max_size))
            if submission_file.is_editable:
                try:
                    with open(tmp_f_name) as f:
                        code = f.read()
                        submission_file.set_code(code)
                except Exception as e:
                    return redirect_to_sandbox(event, u'Error: {}'.format(e))
            else:
                # non-editable files are not verified for now
                dst = os.path.join(sandbox_submission.path, upload_f_name)
                shutil.copy2(tmp_f_name, dst)
            logger.info(u'{} uploaded {} in {}'.format(
                flask_login.current_user.name, upload_f_name, event))

            if submission_file.is_editable:
                new_code = submission_file.get_code()
                diff = '\n'.join(
                    difflib.unified_diff(old_code.splitlines(),
                                         new_code.splitlines()))
                similarity = difflib.SequenceMatcher(a=old_code,
                                                     b=new_code).ratio()
                if app.config['TRACK_USER_INTERACTION']:
                    add_user_interaction(db.session,
                                         interaction='upload',
                                         user=flask_login.current_user,
                                         event=event,
                                         submission_file=submission_file,
                                         diff=diff,
                                         similarity=similarity)
            else:
                if app.config['TRACK_USER_INTERACTION']:
                    add_user_interaction(db.session,
                                         interaction='upload',
                                         user=flask_login.current_user,
                                         event=event,
                                         submission_file=submission_file)

            return redirect(request.referrer)
            # TODO: handle different extensions for the same workflow element
            # ie: now we let upload eg external_data.bla, and only fail at
            # submission, without giving a message

        elif ('submit-csrf_token' in request.form
              and submit_form.validate_on_submit()):
            new_submission_name = request.form['submit-submission_name']
            if not 4 < len(new_submission_name) < 20:
                return redirect_to_sandbox(
                    event, 'Submission name should have length between 4 and '
                    '20 characters.')
            try:
                new_submission_name.encode('ascii')
            except Exception as e:
                return redirect_to_sandbox(event, u'Error: {}'.format(e))
            try:
                new_submission = add_submission(db.session, event_name,
                                                event_team.team.name,
                                                new_submission_name,
                                                sandbox_submission.path)
            except DuplicateSubmissionError:
                return redirect_to_sandbox(
                    event,
                    u'Submission {} already exists. Please change the name.'.
                    format(new_submission_name))
            except MissingExtensionError as e:
                return redirect_to_sandbox(event, 'Missing extension')
            except TooEarlySubmissionError as e:
                return redirect_to_sandbox(event, str(e))

            logger.info(u'{} submitted {} for {}.'.format(
                flask_login.current_user.name, new_submission.name,
                event_team))
            if event.is_send_submitted_mails:
                admin_users = User.query.filter_by(access_level='admin')
                for admin in admin_users:
                    subject = 'Submission {} sent for training'.format(
                        new_submission.name)
                    body = """A new submission have been submitted:
                    event: {}
                    user: {}
                    submission: {}
                    submission path: {}
                    """.format(event_team.event.name,
                               flask_login.current_user.name,
                               new_submission.name, new_submission.path)
                    send_mail(admin, subject, body)
            if app.config['TRACK_USER_INTERACTION']:
                add_user_interaction(db.session,
                                     interaction='submit',
                                     user=flask_login.current_user,
                                     event=event,
                                     submission=new_submission)

            return redirect_to_sandbox(event,
                                       u'{} submitted {} for {}'.format(
                                           flask_login.current_user.firstname,
                                           new_submission.name, event_team),
                                       is_error=False,
                                       category='Submission')

    admin = is_admin(db.session, event_name, flask_login.current_user.name)
    return render_template('sandbox.html',
                           submission_names=sandbox_submission.f_names,
                           code_form=code_form,
                           submit_form=submit_form,
                           upload_form=upload_form,
                           event=event,
                           admin=admin)