def login():
    check = is_acceptable_route(True)
    if not check[0]:
        return check[1]
    assert check[1] is None
    if is_logged_in():
        return redirect('/')
    # TODO What to do if the user is currently logged in?
    if request.method == 'POST':
        login_data = request.json
        user, message = validate_login_data(login_data)
        if not user:
            # This should never happen.
            response = jsonify(message)
            response.status_code = 400
            return response
        session['email'] = user.email
        session['just_logged_in'] = True
        #  TODO  Change something so as to see the login state. Menu changes of course.
        return jsonify('login_success')
    return render_template(
        'login.html',
        page=md(
            base_page, {
                'pagetitle':
                'Login',
                'data':
                'Please login using email and passphrase given at registration time.',
            }))
def logout():
    check = is_acceptable_route(True)
    if not check[0]:
        return check[1]
    assert check[1] is None
    session.pop('email', None)
    return redirect('/')
def registration_update():
    check = utils.is_acceptable_route()
    if not check[0]:
        return check[1]
    assert check[1] is None
    if not utils.is_logged_in():
        return redirect('/')
    user = User.query.filter_by(email=session['email']).first()
    if request.method == 'POST':
        registration_data = request.json
        status, message = validate_registration_data(registration_data)
        if not status:
            # NB This should never be executed.
            response = jsonify(message)
            response.status_code = 400
            return response
        for field in registration_data.keys():
            if field == 'passphrase':
                if registration_data['passphrase']:
                    user.passphrase = utils.hash_passphrase(
                        registration_data['passphrase'])
            elif field in user.__dict__ and user.__dict__[
                    field] != registration_data[field]:
                user.__dict__[field] = registration_data[field]
        db.session.commit()
        session['just_updated_register'] = True
        return jsonify('registration_update_success')
    return render_template('register.html',
                           page=utils.md(
                               base_page, {
                                   'pagetitle':
                                   'Registration Details Updating',
                                   'data':
                                   Markup('''
Here you can edit your registration information.
</p>
<p>
If you do not wish to make any changes just navigate away from this page. There
is no specific button for "leave things as they are" that is the default action.
(Or rather inaction.)
'''),
                                   'email':
                                   user.email,
                                   'name':
                                   user.name,
                                   'phone':
                                   user.phone,
                                   'country':
                                   user.country,
                                   'submit_button':
                                   'Save',
                                   'passphrase_required':
                                   'false',
                                   'countries':
                                   sorted(countries),
                               }))
def register():
    check = utils.is_acceptable_route()
    if not check[0]:
        return check[1]
    assert check[1] is None
    if utils.is_logged_in():
        return redirect('/')
    if request.method == 'POST':
        registration_data = request.json
        status, message = validate_registration_data(registration_data)
        if not status:
            # NB This should never be executed.
            response = jsonify(message)
            response.status_code = 400
            return response
        if not registration_data['passphrase']:
            # NB This should never be executed.
            response = jsonify('No passphrase for new registration.')
            response.status_code = 400
            return response
        if User.query.filter_by(email=registration_data['email']).first():
            # Currently this can happen as client-site checking is not implemented.
            # TODO implement client side checking so this becomes redundant.
            response = jsonify('The email address is already in use.')
            response.status_code = 400
            return response
        registration_data['passphrase'] = utils.hash_passphrase(
            registration_data['passphrase'])
        db.session.add(User(**registration_data))
        db.session.commit()
        session['just_registered'] = True
        return jsonify('register_success')
    default_country = 'United Kingdom'
    assert default_country in countries
    return render_template(
        'register.html',
        page=utils.md(
            base_page, {
                'pagetitle':
                'Register',
                'data':
                'Register here for submitting proposals to the ACCU {} Conference'
                .format(year),
                'submit_button':
                'Register',
                'passphrase_required':
                'true',
                'country':
                default_country,
                'countries':
                sorted(countries),
            }))
def review_list():
    check = is_acceptable_route()
    if not check[0]:
        return check[1]
    assert check[1] is None
    if is_logged_in():
        user = User.query.filter_by(email=session['email']).first()
        if not user:
            return render_template(
                '/general.html',
                page=md(
                    base_page, {
                        'pagetitle':
                        'Review List Failed',
                        'data':
                        'Logged in user is not a registered user. This cannot happen.',
                    }))
        if user.role != Role.reviewer:
            return render_template(
                '/general.html',
                page=md(
                    base_page, {
                        'pagetitle': 'Review List Failed',
                        'data': 'Logged in user is not a registered reviewer.',
                    }))
        # TODO reviewer cannot review proposed proposals (done) but what about being a presenter?
        proposals = [(p.id, p.title, lead.presenter.name, p.session_type.value,
                      already_reviewed(p, user)) for p in Proposal.query.all()
                     if p.proposer != user for lead in p.proposal_presenters
                     if lead.is_lead]
        return render_template(
            '/review_list.html',
            page=md(
                base_page, {
                    'pagetitle': 'List of Proposals',
                    'data': 'Please click on the proposal you wish to review.',
                    'proposals': proposals,
                }))
    return render_template(
        'review_list.html',
        page=md(
            base_page, {
                'pagetitle':
                'Review List Failed',
                'data':
                'You must be registered, logged in, and a reviewer to review proposals',
            }))
def my_proposals():
    check = is_acceptable_route()
    if not check[0]:
        return check[1]
    assert check[1] is None
    if is_logged_in():
        user = User.query.filter_by(email=session['email']).first()
        return render_template('my_proposals.html', page=md(base_page, {
            'pagetitle': 'My Proposals',
            'data': 'The following are your current proposals. Click on a list entry to review that proposal and possibly change it should you wish to.',
            'proposals': [{'title': proposal.title, 'id': proposal.id} for proposal in user.proposals]
        }))
    return render_template('general.html', page=md(base_page, {
        'pagetitle': 'My Proposals Failure',
        'year': year,
        'data': 'You must be registered and logged in to discover your current proposals.',
    }))
def registration_update_success():
    check = utils.is_acceptable_route()
    if not check[0]:
        return check[1]
    assert check[1] is None
    if 'just_updated_register' not in session:
        return redirect('/')
    session.pop('just_updated_registration', False)
    if not utils.is_logged_in():
        return redirect('/')
    return render_template(
        'general.html',
        page=utils.md(
            base_page, {
                'pagetitle': 'Registration Update Successful',
                'data': 'Your registration details were successfully updated.',
            }))
def proposal_update_success():
    check = is_acceptable_route()
    if not check[0]:
        return check[1]
    assert check[1] is None
    if 'just_updated' in session:
        session.pop('just_updated', None)
        return render_template('general.html', page=md(base_page, {
            'pagetitle': 'Proposal Update Successful',
            'data': '''
Thank you, you have successfully updated your proposal for the ACCU {} conference!
If you need to edit it again you can via the 'My Proposal' menu item.
'''.format(year),
        }))
    return render_template('general.html', page=md(base_page, {
        'pagetitle': 'Update Failed',
        'data': 'You must be registered and logged in to submit a proposal.',
    }))
def next_proposal(id, unreviewed):
    check = is_acceptable_route()
    if not check[0]:
        return check[1]
    assert check[1] is None
    if is_logged_in():
        user = User.query.filter_by(email=session['email']).first()
        if user.role != Role.reviewer:
            return render_template(
                '/general.html',
                page=md(
                    base_page, {
                        'pagetitle': 'Proposal Navigation Failed',
                        'data': 'Logged in user is not a registered reviewer.',
                    }))
        if not unreviewed:
            number_of_proposals = Proposal.query.count()
            for i in range(id + 1, number_of_proposals + 1):
                if not _reviewer_is_in_proposal_index(user, i):
                    return jsonify(i)
            response = jsonify("Requested proposal does not exist.")
            response.status_code = 400
            return response
        i = id + 1
        while True:
            proposal = Proposal.query.filter_by(id=i).first()
            if not proposal:
                break
            if not already_reviewed(proposal, user):
                if not _reviewer_is_in_proposal(user, proposal):
                    return jsonify(i)
            i += 1
        response = jsonify("Requested proposal does not exist.")
        response.status_code = 400
        return response
    return render_template(
        'general.html',
        page=md(
            base_page, {
                'pagetitle':
                'Proposal Navigation Failed',
                'data':
                'You must be registered, logged in, and a reviewer to review a proposal',
            }))
def register_success():
    check = utils.is_acceptable_route()
    if not check[0]:
        return check[1]
    assert check[1] is None
    if 'just_registered' not in session:
        return redirect('/')
    session.pop('just_registered', None)
    return render_template("general.html",
                           page=utils.md(
                               base_page, {
                                   'pagetitle':
                                   'Registration Successful',
                                   'data':
                                   Markup('''
You have successfully registered for submitting proposals for the ACCU Conference.
</p>
</p>
Please login and start preparing your proposal for the conference.
''')
                               }))
Example #11
0
def login():
    check = is_acceptable_route()
    if not check[0]:
        return check[1]
    assert check[1] is None
    # TODO What to do if the user is currently logged in?
    page = {
        'type': 'Login',
        'year': year,
    }
    if request.method == 'POST':
        login_data = request.json
        user, message = validate_login_data(login_data)
        if not user:
            return render_template('failure.html',
                                   page=md(page, {'data': message}))
        session['email'] = user.email
        #  TODO  Change something so as to see the login state. Menu changes of course.
        return render_template('success.html',
                               page=md(page, {'data': 'Login successful.'}))
    else:
        return render_template('login.html', page=page)
def login_success():
    check = is_acceptable_route(True)
    if not check[0]:
        return check[1]
    assert check[1] is None
    if 'just_logged_in' not in session:
        return redirect('/')
    session.pop('just_logged_in', None)
    if is_logged_in():
        return render_template('general.html',
                               page=md(
                                   base_page, {
                                       'pagetitle':
                                       'Login Successful',
                                       'data':
                                       Markup('''
Login successful.
</p>
<p>
The menu on the left should now show entries for submitting a new proposal,
amending the registration details for the logged in user, listing the previously
submitted proposals, or logging out.
</p>
<p>
if you have not previously submitted a proposal the "My Proposals" list will be empty.
Once you have submitted one or more proposals, they can be amended via the
"My Proposals" list.
'''),
                                   }))
    return render_template(
        'login.html',
        page=md(
            base_page, {
                'pagetitle':
                'Login Failure',
                'data':
                'Please login using email and passphrase given at registration time.',
            }))
def proposal_update(id):
    check = is_acceptable_route()
    if not check[0]:
        return check[1]
    assert check[1] is None
    if is_logged_in():
        if request.method == 'POST':
            user = User.query.filter_by(email=session['email']).first()
            if user:
                proposal_data = request.json
                status, message = validate_proposal_data(proposal_data)
                if not status:
                    # NB This should never be executed.
                    response = jsonify(message)
                    response.status_code = 400
                    return response
                proposal = Proposal.query.filter_by(id=id).first()
                changeset = {}
                for item in ('title', 'summary', 'session_type', 'keywords', 'no_video', 'audience', 'notes', 'constraints'):
                    if item in proposal_data:
                        if item == 'session_type':
                            datum = SessionType(proposal_data[item])
                        elif item == 'audience':
                            datum = SessionAudience(proposal_data[item])
                        else:
                            datum = proposal_data[item]
                        if datum != proposal.__dict__[item]:
                            changeset[item] = datum
                if changeset:
                    Proposal.query.filter_by(id=id).update(changeset)
                assert len(proposal.presenters) == len(proposal_data['presenters'])
                # TODO What about changing of lead?
                for i, presenter in enumerate(proposal.presenters):
                    changeset = {}
                    presenters_data = proposal_data['presenters'][i]
                    for item in ('email', 'name', 'bio', 'country'):
                        if item in presenters_data and presenter.__dict__[item] != presenters_data[item]:
                            changeset[item] = presenters_data[item]
                    if changeset:
                        Presenter.query.filter_by(email=proposal.presenters[i].email).update(changeset)
                db.session.commit()
                if proposal.scores:
                    for score in proposal.scores:
                        send_email_to(
                            score.scorer.email,
                            score.scorer.name,
                            'ACCUConf Proposal {} has been updated'.format(proposal.title),
                            '''
An email to let you know that the ACCUConf proposal:

{}

has been updated by the submitter and you have already scored that proposal.
'''.format(proposal.title)
                        )
                session['just_updated'] = True
                return jsonify('proposal_update_success')
            return render_template('general.html', page=md(base_page, {
                'pagetitle': 'Proposal Update POST Error',
                'data': 'The logged in user is not in database. This cannot happen.',
            }))
        proposal = Proposal.query.filter_by(id=id).first()
        proposal_presenter = ProposalPresenter.query.filter_by(proposal=proposal).first()
        if not proposal:
            return render_template('general.html', page=md(base_page, {
                'pagetitle': 'Proposal Not Found',
                'data': 'The requested proposal cannot be found.'
            }))
        # TODO How to deal with multi-presenter proposals?
        presenter = proposal.presenters[0]
        return render_template('submit.html', page=md(base_page, {
            'pagetitle': 'Update a proposal',
            'data': Markup(submit_form_preface_markup + '''
</p>
<p>
This page should present all the data of the submission using editable fields.
If you wish to change anything amend the field as needed and click Update.
</p>
<p>
If you do not wish to make any changes just navigate away from this page. There
is no specific button for "leave things as they are" that is the default action.
(Or rather inaction.)
'''),
            'title': proposal.title,
            'session_type': proposal.session_type.value,
            'summary': proposal.summary,
            'audience': proposal.audience.value,
            'keywords': proposal.keywords,
            'no_video': proposal.no_video,
            'notes': proposal.notes,
            'constraints': proposal.constraints,
            'presenter': {
                'email': presenter.email,
                'name': presenter.name,
                'is_lead': proposal_presenter.is_lead,
                'bio': presenter.bio,
                'country': presenter.country,
            },
            'countries': sorted(countries),
            'submit_label': 'Update',
            'proposal_id': id,
        }))
    return render_template('general.html', page=md(base_page, {
        'pagetitle': 'Proposal Update Failure',
        'data': 'You must be registered and logged in to update a proposal.',
    }))
Example #14
0
def test_is_acceptable_route_maintenance(monkeypatch):
    monkeypatch.setitem(app.config, 'MAINTENANCE', True)
    assert not utils.is_acceptable_route()[0]
def review_proposal(id):
    check = is_acceptable_route()
    if not check[0]:
        return check[1]
    assert check[1] is None
    if is_logged_in():
        reviewer = User.query.filter_by(email=session['email']).first()
        if request.method == 'POST':
            review_data = request.json
            if not reviewer:
                response = jsonify(
                    'Logged in person is not a reviewer. This cannot happen.')
                response.status_code = 400
                return response
            proposal = Proposal.query.filter_by(id=id).first()
            if not proposal:
                response = jsonify(
                    'Proposal cannot be found. This cannot happen.')
                response.status_code = 400
                return response
            # TODO Is this the right way of doing this?
            score = Score.query.filter_by(proposal=proposal,
                                          scorer=reviewer).all()
            if score:
                assert len(score) == 1
                score[0].score = review_data['score']
            else:
                db.session.add(Score(proposal, reviewer, review_data['score']))
            if review_data['comment_for_proposer']:
                comment = CommentForProposer.query.filter_by(
                    proposal=proposal, commenter=reviewer).all()
                if comment:
                    comment[0].comment = review_data['comment_for_proposer']
                else:
                    db.session.add(
                        CommentForProposer(
                            proposal, reviewer,
                            review_data['comment_for_proposer']))
            if review_data['comment_for_committee']:
                comment = CommentForCommittee.query.filter_by(
                    proposal=proposal, commenter=reviewer).all()
                if comment:
                    comment[0].comment = review_data['comment_for_committee']
                else:
                    db.session.add(
                        CommentForCommittee(
                            proposal, reviewer,
                            review_data['comment_for_committee']))
            db.session.commit()
            return jsonify('Review stored.')
        if not reviewer:
            return render_template(
                '/general.html',
                page=md(
                    base_page, {
                        'pagetitle':
                        'Review Proposal Failed',
                        'data':
                        'Logged in user is not a registered user. This cannot happen.',
                    }))
        if reviewer.role != Role.reviewer:
            return render_template(
                '/general.html',
                page=md(
                    base_page, {
                        'pagetitle': 'Review Proposal Failed',
                        'data': 'Logged in user is not a registered reviewer.',
                    }))
        number_of_proposals = Proposal.query.count()
        if not (1 <= id <= number_of_proposals):
            return render_template(
                'general.html',
                page=md(
                    base_page, {
                        'pagetitle': 'Review Proposal Failed',
                        'data': 'Requested proposal does not exist.',
                    }))
        proposal = Proposal.query.filter_by(id=id).first()
        presenters = [{
            'name': p.name,
            'bio': p.bio
        } for p in proposal.presenters]
        score = ''
        comment_for_proposer = ''
        comment_for_committee = ''
        if already_reviewed(proposal, reviewer):
            scores = [s for s in reviewer.scores if s.proposal == proposal]
            assert len(scores) == 1
            score = scores[0].score
            comments_for_proposer = [
                c for c in reviewer.comments_for_proposer
                if c.proposal == proposal
            ]
            if comments_for_proposer:
                comment_for_proposer = comments_for_proposer[0].comment
            comments_for_committee = [
                c for c in reviewer.comments_for_committee
                if c.proposal == proposal
            ]
            if comments_for_committee:
                comment_for_committee = comments_for_committee[0].comment
        has_next = id < number_of_proposals
        if has_next:
            for i in range(id + 1, number_of_proposals + 1):
                if not _reviewer_is_in_proposal_index(reviewer, i):
                    break
            else:
                has_next = False
        has_previous = id > 1
        if has_previous:
            for i in range(id - 1, 0, -1):
                if not _reviewer_is_in_proposal_index(reviewer, i):
                    break
            else:
                has_previous = False
        return render_template(
            '/review_proposal.html',
            page=md(
                base_page, {
                    'pagetitle': 'Proposal to Review',
                    'data':
                    'There is no specific "do nothing" button, to not do anything simply navigate away from this page.',
                    'proposal_id': id,
                    'title': proposal.title,
                    'summary': proposal.summary,
                    'session_type':
                    sessiontype_descriptions[proposal.session_type],
                    'audience': proposal.audience.value,
                    'notes': proposal.notes,
                    'presenters': presenters,
                    'button_label': 'Submit' if not score else 'Update',
                    'score': score,
                    'comment_for_proposer': comment_for_proposer,
                    'comment_for_committee': comment_for_committee,
                    'has_previous': has_previous,
                    'has_next': has_next,
                }))
    return render_template(
        'general.html',
        page=md(
            base_page, {
                'pagetitle':
                'Review Proposal Failed',
                'data':
                'You must be registered, logged in, and a reviewer to review a proposal',
            }))
def submit():
    check = is_acceptable_route()
    if not check[0]:
        return check[1]
    assert check[1] is None
    if is_logged_in():
        if request.method == 'POST':
            user = User.query.filter_by(email=session['email']).first()
            if user:
                proposal_data = request.json
                status, message = validate_proposal_data(proposal_data)
                if not status:
                    # NB This should never be executed.
                    response = jsonify(message)
                    response.status_code = 400
                    return response
                proposal = Proposal(
                    user,
                    proposal_data.get('title').strip(),
                    proposal_data.get('summary').strip(),
                    SessionType(proposal_data.get('session_type').strip()),
                    SessionAudience(proposal_data.get('audience').strip()) if proposal_data.get('audience') else SessionAudience.all,
                    proposal_data.get('keywords').strip() if proposal_data.get('keywords') else '',
                    proposal_data.get('no_video') if proposal_data.get('no_video') else False,
                    proposal_data.get('notes').strip() if proposal_data.get('notes') else '',
                    proposal_data.get('constraints').strip() if proposal_data.get('constraints') else '',
                )
                db.session.add(proposal)
                presenters_data = proposal_data.get('presenters')
                for presenter_data in presenters_data:
                    presenter = Presenter.query.filter_by(email=presenter_data['email']).all()
                    if presenter:
                        assert len(presenter) == 1
                        presenter = presenter[0]
                        if presenter.name != presenter_data['name']:
                            presenter.name = presenter_data['name']
                        if presenter.bio != presenter_data['bio']:
                            presenter.bio = presenter_data['bio']
                        if presenter.country != presenter_data['country']:
                            presenter.country = presenter_data['country']
                    else:
                        presenter = Presenter(
                            presenter_data['email'],
                            presenter_data['name'],
                            presenter_data['bio'],
                            presenter_data['country'],
                        )
                        db.session.add(presenter)
                    ProposalPresenter(proposal, presenter, presenter_data['is_lead'])
                db.session.commit()
                session['just_submitted'] = True
                return jsonify('submit_success')
            return render_template('general.html', page=md(base_page, {
                'pagetitle': 'Submit POST Error',
                'data': 'The logged in user is not in database. This cannot happen.',
            }))
        user = User.query.filter_by(email=session['email']).first()
        if user:
            presenter = Presenter.query.filter_by(email=user.email).all()
            if presenter:
                assert len(presenter) == 1
                presenter = presenter[0]
                (p_email, p_name, p_bio, p_country) = (presenter.email, presenter.name, presenter.bio, presenter.country)
            else:
                (p_email, p_name, p_bio, p_country) = (user.email, user.name, '', user.country)
            return render_template('submit.html', page=md(base_page, {
                'pagetitle': 'Submit a proposal',
                'data': Markup(submit_form_preface_markup),
                'title': '',
                'session_type': SessionType.session.value,
                'summary': '',
                'audience': SessionAudience.all.value,
                'keywords': '',
                'no_video': False,
                'notes': '',
                'constraints': '',
                'presenter': {
                    'email': p_email,
                    'name': p_name,
                    'is_lead': True,
                    'bio': p_bio,
                    'country': p_country,
                },
                'countries': sorted(countries),
                'submit_label': 'Submit',
            }))
        return render_template('general.html', page=md(base_page, {
            'pagetitle': 'Submission Problem',
            'data': 'The logged in user is not in database. This cannot happen.',
        }))
    return render_template('general.html', page=md(base_page, {
        'pagetitle': 'Submit Not Possible',
        'data': 'You must be registered and logged in to submit a proposal.'
    }))
def register():
    check = utils.is_acceptable_route()
    if not check[0]:
        return check[1]
    assert check[1] is None
    user = User.query.filter_by(
        email=session['email']).first() if utils.is_logged_in() else None
    edit_mode = bool(user)
    if request.method == 'POST':
        registration_data = request.json
        status, message = validate_registration_data(registration_data)
        if not status:
            # NB This should never be executed.
            response = jsonify(message)
            response.status_code = 400
            return response
        if not edit_mode:
            if not registration_data['passphrase']:
                # NB This should never be executed.
                response = jsonify('No passphrase for new registration.')
                response.status_code = 400
                return response
            if User.query.filter_by(email=registration_data['email']).first():
                # Currently this can happen as client-site checking is not implemented.
                # TODO implement client side checking so this becomes redundant.
                response = jsonify('The email address is already in use.')
                response.status_code = 400
                return response
        if registration_data['passphrase']:
            registration_data['passphrase'] = utils.hash_passphrase(
                registration_data['passphrase'])
        if edit_mode:
            User.query.filter_by(
                email=registration_data['email']).update(registration_data)
            db.session.commit()
            return jsonify('register_success_update')
        db.session.add(User(**registration_data))
        db.session.commit()
        return jsonify('register_success_new')
    else:
        return render_template(
            'register.html',
            page=utils.md(
                base_page,
                {
                    'email':
                    user.email if edit_mode else '',
                    'name':
                    user.name if edit_mode else '',
                    'phone':
                    user.phone if edit_mode else '',
                    'street_address':
                    user.street_address if edit_mode else '',
                    'town_city':
                    user.town_city if edit_mode else '',
                    'state':
                    user.state if edit_mode else '',
                    'postal_code':
                    user.postal_code if edit_mode else '',
                    'country':
                    user.country
                    if edit_mode else 'GBR',  # UK shall be the default
                    'title':
                    'Account Information' if edit_mode else 'Register',
                    'data':
                    'Here you can edit your account information'
                    if edit_mode else
                    'Register here for submitting proposals to ACCU Conference',
                    'submit_button':
                    'Save' if edit_mode else 'Register',
                    'countries':
                    sorted(list(countries.keys())),
                }))
Example #18
0
def test_is_acceptable_route_no_call_no_reviewing(monkeypatch):
    monkeypatch.setitem(app.config, 'CALL_OPEN', False)
    monkeypatch.setitem(app.config, 'REVIEWING_ALLOWED', False)
    assert not utils.is_acceptable_route()[0]
def submit():
    check = is_acceptable_route()
    if not check[0]:
        return check[1]
    assert check[1] is None
    page = {
        'title': 'Submit',
        'year': year,
    }
    if is_logged_in():
        if request.method == 'POST':
            user = User.query.filter_by(email=session['email']).first()
            if user:
                proposal_data = request.json
                status, message = validate_proposal_data(proposal_data)
                response = {}
                if status:
                    proposal = Proposal(
                        user,
                        proposal_data.get('title').strip(),
                        SessionType(proposal_data.get('session_type')),
                        proposal_data.get('abstract').strip())
                    db.session.add(proposal)
                    presenters_data = proposal_data.get('presenters')
                    for presenter_data in presenters_data:
                        presenter = Presenter(
                            presenter_data['email'],
                            presenter_data['name'],
                            'A human being.',
                            presenter_data['country'],
                            presenter_data['state'],
                        )
                        ProposalPresenter(proposal, presenter,
                                          presenter_data['lead'])
                        db.session.add(presenter)
                    db.session.commit()
                    response['success'] = True
                    response[
                        'message'] = '''Thank you, you have successfully submitted a proposal for the ACCU {} conference!
If you need to edit it you can via the 'My Proposal' menu item.'''.format(year)
                    response['redirect'] = '/'
                else:
                    response['success'] = False
                    response['message'] = message
                return jsonify(**response)
        else:
            user = User.query.filter_by(email=session['email']).first()
            if user:
                return render_template(
                    'submit.html',
                    page={
                        'title': 'Submit a proposal for ACCU {}'.format(year),
                        'name': user.name,
                        'proposer': {
                            'email': user.email,
                            'name': user.name,
                            'bio': 'A human being.',
                            'country': user.country,
                            'state': user.state,
                        }
                    })
    return render_template(
        'failure.html',
        page=md(page, {'data': 'Must be logged in to submit a proposal.'}))