from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.application import MIMEApplication import smtplib import time import os import Web.modules.database.settings as cfg def _build_smtp_client(): smtp = smtplib.SMTP( "mail.invario-software.de", 587, timeout=10, ) smtp.ehlo() if True: smtp.starttls() smtp.ehlo() smtp.login("no-reply@invario-software.de", "eSpage,65,{") return smtp def _normalize_recipients(email: list | str) -> list[str]: if isinstance(email, str): email = email.replace(';', ',').split(',') return [str(recipient).strip() for recipient in (email or []) if str(recipient).strip()] def send( email: list | str, subject: str, text_body: str, html_body: str = None, attachments: list = None ) -> bool: """Sends the email with Plain Text, HTML, and optional File Attachments support.""" if isinstance(email, str): email = [email] if attachments is None: attachments = [] TEXT_SIGNATURE = ( "\n\n--\n" "Mit freundlichen Grüßen\n" "Ihr Invario Team\n\n" "Invario UG\n" "Am Sportplatz 10\n" "83052 Bruckmühl" ) HTML_SIGNATURE = """

Mit freundlichen Grüßen,

Ihr Invario Team


Invario UG
Am Sportplatz 10
83052 Bruckmühl

""" text_content = f"{text_body}{TEXT_SIGNATURE}" if html_body: html_content = f"
{html_body}{HTML_SIGNATURE}
" else: # Fallback if only text is provided html_safe_text = text_body.replace('\n', '
') html_content = f"

{html_safe_text}

{HTML_SIGNATURE}" mails_per_second = 10 interval = 1.0 / mails_per_second smtp = None try: smtp = _build_smtp_client() for i, recipient in enumerate(email): start_time = time.time() # Root message structure for email with attachments msg = MIMEMultipart("mixed") msg["Subject"] = subject msg["From"] = "Invario Team " msg["To"] = str(recipient) # Sub-container for Plain Text and HTML bodies msg_body = MIMEMultipart("alternative") msg_body.attach(MIMEText(text_content, "plain")) msg_body.attach(MIMEText(html_content, "html")) msg.attach(msg_body) # Attach files if provided for file_path in attachments: if file_path and os.path.isfile(file_path): filename = os.path.basename(file_path) with open(file_path, "rb") as file: part = MIMEApplication(file.read(), Name=filename) part['Content-Disposition'] = f'attachment; filename="{filename}"' msg.attach(part) smtp.sendmail( from_addr="no-reply@invario-software.de", to_addrs=[recipient], msg=msg.as_string() ) elapsed_time = time.time() - start_time sleep_time = interval - elapsed_time if sleep_time > 0 and i < len(email) - 1: time.sleep(sleep_time) return True except Exception as e: print(f"Debug: Fehler beim Senden der E-Mail: {e}") return False finally: if smtp: try: smtp.quit() except Exception: pass