Files
SemapForm/app/main.py
WorldTeacher 4738732517
Some checks failed
Docker Build (PR) / Build Docker image (pull_request) Failing after 3m19s
feat: add landing page, enable mail-to-terminal, show success message
closes #11
2025-11-19 13:22:30 +01:00

110 lines
3.8 KiB
Python
Executable File

import os
import re
import smtplib
from email.mime.text import MIMEText
from xml.etree.ElementTree import Element, SubElement, tostring
from fastapi import FastAPI, Form, HTTPException, Request, status
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
app = FastAPI()
templates = Jinja2Templates(directory="app/templates")
# Serve static files (CSS, images)
app.mount("/static", StaticFiles(directory="app/static"), name="static")
# add somewhere near the top-level constants
EMAIL_REGEX = re.compile(r"^[^@\s]+@[^@\s]+\.[^@\s]+$")
# SMTP / email configuration via environment
MAIL_ENABLED = os.getenv("MAIL_ENABLED", "false").lower() == "true"
SMTP_HOST = os.getenv("SMTP_HOST", "smtp")
SMTP_PORT = int(os.getenv("SMTP_PORT", "25"))
MAIL_FROM = os.getenv("MAIL_FROM", "noreply@example.com")
MAIL_TO = os.getenv("MAIL_TO", "destination@example.com")
@app.get("/", response_class=HTMLResponse)
async def landing_page(request: Request):
"""Landing page with service selection"""
return templates.TemplateResponse("index.html", {"request": request})
@app.get("/semesterapparat", response_class=HTMLResponse)
async def semesterapparat_form(request: Request):
"""Semesterapparat form page"""
return templates.TemplateResponse("semesterapparat_form.html", {"request": request})
@app.post("/submit")
async def handle_form(
request: Request,
name: str = Form(...),
lastname: str = Form(...),
title: str = Form(...),
telno: str = Form(...),
mail: str = Form(...),
apparatsname: str = Form(...),
subject: str = Form(...),
semester_type: str = Form(...), # "summer" or "winter"
semester_year: str = Form(...),
authorname: list[str] = Form(...),
year: list[str] = Form(...),
booktitle: list[str] = Form(...),
signature: list[str] = Form(...),
message: str = Form(default=""),
):
# Basic email validation (server-side)
if not EMAIL_REGEX.match(mail):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Invalid email address format.",
)
# Build XML
root = Element("form_submission")
static_data = SubElement(root, "static")
SubElement(static_data, "name").text = name
SubElement(static_data, "lastname").text = lastname
SubElement(static_data, "title").text = title
SubElement(static_data, "telno").text = telno
SubElement(static_data, "mail").text = mail
SubElement(static_data, "apparatsname").text = apparatsname
SubElement(static_data, "subject").text = subject
SubElement(static_data, "semester").text = f"{semester_type} {semester_year}"
if message:
SubElement(static_data, "message").text = message
books = SubElement(root, "books")
for i in range(len(authorname)):
book = SubElement(books, "book")
SubElement(book, "authorname").text = authorname[i]
SubElement(book, "year").text = year[i]
SubElement(book, "title").text = booktitle[i]
SubElement(book, "signature").text = signature[i]
xml_data = tostring(root, encoding="unicode")
# Send mail
msg = MIMEText(xml_data, "xml")
msg["Subject"] = "New Form Submission"
msg["From"] = MAIL_FROM
msg["To"] = MAIL_TO
if MAIL_ENABLED:
with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as server:
server.send_message(msg)
else:
print("=" * 80)
print("MAIL SENDING DISABLED - Would have sent:")
print(f"From: {MAIL_FROM}")
print(f"To: {MAIL_TO}")
print(f"Subject: {msg['Subject']}")
print("-" * 80)
print(xml_data)
print("=" * 80)
return RedirectResponse("/?success=true", status_code=303)