104 lines
3.1 KiB
Python
104 lines
3.1 KiB
Python
import os
|
|
import re
|
|
from pathlib import Path
|
|
|
|
import resend
|
|
from flask import Flask, jsonify, request, send_from_directory
|
|
from dotenv import load_dotenv
|
|
|
|
load_dotenv()
|
|
|
|
SITE_ROOT = Path(__file__).parent.resolve()
|
|
|
|
RESEND_API_KEY = os.environ.get("RESEND_API_KEY", "")
|
|
CONTACT_TO = os.environ.get("CONTACT_TO", "alex@lean-101.com")
|
|
CONTACT_FROM = os.environ.get("CONTACT_FROM", "Lean 101 Website <noreply@lean-101.com>")
|
|
|
|
resend.api_key = RESEND_API_KEY
|
|
|
|
app = Flask(__name__, static_folder=None)
|
|
|
|
EMAIL_RE = re.compile(r"^[^@\s]+@[^@\s]+\.[^@\s]+$")
|
|
|
|
|
|
def _clip(value: str, limit: int) -> str:
|
|
value = (value or "").strip()
|
|
return value[:limit]
|
|
|
|
|
|
@app.post("/api/contact")
|
|
def contact():
|
|
form = request.form if request.form else request.get_json(silent=True) or {}
|
|
|
|
if (form.get("website") or "").strip():
|
|
return jsonify({"ok": True}), 200
|
|
|
|
name = _clip(form.get("name", ""), 200)
|
|
email = _clip(form.get("email", ""), 200)
|
|
company = _clip(form.get("company", ""), 200)
|
|
message = _clip(form.get("message", ""), 5000)
|
|
|
|
if not name or not email or not message:
|
|
return jsonify({"error": "Please fill in your name, email, and message."}), 400
|
|
if not EMAIL_RE.match(email):
|
|
return jsonify({"error": "That email address doesn't look right."}), 400
|
|
|
|
if not RESEND_API_KEY:
|
|
app.logger.error("RESEND_API_KEY not configured")
|
|
return jsonify({"error": "Email is not configured on the server."}), 500
|
|
|
|
html = (
|
|
f"<p><strong>Name:</strong> {name}</p>"
|
|
f"<p><strong>Email:</strong> {email}</p>"
|
|
f"<p><strong>Company:</strong> {company or '—'}</p>"
|
|
f"<p><strong>Looking to improve:</strong></p>"
|
|
f"<p>{message.replace(chr(10), '<br>')}</p>"
|
|
)
|
|
|
|
try:
|
|
resend.Emails.send({
|
|
"from": CONTACT_FROM,
|
|
"to": [CONTACT_TO],
|
|
"reply_to": email,
|
|
"subject": f"New Lean 101 enquiry — {name}"
|
|
+ (f" ({company})" if company else ""),
|
|
"html": html,
|
|
})
|
|
except Exception as exc:
|
|
app.logger.exception("Resend send failed: %s", exc)
|
|
return jsonify({"error": "Couldn't send your message. Please try again."}), 502
|
|
|
|
return jsonify({"ok": True}), 200
|
|
|
|
|
|
@app.route("/", defaults={"path": ""})
|
|
@app.route("/<path:path>")
|
|
def static_files(path: str):
|
|
if not path:
|
|
return send_from_directory(SITE_ROOT, "index.html")
|
|
|
|
target = (SITE_ROOT / path).resolve()
|
|
try:
|
|
target.relative_to(SITE_ROOT)
|
|
except ValueError:
|
|
return ("Not found", 404)
|
|
|
|
if target.is_dir():
|
|
index = target / "index.html"
|
|
if index.exists():
|
|
return send_from_directory(target, "index.html")
|
|
return ("Not found", 404)
|
|
|
|
if target.exists():
|
|
return send_from_directory(target.parent, target.name)
|
|
|
|
html_candidate = target.with_suffix(".html")
|
|
if html_candidate.exists():
|
|
return send_from_directory(html_candidate.parent, html_candidate.name)
|
|
|
|
return ("Not found", 404)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
app.run(host="127.0.0.1", port=int(os.environ.get("PORT", "5000")), debug=True)
|