Exemple #1
0
def csv_import(csv_file, state):
    """ Import a previous schedule for testing"""
    faker = Faker()
    # id, title, description, length, need_finance,
    # one_day, type, experience, attendees, size
    reader = DictReader(csv_file)
    count = 0
    for row in reader:
        if Proposal.query.filter_by(title=row["title"]).first():
            continue

        user = User("*****@*****.**" % count, faker.name())
        db.session.add(user)

        proposal = (TalkProposal()
                    if row["type"] == u"talk" else WorkshopProposal()
                    if row["type"] == u"workshop" else InstallationProposal())

        proposal.state = state
        proposal.title = row["title"]
        proposal.description = row["description"]

        proposal.one_day = True if row.get("one_day") == "t" else False
        proposal.needs_money = True if row.get(
            "need_finance") == "t" else False

        if row["type"] == "talk":
            proposal.length = row["length"]

        elif row["type"] == "workshop":
            proposal.length = row["length"]
            proposal.attendees = row["attendees"]

        else:
            proposal.size = row["size"]

        proposal.user = user
        db.session.add(proposal)

        db.session.commit()
        count += 1

    app.logger.info("Imported %s proposals" % count)
def test_product_view_accessible(db, user):
    product_view = ProductView(name="other")
    assert product_view.is_accessible(user)

    product_view = ProductView(name="other", token="testtoken")
    assert product_view.is_accessible(user, "testtoken")
    assert not product_view.is_accessible(user)

    product_view = ProductView(name="cfp", cfp_accepted_only=True)
    assert not product_view.is_accessible(user)

    proposal = TalkProposal()
    proposal.title = "title"
    proposal.description = "description"
    proposal.requirements = "requirements"
    proposal.user = user
    db.session.add(proposal)
    db.session.commit()
    proposal.set_state("accepted")

    assert product_view.is_accessible(user)
Exemple #3
0
def test_product_view_accessible(db, user, monkeypatch):
    product_view = ProductView(name="other", type="ticket")
    assert product_view.is_accessible(user), "Default view should be visible"

    product_view = ProductView(name="another-other", type="ticket", vouchers_only=True)
    voucher = Voucher(view=product_view)

    db.session.add(product_view)
    db.session.add(voucher)
    db.session.commit()

    assert product_view.is_accessible(
        user, voucher.code
    ), "Product should be visible with voucher"

    assert not product_view.is_accessible(
        user
    ), "Product should be inaccessible without voucher"

    assert not product_view.is_accessible(
        user, "wrong"
    ), "Product should be inaccessible with incorrect voucher"

    product_view = ProductView(name="cfp", cfp_accepted_only=True, type="ticket")
    assert not product_view.is_accessible(
        user
    ), "CfP products should not be visible without accepted proposal"

    proposal = TalkProposal()
    proposal.title = "title"
    proposal.description = "description"
    proposal.requirements = "requirements"
    proposal.user = user
    db.session.add(proposal)
    db.session.commit()
    proposal.set_state("accepted")

    assert product_view.is_accessible(
        user
    ), "CfP products should be visible with accepted proposal"
def test_cfp(db, app, user, outbox, title, description, requirements):
    for c in ["\0", "\r", "\n"]:
        assume(c not in title)

    assume("\0" not in description)
    assume("\0" not in requirements)

    proposal = TalkProposal()
    proposal.title = title
    proposal.description = description
    proposal.requirements = requirements
    proposal.user = user

    db.session.add(proposal)
    db.session.commit()

    proposal.set_state('accepted')
    with app.test_request_context('/'):
        send_email_for_proposal(proposal, reason='accepted')

    assert len(outbox) == 1
    del outbox[:]
Exemple #5
0
def test_product_view_accessible(db, user):
    product_view = ProductView(name="other")
    assert product_view.is_accessible(user)

    product_view = ProductView(name="other", token="testtoken")
    assert product_view.is_accessible(user, "testtoken")
    assert not product_view.is_accessible(user)

    product_view = ProductView(name="cfp", cfp_accepted_only=True)
    assert not product_view.is_accessible(user)

    proposal = TalkProposal()
    proposal.title = "title"
    proposal.description = "description"
    proposal.requirements = "requirements"
    proposal.user = user
    db.session.add(proposal)
    db.session.commit()
    proposal.set_state('accepted')

    assert product_view.is_accessible(user)
Exemple #6
0
def main(cfp_type="talk"):
    if cfp_type not in ["talk", "workshop", "installation"]:
        abort(404)

    ignore_closed = "closed" in request.args

    if app.config.get("CFP_CLOSED") and not ignore_closed:
        return render_template("cfp/closed.html")

    forms = [
        TalkProposalForm(prefix="talk"),
        WorkshopProposalForm(prefix="workshop"),
        InstallationProposalForm(prefix="installation"),
    ]
    (form,) = [f for f in forms if f.type == cfp_type]
    form.active_cfp_type = cfp_type

    # If the user is already logged in set their name & email for the form
    if current_user.is_authenticated():
        form.name.data = current_user.name
        form.email.data = current_user.email

    if request.method == "POST":
        app.logger.info("Checking %s proposal for %s (%s)", cfp_type, form.name.data, form.email.data)

    if form.validate_on_submit():
        new_user = False
        if current_user.is_anonymous():
            try:
                create_current_user(form.email.data, form.name.data)
                new_user = True
            except IntegrityError as e:
                app.logger.warn("Adding user raised %r, possible double-click", e)
                flash("An error occurred while creating an account for you. Please try again.")
                return redirect(url_for(".main"))

        if cfp_type == "talk":
            cfp = TalkProposal()
            cfp.length = form.length.data

        elif cfp_type == "workshop":
            cfp = WorkshopProposal()
            cfp.length = form.length.data
            cfp.attendees = form.attendees.data
            cfp.cost = form.cost.data

        elif cfp_type == "installation":
            cfp = InstallationProposal()
            cfp.size = form.size.data
            cfp.funds = form.funds.data

        cfp.user_id = current_user.id

        cfp.title = form.title.data
        cfp.requirements = form.requirements.data
        cfp.description = form.description.data
        cfp.notice_required = form.notice_required.data
        cfp.needs_help = form.needs_help.data

        db.session.add(cfp)
        db.session.commit()

        # Send confirmation message
        msg = Message(
            "Electromagnetic Field CFP Submission", sender=app.config["CONTENT_EMAIL"], recipients=[current_user.email]
        )

        msg.body = render_template("emails/cfp-submission.txt", cfp=cfp, type=cfp_type, new_user=new_user)
        mail.send(msg)

        return redirect(url_for(".complete"))

    full_price = TicketType.get_price_cheapest_full()

    return render_template(
        "cfp/main.html",
        full_price=full_price,
        forms=forms,
        active_cfp_type=cfp_type,
        has_errors=bool(form.errors),
        ignore_closed=ignore_closed,
    )
Exemple #7
0
    def run(self):
        if not User.query.filter_by(email='*****@*****.**').first():
            user = User('*****@*****.**', 'Test Admin')
            user.grant_permission('admin')
            cfp = TalkProposal()
            cfp.user = user
            cfp.title = 'test (admin)'
            cfp.description = 'test proposal from admin'
            db.session.add(user)

        if not User.query.filter_by(email='*****@*****.**').first():
            user2 = User('*****@*****.**', 'Test Anonymiser')
            user2.grant_permission('cfp_anonymiser')
            cfp = TalkProposal()
            cfp.user = user2
            cfp.title = 'test (anonymiser)'
            cfp.description = 'test proposal from anonymiser'
            db.session.add(user2)

        if not User.query.filter_by(email='*****@*****.**').first():
            user3 = User('*****@*****.**', 'Test Reviewer')
            user3.grant_permission('cfp_reviewer')
            cfp = TalkProposal()
            cfp.user = user3
            cfp.title = 'test (reviewer)'
            cfp.description = 'test proposal from reviewer'
            db.session.add(user3)

        if not User.query.filter_by(email='*****@*****.**').first():
            user4 = User('*****@*****.**', 'Test Arrivals')
            user4.grant_permission('arrivals')
            cfp = TalkProposal()
            cfp.user = user4
            cfp.title = 'test (arrivals)'
            cfp.description = 'test proposal from arrivals'
            db.session.add(user4)

        db.session.commit()
Exemple #8
0
    def run(self, filename, state):
        faker = Faker()
        with open(filename) as csvfile:
            # id, title, description, length, need_finance,
            # one_day, type, experience, attendees, size
            reader = DictReader(csvfile)
            count = 0
            for row in reader:
                if Proposal.query.filter_by(title=row['title']).first():
                    continue

                user = User('*****@*****.**' % count, faker.name())
                db.session.add(user)

                proposal = TalkProposal() if row['type'] == u'talk' else\
                    WorkshopProposal() if row['type'] == u'workshop' else\
                    InstallationProposal()

                proposal.state = state
                proposal.title = row['title']
                proposal.description = row['description']

                proposal.one_day = True if row.get('one_day') == 't' else False
                proposal.needs_money = True if row.get('need_finance') == 't' else False

                if row['type'] == 'talk':
                    proposal.length = row['length']

                elif row['type'] == 'workshop':
                    proposal.length = row['length']
                    proposal.attendees = row['attendees']

                else:
                    proposal.size = row['size']

                proposal.user = user
                db.session.add(proposal)

                db.session.commit()
                count += 1

        app.logger.info('Imported %s proposals' % count)
Exemple #9
0
def form(cfp_type="talk"):
    form = get_cfp_type_form(cfp_type)
    if not form:
        abort(404)

    ignore_closed = "closed" in request.args

    if feature_enabled("CFP_CLOSED") and not ignore_closed:
        return render_template("cfp/closed.html", cfp_type=cfp_type)

    # If the user is already logged in set their name & email for the form
    if current_user.is_authenticated:
        form.email.data = current_user.email
        if current_user.name != current_user.email:
            form.name.data = current_user.name

    if request.method == "POST":
        app.logger.info(
            "Checking %s proposal for %s (%s)",
            cfp_type,
            form.name.data,
            form.email.data,
        )

    if form.validate_on_submit():
        new_user = False
        if current_user.is_anonymous:
            try:
                create_current_user(form.email.data, form.name.data)
                new_user = True
            except IntegrityError as e:
                app.logger.warn("Adding user raised %r, possible double-click",
                                e)
                flash(
                    "An error occurred while creating an account for you. Please try again."
                )
                return redirect(url_for(".main"))

        elif current_user.name == current_user.email:
            current_user.name = form.name.data

        if cfp_type == "talk":
            cfp = TalkProposal()
            cfp.length = form.length.data

        elif cfp_type == "performance":
            cfp = PerformanceProposal()
            cfp.length = form.length.data

        elif cfp_type == "workshop":
            cfp = WorkshopProposal()
            cfp.length = form.length.data
            cfp.attendees = form.attendees.data
            cfp.cost = form.cost.data
            cfp.participant_equipment = form.participant_equipment.data
            cfp.age_range = form.age_range.data

        elif cfp_type == "youthworkshop":
            cfp = YouthWorkshopProposal()
            cfp.length = form.length.data
            cfp.attendees = form.attendees.data
            cfp.cost = form.cost.data
            cfp.participant_equipment = form.participant_equipment.data
            cfp.age_range = form.age_range.data
            cfp.valid_dbs = form.valid_dbs.data

        elif cfp_type == "installation":
            cfp = InstallationProposal()
            cfp.size = form.size.data
            cfp.funds = form.funds.data

        cfp.user_id = current_user.id

        cfp.title = form.title.data
        cfp.requirements = form.requirements.data
        cfp.description = form.description.data
        cfp.notice_required = form.notice_required.data
        cfp.needs_help = form.needs_help.data

        db.session.add(cfp)
        db.session.commit()

        # Send confirmation message
        msg = Message(
            "Electromagnetic Field CFP Submission",
            sender=app.config["CONTENT_EMAIL"],
            recipients=[current_user.email],
        )

        msg.body = render_template("emails/cfp-submission.txt",
                                   proposal=cfp,
                                   new_user=new_user)
        mail.send(msg)

        return redirect(url_for(".complete"))

    return render_template(
        "cfp/new.html",
        cfp_type=cfp_type,
        form=form,
        has_errors=bool(form.errors),
        ignore_closed=ignore_closed,
    )
Exemple #10
0
    def run(self):
        if not User.query.filter_by(email='*****@*****.**').first():
            user = User('*****@*****.**', 'Test Admin')
            user.grant_permission('admin')
            cfp = TalkProposal()
            cfp.user = user
            cfp.title = 'test (admin)'
            cfp.description = 'test proposal from admin'
            db.session.add(user)

        if not User.query.filter_by(email='*****@*****.**').first():
            user2 = User('*****@*****.**', 'Test Anonymiser')
            user2.grant_permission('cfp_anonymiser')
            cfp = TalkProposal()
            cfp.user = user2
            cfp.title = 'test (anonymiser)'
            cfp.description = 'test proposal from anonymiser'
            db.session.add(user2)

        if not User.query.filter_by(email='*****@*****.**').first():
            user3 = User('*****@*****.**', 'Test Reviewer')
            user3.grant_permission('cfp_reviewer')
            cfp = TalkProposal()
            cfp.user = user3
            cfp.title = 'test (reviewer)'
            cfp.description = 'test proposal from reviewer'
            db.session.add(user3)

        if not User.query.filter_by(email='*****@*****.**').first():
            user4 = User('*****@*****.**', 'Test Arrivals')
            user4.grant_permission('arrivals')
            cfp = TalkProposal()
            cfp.user = user4
            cfp.title = 'test (arrivals)'
            cfp.description = 'test proposal from arrivals'
            db.session.add(user4)

        db.session.commit()
Exemple #11
0
    def run(self, filename, state):
        faker = Faker()
        with open(filename) as csvfile:
            # id, title, description, length, need_finance,
            # one_day, type, experience, attendees, size
            reader = DictReader(csvfile)
            count = 0
            for row in reader:
                if Proposal.query.filter_by(title=row['title']).first():
                    continue

                user = User('*****@*****.**' % count, faker.name())
                db.session.add(user)

                proposal = TalkProposal() if row['type'] == u'talk' else\
                    WorkshopProposal() if row['type'] == u'workshop' else\
                    InstallationProposal()

                proposal.state = state
                proposal.title = row['title']
                proposal.description = row['description']

                proposal.one_day = True if row.get('one_day') == 't' else False
                proposal.needs_money = True if row.get(
                    'need_finance') == 't' else False

                if row['type'] == 'talk':
                    proposal.length = row['length']

                elif row['type'] == 'workshop':
                    proposal.length = row['length']
                    proposal.attendees = row['attendees']

                else:
                    proposal.size = row['size']

                proposal.user = user
                db.session.add(proposal)

                db.session.commit()
                count += 1

        app.logger.info('Imported %s proposals' % count)
Exemple #12
0
def cfp(cfp_type='talk'):
    if cfp_type not in ['talk', 'workshop', 'installation']:
        abort(404)

    forms = [TalkProposalForm(), WorkshopProposalForm(), InstallationProposalForm()]
    (form,) = [f for f in forms if f.type == cfp_type]

    if request.method == 'POST':
        app.logger.info('Checking %s proposal for %s (%s)', cfp_type, form.name.data, form.email.data)

    if form.validate_on_submit():
        if cfp_type == 'talk':
            cfp = TalkProposal()
            cfp.length = form.length.data
            cfp.experience = form.experience.data
            cfp.one_day = form.one_day.data
        elif cfp_type == 'workshop':
            cfp = WorkshopProposal()
            cfp.length = form.length.data
            cfp.attendees = form.attendees.data
            cfp.one_day = form.one_day.data
        elif cfp_type == 'installation':
            cfp = InstallationProposal()
            cfp.size = form.size.data

        cfp.name = form.name.data
        cfp.email = form.email.data
        cfp.title = form.title.data
        cfp.description = form.description.data
        cfp.need_finance = form.need_finance.data

        cfp.diversity = ProposalDiversity()
        cfp.diversity.age = form.diversity.age.data
        cfp.diversity.gender = form.diversity.gender.data
        cfp.diversity.ethnicity = form.diversity.ethnicity.data

        db.session.add(cfp)
        db.session.commit()

        return redirect(url_for('cfp_complete'))

    if current_user.is_authenticated():
        form.name.data = current_user.name
        form.email.data = current_user.email

    full_price = TicketType.query.get('full').get_price('GBP')

    return render_template('cfp.html', full_price=full_price,
        forms=forms, active_cfp_type=cfp_type, has_errors=bool(form.errors))
Exemple #13
0
def form(cfp_type="talk"):
    form = get_cfp_type_form(cfp_type)
    if not form:
        abort(404)

    ignore_closed = "closed" in request.args

    if feature_enabled("CFP_CLOSED") and not ignore_closed:
        return render_template("cfp/closed.html", cfp_type=cfp_type)

    if feature_enabled("CFP_{}S_CLOSED".format(
            cfp_type.upper())) and not ignore_closed:
        msg = Markup(
            render_template_string(
                """Sorry, we're not accepting new {{ type }} proposals, if you have been told to submit something please <a href="{{ url }}">click here</a>""",
                type=HUMAN_CFP_TYPES[cfp_type],
                url=url_for(".form", cfp_type=cfp_type, closed=True),
            ))
        flash(msg)
        return redirect(url_for(".main"))

    if (cfp_type == "lightning" and not feature_enabled("LIGHTNING_TALKS")
            and not current_user.has_permission("cfp_admin")):
        flash("We're not currently accepting Lightning Talks.")
        return redirect(url_for(".main"))

    remaining_lightning_slots = LightningTalkProposal.get_days_with_slots()
    # Require logged in users as you have to have a ticket to lightning talk
    if cfp_type == "lightning" and current_user.is_anonymous:
        return redirect(
            url_for("users.login", next=url_for(".form",
                                                cfp_type="lightning")))
    elif cfp_type == "lightning":
        if all([i <= 0 for i in remaining_lightning_slots.values()]):
            flash("All lightning talk sessions are now full, sorry")
            return redirect(url_for(".main"))
        form.set_session_choices(remaining_lightning_slots)

    # If the user is already logged in set their name & email for the form
    if current_user.is_authenticated:
        form.email.data = current_user.email
        if current_user.name != current_user.email:
            form.name.data = current_user.name

    if request.method == "POST":
        app.logger.info(
            "Checking %s proposal for %s (%s)",
            cfp_type,
            form.name.data,
            form.email.data,
        )

    if form.validate_on_submit():
        new_user = False
        if current_user.is_anonymous:
            try:
                create_current_user(form.email.data, form.name.data)
                new_user = True
            except IntegrityError as e:
                app.logger.warn("Adding user raised %r, possible double-click",
                                e)
                flash(
                    "An error occurred while creating an account for you. Please try again."
                )
                return redirect(url_for(".main"))

        elif current_user.name == current_user.email:
            current_user.name = form.name.data

        if cfp_type == "talk":
            proposal = TalkProposal()
            proposal.length = form.length.data

        elif cfp_type == "performance":
            proposal = PerformanceProposal()
            proposal.length = form.length.data

        elif cfp_type == "workshop":
            proposal = WorkshopProposal()
            proposal.length = form.length.data
            proposal.attendees = form.attendees.data
            proposal.cost = form.cost.data
            proposal.participant_equipment = form.participant_equipment.data
            proposal.age_range = form.age_range.data

        elif cfp_type == "youthworkshop":
            proposal = YouthWorkshopProposal()
            proposal.length = form.length.data
            proposal.attendees = form.attendees.data
            proposal.cost = form.cost.data
            proposal.participant_equipment = form.participant_equipment.data
            proposal.age_range = form.age_range.data
            proposal.valid_dbs = form.valid_dbs.data

        elif cfp_type == "installation":
            proposal = InstallationProposal()
            proposal.size = form.size.data
            proposal.funds = form.funds.data

        elif cfp_type == "lightning":
            if remaining_lightning_slots[form.session.data] <= 0:
                # Manually set this because otherwise we need to pass the
                # remaining_lightning_slots object to validate
                form.errors[
                    "sessions"] = "That session is now full, sorry. Please select a different day"
                return render_template(
                    "cfp/new.html",
                    cfp_type=cfp_type,
                    form=form,
                    has_errors=bool(form.errors),
                    ignore_closed=ignore_closed,
                )

            proposal = LightningTalkProposal()
            proposal.slide_link = form.slide_link.data
            proposal.session = form.session.data

        proposal.user_id = current_user.id

        proposal.title = form.title.data
        proposal.requirements = form.requirements.data
        proposal.description = form.description.data
        proposal.notice_required = form.notice_required.data
        proposal.needs_help = form.needs_help.data

        db.session.add(proposal)
        db.session.commit()

        # Send confirmation message
        msg = EmailMessage(
            "Electromagnetic Field CFP Submission",
            from_email=from_email("CONTENT_EMAIL"),
            to=[current_user.email],
        )

        msg.body = render_template("emails/cfp-submission.txt",
                                   proposal=proposal,
                                   new_user=new_user)
        msg.send()

        if channel := app.config.get("CONTENT_IRC_CHANNEL"):
            # WARNING: don't send personal information via this (the channel is public)
            irc_send(
                f"{channel} New CfP {proposal.human_type} submission: {external_url('cfp_review.update_proposal', proposal_id=proposal.id)}"
            )
        return redirect(url_for(".complete"))
Exemple #14
0
def form(cfp_type='talk'):
    form = get_cfp_type_form(cfp_type)
    if not form:
        abort(404)

    ignore_closed = 'closed' in request.args

    if app.config.get('CFP_CLOSED') and not ignore_closed:
        return render_template('cfp/closed.html', cfp_type=cfp_type)

    # If the user is already logged in set their name & email for the form
    if current_user.is_authenticated:
        form.email.data = current_user.email
        if current_user.name != current_user.email:
            form.name.data = current_user.name

    if request.method == 'POST':
        app.logger.info('Checking %s proposal for %s (%s)', cfp_type,
                        form.name.data, form.email.data)

    if form.validate_on_submit():
        new_user = False
        if current_user.is_anonymous:
            try:
                create_current_user(form.email.data, form.name.data)
                new_user = True
            except IntegrityError as e:
                app.logger.warn('Adding user raised %r, possible double-click', e)
                flash('An error occurred while creating an account for you. Please try again.')
                return redirect(url_for('.main'))

        elif current_user.name == current_user.email:
            current_user.name = form.name.data

        if cfp_type == 'talk':
            cfp = TalkProposal()
            cfp.length = form.length.data

        elif cfp_type == 'performance':
            cfp = PerformanceProposal()
            cfp.length = form.length.data

        elif cfp_type == 'workshop':
            cfp = WorkshopProposal()
            cfp.length = form.length.data
            cfp.attendees = form.attendees.data
            cfp.cost = form.cost.data
            cfp.participant_equipment = form.participant_equipment.data
            cfp.age_range = form.age_range.data

        elif cfp_type == 'youthworkshop':
            cfp = YouthWorkshopProposal()
            cfp.length = form.length.data
            cfp.attendees = form.attendees.data
            cfp.cost = form.cost.data
            cfp.participant_equipment = form.participant_equipment.data
            cfp.age_range = form.age_range.data
            cfp.valid_dbs = form.valid_dbs.data

        elif cfp_type == 'installation':
            cfp = InstallationProposal()
            cfp.size = form.size.data
            cfp.funds = form.funds.data

        cfp.user_id = current_user.id

        cfp.title = form.title.data
        cfp.requirements = form.requirements.data
        cfp.description = form.description.data
        cfp.notice_required = form.notice_required.data
        cfp.needs_help = form.needs_help.data

        db.session.add(cfp)
        db.session.commit()

        # Send confirmation message
        msg = Message('Electromagnetic Field CFP Submission',
                      sender=app.config['CONTENT_EMAIL'],
                      recipients=[current_user.email])

        msg.body = render_template('emails/cfp-submission.txt',
                                   proposal=cfp, new_user=new_user)
        mail.send(msg)

        return redirect(url_for('.complete'))

    return render_template('cfp/new.html', cfp_type=cfp_type, form=form,
                           has_errors=bool(form.errors), ignore_closed=ignore_closed)
Exemple #15
0
def main(cfp_type='talk'):
    if cfp_type not in ['talk', 'workshop', 'installation']:
        abort(404)

    ignore_closed = 'closed' in request.args

    if app.config.get('CFP_CLOSED') and not ignore_closed:
        return render_template('cfp/closed.html')

    forms = [
        TalkProposalForm(prefix="talk"),
        WorkshopProposalForm(prefix="workshop"),
        InstallationProposalForm(prefix="installation")
    ]
    (form, ) = [f for f in forms if f.type == cfp_type]
    form.active_cfp_type = cfp_type

    # If the user is already logged in set their name & email for the form
    if current_user.is_authenticated():
        form.name.data = current_user.name
        form.email.data = current_user.email

    if request.method == 'POST':
        app.logger.info('Checking %s proposal for %s (%s)', cfp_type,
                        form.name.data, form.email.data)

    if form.validate_on_submit():
        new_user = False
        if current_user.is_anonymous():
            try:
                create_current_user(form.email.data, form.name.data)
                new_user = True
            except IntegrityError as e:
                app.logger.warn('Adding user raised %r, possible double-click',
                                e)
                flash(
                    'An error occurred while creating an account for you. Please try again.'
                )
                return redirect(url_for('.main'))

        if cfp_type == 'talk':
            cfp = TalkProposal()
            cfp.length = form.length.data

        elif cfp_type == 'workshop':
            cfp = WorkshopProposal()
            cfp.length = form.length.data
            cfp.attendees = form.attendees.data
            cfp.cost = form.cost.data

        elif cfp_type == 'installation':
            cfp = InstallationProposal()
            cfp.size = form.size.data
            cfp.funds = form.funds.data

        cfp.user_id = current_user.id

        cfp.title = form.title.data
        cfp.requirements = form.requirements.data
        cfp.description = form.description.data
        cfp.notice_required = form.notice_required.data
        cfp.needs_help = form.needs_help.data

        db.session.add(cfp)
        db.session.commit()

        # Send confirmation message
        msg = Message('Electromagnetic Field CFP Submission',
                      sender=app.config['CONTENT_EMAIL'],
                      recipients=[current_user.email])

        msg.body = render_template('emails/cfp-submission.txt',
                                   cfp=cfp,
                                   type=cfp_type,
                                   new_user=new_user)
        mail.send(msg)

        return redirect(url_for('.complete'))

    full_price = TicketType.get_price_cheapest_full()

    return render_template('cfp/main.html',
                           full_price=full_price,
                           forms=forms,
                           active_cfp_type=cfp_type,
                           has_errors=bool(form.errors),
                           ignore_closed=ignore_closed)