Skip to content

Commit

Permalink
Merge branch 'main' into static-content-as-markdown
Browse files Browse the repository at this point in the history
  • Loading branch information
russss authored Dec 17, 2023
2 parents 183c16e + 41e68f9 commit f55f09c
Show file tree
Hide file tree
Showing 23 changed files with 1,579 additions and 1,487 deletions.
3 changes: 0 additions & 3 deletions .mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@ ignore_missing_imports = True
[mypy-icalendar.*]
ignore_missing_imports = True

[mypy-mailchimp3.*]
ignore_missing_imports = True

[mypy-ofxparse.*]
ignore_missing_imports = True

Expand Down
88 changes: 22 additions & 66 deletions apps/base/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import os
from typing import Optional
from mailchimp3 import MailChimp
from mailchimp3.helpers import get_subscriber_hash
from mailchimp3.mailchimpclient import MailChimpError

from flask import (
render_template,
Expand All @@ -15,6 +12,7 @@
abort,
current_app as app,
)
import requests

from main import cache
from ..common import feature_flag
Expand Down Expand Up @@ -53,69 +51,27 @@ def main():

@base.route("/", methods=["POST"])
def main_post():
mc = MailChimp(mc_api=app.config["MAILCHIMP_KEY"])
try:
email = request.form.get("email")

try:
data = mc.lists.members.create_or_update(
list_id=app.config["MAILCHIMP_LIST"],
subscriber_hash=get_subscriber_hash(email),
data={
"email_address": email,
"status": "subscribed",
"status_if_new": "pending",
},
)
status = data.get("status")
if status == "pending":
flash(
"Thanks for subscribing! You will receive a confirmation email shortly."
)
elif status == "subscribed":
flash("You were already subscribed! Thanks for checking back.")
else:
raise ValueError("Unexpected status %s" % status)

except ValueError as e:
# ugh, this library is awful
app.logger.info(
"ValueError from mailchimp3 %s, assuming bad email: %r", e, email
)
flash("Your email address was not accepted - please check and try again.")

except MailChimpError as e:
# Either the JSON, or a dictionary containing the response
(data,) = e.args
if data.get("status") != 400:
raise

title = data.get("title")
if title == "Member In Compliance State":
app.logger.info("Member in compliance state: %r", email)
flash(
"""You've already been unsubscribed from our list, so we can't add you again.
Please contact %s to update your settings."""
% app.config["TICKETS_EMAIL"][1]
)

elif title == "Invalid Resource":
app.logger.warn(
"Invalid Resource from MailChimp, likely bad email or rate limited: %r",
email,
)
flash(
"""Your email address was not accepted - please check and try again.
If you've signed up to other lists recently, please wait 48 hours."""
)

else:
app.logger.warn("MailChimp returned %s: %s", title, data.get("detail"))
flash("Sorry, an error occurred: %s." % (title or "unknown"))

except Exception as e:
app.logger.exception("Error subscribing: %r", e)
flash("Sorry, an error occurred.")
email = request.form.get("email")

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

if response.status_code != 200:
app.logger.warn(
"Unable to subscribe to mailing list (HTTP %s): %s",
response.status_code,
response.text,
)
flash(
"Sorry, we were unable to subscribe you to the mailing list. Please try again later."
)

else:
flash(
"Thanks for subscribing! If you weren't already subscribed, you will receive a confirmation email shortly."
)

return redirect(url_for(".main"))

Expand Down
30 changes: 0 additions & 30 deletions apps/common/receipt.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import barcode
from barcode.writer import ImageWriter, SVGWriter
import segno
from segno import helpers

from main import external_url
from models import event_year
Expand Down Expand Up @@ -105,22 +104,6 @@ def make_qrfile(data, **kwargs):
return qrfile


def make_epc_qrfile(payment, **kwargs):
qrfile = io.BytesIO()
# TODO: this isn't currently used. Need to fetch IBAN from payment.recommended_destination
# and name from somewhere - maybe config rather than hard-coding.
qr = helpers.make_epc_qr(
name="FIXME FIXME FIXME",
iban="FIXME FIXME FIXME",
amount=payment.amount,
reference=payment.bankref,
encoding=1,
)
qr.save(qrfile, **kwargs)
qrfile.seek(0)
return qrfile


def qrfile_to_svg(qrfile):
return Markup(qrfile.getvalue().decode("utf-8"))

Expand All @@ -138,19 +121,6 @@ def format_inline_qr(data):
return qrfile_to_svg(qrfile)


def format_inline_epc_qr(payment):
qrfile = make_epc_qrfile(
payment,
kind="svg",
svgclass=None,
omitsize=True,
xmldecl=False,
svgns=False,
nl=False,
)
return qrfile_to_svg(qrfile)


def make_qr_png(url):
return make_qrfile(url, kind="png", scale=3)

Expand Down
38 changes: 37 additions & 1 deletion apps/payments/invoice.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from decimal import Decimal
from io import BytesIO
import logging
import shutil
import os.path
Expand All @@ -14,11 +15,13 @@
send_file,
)
from flask_login import login_required, current_user
from markupsafe import Markup
from segno import helpers
from sqlalchemy.sql.functions import func
from wtforms import TextAreaField, SubmitField

from main import external_url, db
from ..common.receipt import format_inline_epc_qr, render_pdf
from ..common.receipt import render_pdf
from models.product import Product, PriceTier
from models.purchase import Purchase
from ..common.forms import Form
Expand All @@ -28,6 +31,39 @@
logger = logging.getLogger(__name__)


def make_epc_qrfile(payment, **kwargs):
qrfile = BytesIO()
# TODO: this isn't currently used. Need to fetch IBAN from payment.recommended_destination
# and name from somewhere - maybe config rather than hard-coding.
qr = helpers.make_epc_qr(
name="EMF Festivals Ltd",
iban=payment.recommended_destination.iban,
amount=payment.amount,
reference=payment.bankref,
encoding=1,
)
qr.save(qrfile, **kwargs)
qrfile.seek(0)
return qrfile


def qrfile_to_svg(qrfile):
return Markup(qrfile.getvalue().decode("utf-8"))


def format_inline_epc_qr(payment):
qrfile = make_epc_qrfile(
payment,
kind="svg",
svgclass=None,
omitsize=True,
xmldecl=False,
svgns=False,
nl=False,
)
return qrfile_to_svg(qrfile)


class InvoiceForm(Form):
company = TextAreaField("Company name")
update = SubmitField("Update")
Expand Down
3 changes: 2 additions & 1 deletion config/development-example.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ STRIPE_WEBHOOK_KEY = ""
TRANSFERWISE_ENVIRONMENT = "sandbox"
TRANSFERWISE_API_TOKEN = ""

MAILCHIMP_KEY = ""
LISTMONK_URL = "https://broadcast.emfcamp.org"
LISTMONK_LIST_ID = "e4f02d85-5f8f-458f-9f83-051edf25bfb0"

MAIL_SERVER = "localhost"
MAIL_BACKEND = "console"
Expand Down
2 changes: 0 additions & 2 deletions logging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ loggers:
sqlalchemy.engine.base.Engine:
handlers: [sqlalchemy]
propagate: false
mailchimp3:
level: WARN
iso8601:
level: WARN
pyppeteer:
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
"datatables.net": "^1.11.3",
"jquery": "^3.5.0",
"jquery-highlight": "^3.5.0",
"luxon": "^1.22.0",
"luxon": "^1.28.1",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-nl2br": "^0.6.0",
Expand Down
Loading

0 comments on commit f55f09c

Please sign in to comment.