diff --git a/app/main.py b/app/main.py index 8930e82..f339833 100755 --- a/app/main.py +++ b/app/main.py @@ -2,13 +2,16 @@ import os import re import smtplib from email.mime.text import MIMEText +from typing import Optional from xml.etree.ElementTree import Element, SubElement, tostring +from dotenv import load_dotenv from fastapi import FastAPI, Form, HTTPException, Request, status from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates +load_dotenv() app = FastAPI() templates = Jinja2Templates(directory="app/templates") @@ -21,8 +24,15 @@ EMAIL_REGEX = re.compile(r"^[^@\s]+@[^@\s]+\.[^@\s]+$") # SMTP / email configuration via environment SMTP_HOST = os.getenv("SMTP_HOST", "smtp") SMTP_PORT = int(os.getenv("SMTP_PORT", "25")) -MAIL_FROM = os.getenv("MAIL_FROM", "noreply@example.com") +SENDER_MAIL = os.getenv("SENDER_MAIL", "noreply@example.com") MAIL_TO = os.getenv("MAIL_TO", "destination@example.com") +MAIL_USERNAME = os.getenv("MAIL_USERNAME") +MAIL_PASSWORD = os.getenv("MAIL_PASSWORD") + +print( + f"Using SMTP server {SMTP_HOST}:{SMTP_PORT} with user {MAIL_USERNAME}" + f" to send from {SENDER_MAIL} to {MAIL_TO}" +) @app.get("/", response_class=HTMLResponse) @@ -35,17 +45,18 @@ async def handle_form( request: Request, name: str = Form(...), lastname: str = Form(...), - title: str = Form(...), + title: Optional[str] = Form(None), telno: str = Form(...), mail: str = Form(...), apparatsname: str = Form(...), subject: str = Form(...), semester_type: str = Form(...), # "summer" or "winter" semester_year: str = Form(...), + dauerapparat: bool = Form(False), authorname: list[str] = Form(...), year: list[str] = Form(...), booktitle: list[str] = Form(...), - signature: list[str] = Form(...), + signature: Optional[list[str]] = Form(None), ): # Build XML root = Element("form_submission") @@ -53,12 +64,14 @@ async def handle_form( static_data = SubElement(root, "static") SubElement(static_data, "name").text = name SubElement(static_data, "lastname").text = lastname - SubElement(static_data, "title").text = title + # Title is optional + SubElement(static_data, "title").text = title or "" 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}" + SubElement(static_data, "dauerapparat").text = "true" if dauerapparat else "false" # inside handle_form(), right after parameters are received, before building XML: # Basic email validation (server-side) if not EMAIL_REGEX.match(mail): @@ -72,17 +85,27 @@ async def handle_form( SubElement(book, "authorname").text = authorname[i] SubElement(book, "year").text = year[i] SubElement(book, "title").text = booktitle[i] - SubElement(book, "signature").text = signature[i] + # Signature is optional; write empty string if not provided + sig_value = "" + if signature and i < len(signature): + sig_raw = signature[i] or "" + sig_value = sig_raw.strip() + SubElement(book, "signature").text = sig_value xml_data = tostring(root, encoding="unicode") # Send mail msg = MIMEText(xml_data, "xml") - msg["Subject"] = "New Form Submission" - msg["From"] = MAIL_FROM + msg["Subject"] = "Antrag für neuen Semesterapparat" + msg["From"] = SENDER_MAIL msg["To"] = MAIL_TO - with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as server: - server.send_message(msg) + with smtplib.SMTP_SSL(SMTP_HOST, SMTP_PORT) as server: + server.connect(SMTP_HOST, SMTP_PORT) + # Login only if credentials are provided + if MAIL_USERNAME and MAIL_PASSWORD: + server.login(MAIL_USERNAME, MAIL_PASSWORD) + + server.send_message(msg, from_addr=SENDER_MAIL, to_addrs=[MAIL_TO]) return RedirectResponse("/", status_code=303) diff --git a/app/static/styles.css b/app/static/styles.css index e519780..7832fa7 100644 --- a/app/static/styles.css +++ b/app/static/styles.css @@ -53,6 +53,7 @@ body { display: flex; align-items: center; gap: 14px; + height: 72px; padding: 14px 0; justify-content: space-between; } @@ -273,6 +274,10 @@ input[type="radio"] { accent-color: var(--control-accent); } justify-content: center; text-align: center; } +.inline-controls.start { + justify-content: flex-start; + text-align: left; +} .inline-controls input[type="number"] { width: 120px; text-align: center; diff --git a/app/templates/form.html b/app/templates/form.html index ad0ecd2..16cee9e 100755 --- a/app/templates/form.html +++ b/app/templates/form.html @@ -38,8 +38,8 @@
| Autorenname | Jahr/Auflage | Titel | Signatur | +Autorenname | Jahr/Auflage | Titel | Signatur (wenn vorhanden) |
|---|---|---|---|---|---|---|---|
| - | + |