Mail Content as HTML

This commit is contained in:
MaPaLo76 2025-06-07 09:29:17 +02:00
parent c0f743db84
commit f8259e69c1

View File

@ -1,4 +1,5 @@
import click
import time
import logging
import xmlrpc.client
import yaml
@ -17,40 +18,75 @@ from collections import defaultdict
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
BATCH_SIZE = 20
BATCH_WAIT_SECONDS = 30 * 60 # 30 Minuten
PRODUCT_NAMES = ["Formatkreissäge (1 Minute)", "Hobel (1 Minute)"]
TRAINING_PRODUCTS = ["Einweisung FKS", "Einweisung Hobel"]
EMAIL_SUBJECT = "Neue Maschinen in der Werkstatt - Einweisungsvideos erforderlich"
EMAIL_BODY_TEMPLATE = """Hallo {name},
EMAIL_BODY_TEMPLATE = """
<html>
<body style="font-family: sans-serif; font-size: 14px; line-height: 1.6;">
<p>Hallo {name},</p>
wir freuen uns, dass du in den letzten zwei Jahren unsere Formatkreissäge oder unseren Abricht-/Dickenhobel genutzt hast. Wir haben tolle Nachrichten für dich!
<p>
wir freuen uns, dass du in den letzten zwei Jahren unsere Formatkreissäge oder unseren Abricht-/Dickenhobel genutzt hast. Wir haben tolle Nachrichten für dich!
</p>
Voraussichtlich ab dem 15.06. stehen die neuen Maschinen wieder zur Nutzung bereit.
Da du bereits für mindestens eine der beiden Maschinen eine Einweisung erhalten hast, ist für diese keine erneute Einweisung erforderlich.
<p>
Vielleicht hast du es schon mitbekommen: Vor knapp zwei Monaten haben wir die FormatkreissägeAbricht-/Dickenhobel-Kombi durch zwei neue Maschinen ersetzt.
<strong>Voraussichtlich ab dem 15.06.</strong> stehen die neue Formatkreissäge und der neue Abricht-/Dickenhobel wieder zur Nutzung bereit.
Da du bereits für mindestens eine der beiden Maschinen eine Einweisung erhalten hast, ist <strong>für diese keine erneute Einweisung erforderlich</strong>.
</p>
Wir bitten dich jedoch, dir vor der nächsten Nutzung die jeweiligen Einweisungsvideos auf YouTube anzuschauen. Diese ersetzen keine vollständige Einweisung, sind aber für uns eine wichtige Sicherheitsmaßnahme bei der Umstellung auf die neuen Maschinen:
<p>
Wir bitten dich jedoch, dir vor der nächsten Nutzung die jeweiligen Einweisungsvideos auf YouTube anzuschauen.
Diese ersetzen keine vollständige Einweisung, sind aber für uns eine wichtige Sicherheitsmaßnahme bei der Umstellung auf die neuen Maschinen:
</p>
Videoserie zur Formatkreissäge: https://...
Videoserie zum Abricht-/Dickenhobel: https://...
<ul>
<li><a href="https://www.youtube.com/playlist?list=PL3oeDnj7aMvkyCnmMH6uDlFCV7unT0r3P" target="_blank">Videoserie zur Formatkreissäge</a></li>
<li><a href="https://www.youtube.com/playlist?list=PL3oeDnj7aMvlG6T1xC38x1lTsXap154zU" target="_blank">Videoserie zum Abricht-/Dickenhobel</a></li>
</ul>
Vor der Nutzung werden wir dich fragen, ob du die Videos angesehen hast. Auf dieser Vertrauensbasis wird deine Freigabe im System aktiviert.
<p>
Vor der Nutzung werden wir dich fragen, ob du die Videos angesehen hast. Auf dieser Vertrauensbasis wird deine Freigabe im System aktiviert.
</p>
Über unsere Webseite informieren wir dich durch einen roten Hinweisbanner, ab wann die Maschinen wieder nutzbar sind.
<p>
Über unsere Webseite informieren wir dich durch einen roten Hinweisbanner, ab wann die Maschinen wieder nutzbar sind.
</p>
Bitte beachte, dass die Maschinen nur von Personen genutzt werden dürfen, die eine Einweisung erhalten haben. Solltest du für eine der beiden Maschinen noch keine Einweisung erhalten haben, melde dich gerne bei uns, um einen Termin zu vereinbaren.
<p>
Bitte beachte, dass die Maschinen nur von Personen genutzt werden dürfen, die eine Einweisung erhalten haben.
Solltest du für eine der beiden Maschinen noch keine Einweisung erhalten haben, melde dich gerne bei uns, um einen Termin zu vereinbaren.
</p>
---
<hr>
Diese E-Mail ist eine einmalige Information aus gegebenem Anlass. Wir versenden in der Regel keinen Newsletter oder Werbung. Vielen Dank für dein Verständnis.
<p>
Diese E-Mail ist eine einmalige Information aus gegebenem Anlass.
Wir versenden in der Regel keinen Newsletter oder Werbung. Vielen Dank für dein Verständnis.
</p>
Mit werkstattfreundlichen Grüßen
Dein Hobbyhimmel-Team
<p>
Mit werkstattfreundlichen Grüßen<br>
Dein Hobbyhimmel-Team
</p>
---
<hr>
Hinweis gemäß Art. 6 Abs. 1 lit. f DSGVO:
Diese Information erhältst du, weil du in den letzten zwei Jahren entsprechende Maschinen in unserer Werkstatt genutzt hast. Die Kontaktaufnahme erfolgt im Rahmen unseres berechtigten Interesses, dich über sicherheitsrelevante Änderungen zu informieren.
<p style="font-size: 12px; color: gray;">
Hinweis gemäß Art. 6 Abs. 1 lit. f DSGVO:<br>
Diese Information erhältst du, weil du in den letzten zwei Jahren entsprechende Maschinen in unserer Werkstatt genutzt hast.
Die Kontaktaufnahme erfolgt im Rahmen unseres berechtigten Interesses, dich über sicherheitsrelevante Änderungen zu informieren.
</p>
</body>
</html>
"""
def test_odoo_api_connection(odoo_api: dict):
"""
Testet die Verbindung zur Odoo API und authentifiziert den Benutzer.
@ -109,7 +145,7 @@ def send_email(secrets, email, subject, body):
msg['From'] = email_sender
msg['To'] = email_receiver
msg['Subject'] = subject
msg.attach(MIMEText(body, 'plain'))
msg.attach(MIMEText(body, 'html'))
signature = """
<p><strong><span style="font-size: 14px;"><span style="color: #99cc00;">HOBBY</span>HIMMEL</span> - </strong>Die Offene Werkstatt<br />Siemensstrasse 140<br />70469 Stuttgart - Feuerbach<br /><br />0172 / 77 88&nbsp;0 44<br /><a href="mailto:info@hobbyhimmel.de" target="_blank" rel="nofollow noopener">info@hobbyhimmel.de</a><br /><br /><a href="http://www.hobbyhimmel.de/" target="_blank" rel="nofollow noopener">hobbyhimmel.de</a>&nbsp;|&nbsp;<a href="https://facebook.com/hobbyhimmel.stuttgart" target="_blank" rel="nofollow noopener">facebook.com/hobbyhimmel.stuttgart</a>&nbsp;|&nbsp;<a href="https://www.instagram.com/explore/locations/1024077988/hobbyhimmel-die-offene-werkstatt/" target="_blank" rel="nofollow noopener">instagram.de/hobbyhimmel</a><br />VVOW e. V. - Verein zur Verbreitung Offener Werkst&auml;tten |&nbsp;<a href="http://www.vvow.de/" target="_blank" rel="nofollow noopener">vvow.de</a></p>
@ -310,13 +346,10 @@ def main(send,years,testmail):
partners = get_partner_emails(models, db, uid, secrets['odoo-api']['password'], partner_ids)
employee_partner_ids = get_all_employees(models, db, uid, secrets['odoo-api']['password'])
logger.info(f"📋 Es wurden {len(partners)} Partner mit E-Mail gefunden.")
count = 0
count_hero = 0
for partner in partners:
for i, partner in enumerate(partners):
name = partner['name']
email = partner['email']
if testmail:
@ -327,6 +360,10 @@ def main(send,years,testmail):
if send or testmail:
send_email(secrets, email, subject=EMAIL_SUBJECT, body=message)
logger.debug(f"📧 E-Mail an {email} gesendet.")
# Pausieren nach jedem BATCH_SIZE-Versand
if (i + 1) % BATCH_SIZE == 0:
logger.info(f"⏸️ Batchgrenze erreicht Warte {BATCH_WAIT_SECONDS // 60} Minuten ...")
time.sleep(BATCH_WAIT_SECONDS)
else:
logger.debug(f"🔍 Testmodus: {email} würde E-Mail erhalten. Name: {name}")
count += 1