Skip to content

Commit

Permalink
Merge branch 'main' into fixup/repair-the-timeline
Browse files Browse the repository at this point in the history
  • Loading branch information
russss authored Jan 9, 2024
2 parents db1375f + 6128d1c commit 3d2bfcf
Show file tree
Hide file tree
Showing 43 changed files with 10,280 additions and 169 deletions.
6 changes: 5 additions & 1 deletion apps/base/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ def main():
def main_post():
honeypot_field = request.form.get("name")
email = request.form.get("email", "").strip()
list = request.form.get("list")

if request.form.get("list") not in app.config["LISTMONK_LISTS"]:
return raise_404()

if email == "":
return redirect(url_for(".main"))
Expand All @@ -68,7 +72,7 @@ def main_post():

response = requests.post(
app.config["LISTMONK_URL"] + "/api/public/subscription",
json={"email": email, "list_uuids": [app.config["LISTMONK_LIST_ID"]]},
json={"email": email, "list_uuids": [app.config["LISTMONK_LISTS"][list]]},
)

if response.status_code != 200:
Expand Down
16 changes: 14 additions & 2 deletions apps/base/about.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@
although some legacy content remains here.
"""

from flask import abort, current_app as app, redirect, render_template, url_for
from flask import (
abort,
current_app as app,
redirect,
render_template,
render_template_string,
url_for,
)
from markdown import markdown
from os import path
from pathlib import Path
Expand Down Expand Up @@ -33,7 +40,12 @@ def render_markdown(source, **view_variables):
source = f.read()
(metadata, content) = source.split("---", 2)
metadata = parse_yaml(metadata)
content = Markup(markdown(content, extensions=["markdown.extensions.nl2br"]))
content = Markup(
markdown(
render_template_string(content),
extensions=["markdown.extensions.nl2br"],
)
)

view_variables.update(content=content, title=metadata["title"])
return render_template(page_template(metadata), **view_variables)
Expand Down
55 changes: 54 additions & 1 deletion apps/base/dev/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@
import click
from pendulum import parse
from flask import current_app as app
from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound

from main import db

from models.volunteer.venue import VolunteerVenue
from models.volunteer.shift import Shift
from models.volunteer.role import Role

from apps.cfp.tasks import create_tags
from models.payment import BankAccount

from . import dev_cli
from .fake import FakeDataGenerator

Expand All @@ -20,6 +24,8 @@ def dev_data(ctx):
ctx.invoke(fake_data)
ctx.invoke(volunteer_data)
ctx.invoke(volunteer_shifts)
ctx.invoke(create_tags)
ctx.invoke(create_bank_accounts)


@dev_cli.command("cfp_data")
Expand Down Expand Up @@ -537,7 +543,6 @@ def volunteer_shifts():
venue = VolunteerVenue.get_by_name(shift_venue)

for shift_ranges in shift_list[shift_role][shift_venue]:

shifts = Shift.generate_for(
role=role,
venue=venue,
Expand All @@ -550,3 +555,51 @@ def volunteer_shifts():
db.session.add(s)

db.session.commit()


@dev_cli.command("createbankaccounts")
def create_bank_accounts_cmd():
create_bank_accounts()


def create_bank_accounts():
"""Create bank accounts if they don't exist"""
gbp = BankAccount(
sort_code="102030",
acct_id="40506070",
currency="GBP",
active=True,
payee_name="EMF Festivals Ltd",
institution="London Bank",
address="13 Bartlett Place, London, WC1B 4NM",
iban=None,
swift=None,
)
eur = BankAccount(
sort_code=None,
acct_id=None,
currency="EUR",
active=True,
payee_name="EMF Festivals Ltd",
institution="London Bank",
address="13 Bartlett Place, London, WC1B 4NM",
iban="GB33BUKB20201555555555",
swift="GB33BUKB",
)
for acct in [gbp, eur]:
try:
BankAccount.query.filter_by(
acct_id=acct.acct_id, sort_code=acct.sort_code
).one()
except NoResultFound:
app.logger.info(
"Adding %s account %s %s",
acct.currency,
acct.sort_code or acct.swift,
acct.acct_id or acct.iban,
)
db.session.add(acct)
except MultipleResultsFound:
pass

db.session.commit()
47 changes: 0 additions & 47 deletions apps/base/tasks_banking.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from datetime import datetime, timedelta

from flask import current_app as app
from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound

from main import db, wise
from apps.base import base
Expand All @@ -16,52 +15,6 @@
from models.payment import BankAccount, BankTransaction


@base.cli.command("createbankaccounts")
def create_bank_accounts_cmd():
create_bank_accounts()


def create_bank_accounts():
"""Create bank accounts if they don't exist"""
gbp = BankAccount(
sort_code="102030",
acct_id="40506070",
currency="GBP",
active=True,
institution="London Bank",
address="13 Bartlett Place, London, WC1B 4NM",
iban=None,
swift=None,
)
eur = BankAccount(
sort_code=None,
acct_id=None,
currency="EUR",
active=True,
institution="London Bank",
address="13 Bartlett Place, London, WC1B 4NM",
iban="GB33BUKB20201555555555",
swift="GB33BUKB",
)
for acct in [gbp, eur]:
try:
BankAccount.query.filter_by(
acct_id=acct.acct_id, sort_code=acct.sort_code
).one()
except NoResultFound:
app.logger.info(
"Adding %s account %s %s",
acct.currency,
acct.sort_code or acct.swift,
acct.acct_id or acct.iban,
)
db.session.add(acct)
except MultipleResultsFound:
pass

db.session.commit()


@base.cli.command("loadofx")
@click.argument("ofx_file", type=click.File("r"))
def load_ofx(ofx_file):
Expand Down
25 changes: 25 additions & 0 deletions apps/cfp/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from main import db
from models.cfp import Proposal, TalkProposal, WorkshopProposal, InstallationProposal
from models.cfp_tag import Tag, DEFAULT_TAGS
from models.user import User
from apps.cfp_review.base import send_email_for_proposal
from ..common.email import from_email
Expand Down Expand Up @@ -125,3 +126,27 @@ def email_reserve():
send_email_for_proposal(
proposal, reason="reserve-list", from_address=from_email("SPEAKERS_EMAIL")
)


@cfp.cli.command(
"create_tags",
help=f"Add tags to the database. Defaults are {DEFAULT_TAGS}.",
)
@click.argument("tags_to_create", nargs=-1)
def create_tags(tags_to_create):
"""Upset tag list"""
if not tags_to_create:
tags_to_create = DEFAULT_TAGS

tags_created = 0
for tag in tags_to_create:
if Tag.query.filter_by(tag=tag).all():
app.logger.info(f"'{tag}' already exists, skipping.")
continue

db.session.add(Tag(tag))
tags_created += 1
app.logger.info(f"'{tag}' added to session.")

db.session.commit()
app.logger.info(f"Successfully created {tags_created} new tags.")
68 changes: 60 additions & 8 deletions apps/cfp_review/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,23 @@
from main import db, external_url
from .majority_judgement import calculate_max_normalised_score
from models.cfp import (
Proposal,
LightningTalkProposal,
CFPMessage,
CFPVote,
Venue,
InvalidVenueException,
MANUAL_REVIEW_TYPES,
get_available_proposal_minutes,
ROUGH_LENGTHS,
get_days_map,
DEFAULT_VENUES,
EVENT_SPACING,
FavouriteProposal,
get_available_proposal_minutes,
get_days_map,
HUMAN_CFP_TYPES,
InvalidVenueException,
LightningTalkProposal,
MANUAL_REVIEW_TYPES,
ORDERED_STATES,
Proposal,
ROUGH_LENGTHS,
Venue,
)
from models.cfp_tag import Tag
from models.user import User
from models.purchase import Ticket
from .forms import (
Expand Down Expand Up @@ -138,6 +141,22 @@ def filter_proposal_request():
)
)

tags = request.args.getlist("tags")
if "untagged" in tags:
if len(tags) > 1:
flash("'untagged' in 'tags' arg, other tags ignored")
filtered = True
# join(..outer=True) == left outer join
proposal_query = proposal_query.join(Proposal.tags, isouter=True).filter(
Tag.id.is_(None)
)

elif tags:
filtered = True
proposal_query = proposal_query.join(Proposal.tags).filter(
Proposal.tags.any(Tag.tag.in_(tags))
)

sort_dict = get_proposal_sort_dict(request.args)
proposal_query = proposal_query.options(joinedload(Proposal.user)).options(
joinedload("user.owned_tickets")
Expand All @@ -159,12 +178,18 @@ def proposals():
if "reverse" in non_sort_query_string:
del non_sort_query_string["reverse"]

tag_counts = {t.tag: [0, len(t.proposals)] for t in Tag.query.all()}
for prop in proposals:
for t in prop.tags:
tag_counts[t.tag][0] = tag_counts[t.tag][0] + 1

return render_template(
"cfp_review/proposals.html",
proposals=proposals,
new_qs=non_sort_query_string,
filtered=filtered,
total_proposals=Proposal.query.count(),
tag_counts=tag_counts,
)


Expand Down Expand Up @@ -295,6 +320,8 @@ def log_and_close(msg, next_page, proposal_id=None):
else:
raise Exception("Unknown cfp type {}".format(prop.type))

form.tags.choices = [(t.tag, t.tag) for t in Tag.query.order_by(Tag.tag).all()]

# Process the POST
if form.validate_on_submit():
try:
Expand Down Expand Up @@ -343,6 +370,7 @@ def log_and_close(msg, next_page, proposal_id=None):
form.state.data = prop.state
form.title.data = prop.title
form.description.data = prop.description
form.tags.data = [t.tag for t in prop.tags]
form.requirements.data = prop.requirements
form.length.data = prop.length
form.notice_required.data = prop.notice_required
Expand Down Expand Up @@ -1173,4 +1201,28 @@ def lightning_talks():
)


@cfp_review.route("/proposals-summary")
@schedule_required
def proposals_summary():
counts_by_tag = {t.tag: len(t.proposals) for t in Tag.query.all()}
counts_by_tag["untagged"] = 0

counts_by_type = {t: 0 for t in HUMAN_CFP_TYPES}
counts_by_state = {s: 0 for s in ORDERED_STATES}

for prop in Proposal.query.all():
counts_by_type[prop.type] += 1
counts_by_state[prop.state] += 1

if not prop.tags:
counts_by_tag["untagged"] += 1

return render_template(
"cfp_review/proposals_summary.html",
counts_by_tag=counts_by_tag,
counts_by_type=counts_by_type,
counts_by_state=counts_by_state,
)


from . import venues # noqa
7 changes: 5 additions & 2 deletions apps/cfp_review/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@
StringField,
FieldList,
FormField,
RadioField,
SelectField,
TextAreaField,
BooleanField,
IntegerField,
FloatField,
SelectMultipleField,
)
from wtforms.validators import DataRequired, Optional, NumberRange, ValidationError

from models.cfp import Venue, ORDERED_STATES
from models.cfp_tag import Tag
from ..common.forms import Form, HiddenIntegerField, EmailField

from dateutil.parser import parse as parse_date
Expand All @@ -24,6 +25,7 @@ class UpdateProposalForm(Form):
state = SelectField("State", choices=[(s, s) for s in ORDERED_STATES])
title = StringField("Title", [DataRequired()])
description = TextAreaField("Description", [DataRequired()])
tags = SelectMultipleField("Tags")
requirements = TextAreaField("Requirements")
length = StringField("Length")
notice_required = SelectField(
Expand All @@ -50,7 +52,7 @@ class UpdateProposalForm(Form):
telephone_number = StringField("Telephone")
eventphone_number = StringField("On-site extension")
may_record = BooleanField("May record")
needs_laptop = RadioField(
needs_laptop = SelectField(
"Needs laptop",
choices=[
(0, "Is providing their own laptop"),
Expand Down Expand Up @@ -94,6 +96,7 @@ def validate_allowed_times(self, field):
def update_proposal(self, proposal):
proposal.title = self.title.data
proposal.description = self.description.data
proposal.tags = Tag.parse_serialised_tags(self.tags.data)
proposal.requirements = self.requirements.data
proposal.length = self.length.data
proposal.notice_required = self.notice_required.data
Expand Down
Loading

0 comments on commit 3d2bfcf

Please sign in to comment.