v1
Some checks failed
CI / test (3.11) (push) Failing after 5m36s
CI / build-image (push) Has been skipped

This commit is contained in:
2025-10-22 16:48:55 +02:00
commit 4cefd4e3ab
53 changed files with 5837 additions and 0 deletions

133
server/routes/newsletter.py Normal file
View File

@@ -0,0 +1,133 @@
"""Newsletter subscription routes."""
from __future__ import annotations
import logging
from flask import Blueprint, jsonify, request, render_template
from ..services import newsletter
bp = Blueprint("newsletter", __name__, url_prefix="/api")
@bp.route("/newsletter", methods=["POST"])
def subscribe():
payload = request.form or request.get_json(silent=True) or {}
email = (payload.get("email") or "").strip()
if not newsletter.validate_email(email):
return jsonify({"status": "error", "message": "Valid email is required."}), 400
try:
created = newsletter.subscribe(email)
except Exception as exc: # pragma: no cover - errors are logged
logging.exception("Failed to persist subscriber: %s", exc)
return jsonify({"status": "error", "message": "Could not store subscription."}), 500
if not created:
logging.info("Newsletter subscription ignored (duplicate): %s", email)
return jsonify({"status": "error", "message": "Email is already subscribed."}), 409
logging.info("New newsletter subscription: %s", email)
return jsonify({"status": "ok", "message": "Subscribed successfully."}), 201
@bp.route("/newsletter", methods=["DELETE"])
def unsubscribe():
payload = request.form or request.get_json(silent=True) or {}
email = (payload.get("email") or "").strip()
if not newsletter.validate_email(email):
return jsonify({"status": "error", "message": "Valid email is required."}), 400
try:
deleted = newsletter.unsubscribe(email)
except Exception as exc: # pragma: no cover - errors are logged
logging.exception("Failed to remove subscriber: %s", exc)
return jsonify({"status": "error", "message": "Could not remove subscription."}), 500
if not deleted:
logging.info(
"Newsletter unsubscription ignored (not subscribed): %s", email)
return jsonify({"status": "error", "message": "Email is not subscribed."}), 404
logging.info("Newsletter unsubscription: %s", email)
return jsonify({"status": "ok", "message": "Unsubscribed successfully."}), 200
@bp.route("/newsletter", methods=["PUT"])
def update_subscription():
payload = request.form or request.get_json(silent=True) or {}
old_email = (payload.get("old_email") or "").strip()
new_email = (payload.get("new_email") or "").strip()
if not newsletter.validate_email(old_email) or not newsletter.validate_email(new_email):
return jsonify({"status": "error", "message": "Valid old and new emails are required."}), 400
try:
updated = newsletter.update_email(old_email, new_email)
except Exception as exc: # pragma: no cover - errors are logged
logging.exception("Failed to update subscriber: %s", exc)
return jsonify({"status": "error", "message": "Could not update subscription."}), 500
if not updated:
return jsonify({"status": "error", "message": "Old email not found or new email already exists."}), 404
logging.info("Newsletter subscription updated: %s -> %s",
old_email, new_email)
return jsonify({"status": "ok", "message": "Subscription updated successfully."}), 200
@bp.route("/newsletter/manage", methods=["GET", "POST"])
def manage_subscription():
"""Display newsletter subscription management page."""
message = None
message_type = None
if request.method == "POST":
action = request.form.get("action")
email = (request.form.get("email") or "").strip()
if not newsletter.validate_email(email):
message = "Please enter a valid email address."
message_type = "error"
else:
try:
if action == "subscribe":
created = newsletter.subscribe(email)
if created:
message = "Successfully subscribed to newsletter!"
message_type = "success"
else:
message = "This email is already subscribed."
message_type = "info"
elif action == "unsubscribe":
deleted = newsletter.unsubscribe(email)
if deleted:
message = "Successfully unsubscribed from newsletter."
message_type = "success"
else:
message = "This email is not currently subscribed."
message_type = "info"
elif action == "update":
old_email = (request.form.get("old_email") or "").strip()
if not newsletter.validate_email(old_email):
message = "Please enter a valid current email address."
message_type = "error"
elif old_email == email:
message = "New email must be different from current email."
message_type = "error"
else:
updated = newsletter.update_email(old_email, email)
if updated:
message = "Email address updated successfully!"
message_type = "success"
else:
message = "Current email not found or new email already exists."
message_type = "error"
except Exception as exc:
logging.exception("Failed to manage subscription: %s", exc)
message = "An error occurred. Please try again."
message_type = "error"
return render_template("newsletter_manage.html", message=message, message_type=message_type)