diff --git a/app/__init__.py b/app/__init__.py index 2b38c7e..999cabd 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -2,6 +2,7 @@ from flask import Flask from app.config import Config from app.extensions import db, mail, limiter from werkzeug.middleware.proxy_fix import ProxyFix +import logging def create_app(config_class=Config): app = Flask(__name__) @@ -9,6 +10,10 @@ def create_app(config_class=Config): app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1) + gunicorn_logger = logging.getLogger("gunicorn.error") + app.logger.handlers = gunicorn_logger.handlers + app.logger.setLevel(gunicorn_logger.level) + # Initialize extensions db.init_app(app) mail.init_app(app) diff --git a/app/routes.py b/app/routes.py index e591631..048c6eb 100644 --- a/app/routes.py +++ b/app/routes.py @@ -30,6 +30,7 @@ def send_verification_email(user, is_new=True): msg = Message('Verify your CTF Registration', recipients=[user.email]) msg.html = render_template("email.html", user_name=user.name, register_link=register_link, remove_link=remove_link, logo_url=logo) mail.send(msg) + current_app.logger.info(f"Sent verification email to {user.email}") user.num_emails_sent += 1 db.session.commit() if is_new: @@ -43,8 +44,24 @@ def send_waitlist_email(user): msg = Message('h4tum CTF 2026 Registration', recipients=[user.email]) logo = url_for('static', filename='h4tum_white.png', _external=True) msg.html = render_template("waitlist_email.html", logo_url=logo, user_name=user.name) + current_app.logger.info(msg) mail.send(msg) +def send_waitlist_newsletter(): + results = db.session.query(Participant.email).filter(Participant.on_waitlist == True).all() + waitlist_emails = [r[0] for r in results] + logo = url_for('static', filename='h4tum_white.png', _external=True) + s = URLSafeTimedSerializer(current_app.config['SECRET_KEY']) + for email in waitlist_emails: + register_token = s.dumps(email, salt='email-confirm-h4tum-ctf-2025') + register_link = url_for('main.verify_email', token=register_token, _external=True) + remove_token = s.dumps(email, salt='email-remove-h4tum-ctf-2026') + remove_link = url_for('main.remove_registration', token=remove_token, _external=True) + msg = Message('h4tum CTF 2026 Free Spot available', recipients=[email]) + msg.html = render_template("waitlist_maillist_email.html", logo_url=logo, register_link=register_link, remove_link=remove_link) + mail.send(msg) + current_app.logger.info(f"Sent waitlist newsletter email to {email}") + @bp.route('/', methods=['GET', 'POST']) @limiter.limit("5 per hour", methods=["POST"]) def index(): @@ -109,9 +126,11 @@ def verify_email(token): if user.confirmed: return render_template('success.html', message="You are confirmed", discord_link=current_app.config['DISCORD_LINK'], discord_token=user.discord_token) else: - return render_template("error.html", error_message="Sorry! The event filled up while you were verifying.") + return render_template("error.html", error_message="Sorry! The event filled up while you were claiming the last spot.") else: user.confirmed = True + if user.on_waitlist: + user.on_waitlist = False db.session.commit() discord_link = current_app.config['DISCORD_LINK'] @@ -137,16 +156,14 @@ def remove_registration(token): if not user: return render_template("error.html", error_message="No user found.") - - try: - db.session.delete(user) - db.session.commit() - return render_template("deregistered.html", message="Sad to see you go. Comeback next time :D") - except: - db.session.rollback() - return render_template("error.html", error_message="Removing user did not work") + db.session.delete(user) + db.session.commit() + + if get_confirmed_count() == current_app.config['MAX_SPOTS'] - 1: + send_waitlist_newsletter() + + return render_template("deregistered.html", message="Sad to see you go. Comeback next time :D") - @bp.route('/dsgvo') @limiter.exempt def dsgvo(): diff --git a/app/templates/waitlist_maillist_email.html b/app/templates/waitlist_maillist_email.html new file mode 100644 index 0000000..489f63e --- /dev/null +++ b/app/templates/waitlist_maillist_email.html @@ -0,0 +1,69 @@ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Club Logo +
+

Registration Received

+
+ A spot has just become available for h4tum CTF 2026! Be fast and claim it! +
+ + + + +
+ + CLAIM THE SPOT + +
+
+ If you can not attend anymore / don't want to receive any further emails: +
+ + + + +
+ + DEREGISTER + +
+
+ This email is sent automatically every time a place becomes available. You can unsubscribe by pressing the big red button. +
+
+ +