@Rotmilan: Was meinst Du mit „noch ein bisschen leserlicher“?
Was in den Maildaten auch fehlt ist die Leerzeile die zwischen den Headern und dem Mailtext sein sollte. Das könnte auch ein Grund sein warum ein Mailserver die Mail ablehnt, oder zumindest mit höherer Wahrscheinlichkeit als Spam einstuft, denn E-Mail-Programme machen das in aller Regel korrekt, womit dieser Fehler auf ein Skript hindeutet, was wiederum eher Spammer verwenden würden.
Der Aufbau einer Nachricht wird in
RFC5322 spezifiziert. In der Regel gilt das Programme die das verarbeiten etwas entspannter sein sollten was die Regeln betrifft und so einiges durchgehen lassen was nicht der Spezifikation entspricht, aber wenn man Sachen falsch macht, welche die verbreiteten E-Mail-Programme *nicht* falsch machen, steigt das Risiko das irgendwo ein Programm auf dem Weg das als Spam einstuft und wegfiltert.
Aber auch erlaubte aber ungewöhnliche Eigenschaften der Nachricht können für Spamfilter suspekt aussehen. Beispielsweise, dass kein "To:"-Header vorhanden ist. Ich kenne keinen E-Mail-Client der den nicht setzt.
Dein letztes Beispiel kommt nicht am Compiler vorbei, weil in der Zeile wo `gesamtnachricht` definiert wird ein Zeilenumbruck im Ausdruck ist, der so nicht erlaubt ist. Den könnte man beispielsweise machen wenn der Ausdruck in Klammern stünde, weil der Compiler weiss, dass ein Ausdruck noch nicht zuende sein kann solange noch austehende schliessende Klammern fehlen.
Das ``with``-Schlüsselwort kann man mit Objekten verwenden die `__enter__()` und `__exit__()` entsprechend implementieren, also Kontextmanager sind. Das sorgt dafür das beim Verlassen des ``with``-Blocks *egal aus welchem Grund*, die `__exit__()`-Methode aufgerufen wird, die in der Regel aufräumarbeiten enthält. Bei `SMTP`-Objekten ist das der Aufruf der `quit()`-Methode.
Zwischen Worte in Namen setzt man Unterstriche. So weiss man jetzt nicht ob die Funktion deutsch oder englisch benannt ist — `sende_mail()` oder `send_email()`?
Das zusammenstückeln von Zeichenketten und Werten mittels ``+`` ist eher BASIC als Python. Dafür gibt es die `format()`-Methode auf Zeichenketten und f-Zeichenkettenliterale.
Zeichenkettenliterale die nur durch „whitespace“-Zeichen getrennt sind, setzt der Compiler automatisch zu einer Zeichenkette zusammen. So kann man die Nachricht lesbarer auf mehrere Zeilen im Quelltext verteilen.
`x` ist ein schlechter Name für — ja was ist das denn eigentlich? Namen sollen dem Leser vermitteln was der Wert dahinter bedeutet. `x` tut das beim X-Anteil von Koordinaten oder für eine Gleitkommazahl für eine generische mathematische Funktion. Eher nicht für den Rückgabewert von `sendmail()`.
Zwischenstand (ungetestet):
Code: Alles auswählen
#!/usr/bin/env python3
import smtplib
PASSWORT = "xyz"
ABSENDER = "sender@freenet.de"
EMPFAENGER = "empfaenger@freenet.de"
SERVER = "mx.freenet.de"
PORT = 587
def sende_mail(text, betreff="Standardbetreff"):
with smtplib.SMTP(SERVER, PORT) as smtp:
smtp.ehlo()
smtp.starttls()
smtp.login(ABSENDER, PASSWORT)
return smtp.sendmail(
ABSENDER,
EMPFAENGER,
(
f"From: {ABSENDER}\n"
f"To: {EMPFAENGER}\n"
f"Subject: {betreff}\n"
f"\n"
f"{text}\n"
),
)
def main():
sende_mail("Der Nachrichtentext, der Versand werden soll.")
if __name__ == "__main__":
main()
Das ist aber alles recht fragil. Alles was in die Nachricht kommt muss beispielsweise als ASCII kodierbar sein.
Man könnte sich eine Nachricht als Objekt zusammenbauen mit den Zutaten die man im `email`-Package in der Standardbibliothek findet, aber selbst das deckt nicht alle Fälle ab um die man sich wirklich nicht selbst kümmern möchte. Das ist alles nicht so wirklich praxistauglich. Da würde man ein externes Package wie `marrow.mailer` oder etwas vergleichbares benutzen.