Datei auslesen und Inhalt mit smtplib verschicken

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
fred0815
User
Beiträge: 3
Registriert: Dienstag 20. Dezember 2022, 16:00

Moin, ich möchte eine Textdatei auslesen und den Inhalt per Mail verschicken.
Leider klappt das nicht.
Die Fehlermeldung beim ausführen lautet:
'str' object has no attribute 'policy'

Das Pythonscript sieht so im Moment so aus:

Code: Alles auswählen

#!/usr/bin/env python3

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from pathlib import Path
import smtplib
import time
import glob
import os

PORT = 587
VON = 'a@gmx.de'
ZU  = 'b@gmx.de'
BENUTZERNAME = 'a@gmx.de'
PASSWORT = 'geheim'

msg = MIMEMultipart()
msg['Subject'] = 'Email'
msg['From'] = 'a@gmx.de'
msg['To'] = 'b@gmx.de'

def sende_email():
    with smtplib.SMTP('mail.gmx.net', PORT) as server:
        server.ehlo('a@gmx.de')
        server.starttls()
        server.ehlo('a@gmx.de')
        server.login(BENUTZERNAME, PASSWORT)
        list_of_files = glob.glob('/pfad/zur/*.txt')
        latest_file = max(list_of_files, key=os.path.getctime)
        print(latest_file)
        with open(latest_file) as datei:
            print(datei.read())
            body = datei.read()
            msg.attach(body)
            server.sendmail(VON, ZU, msg.as_string())
            print("Erfolg")
            server.quit()

def main():
    sende_email()
    time.sleep(5)

if __name__ == "__main__":
    try:
        main()
    except Exception as e:
        print(e)
Kann mir jemand sagen, wie ich den Inhalt der Datei unkompliziert in die Email bekomme ?
fred0815
User
Beiträge: 3
Registriert: Dienstag 20. Dezember 2022, 16:00

Hat sich schon erledigt:

Code: Alles auswählen

#!/usr/bin/env python3
import glob
import os
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

smtpServer = "mail.gmx.net"
smtpPort = 587
username = "a@gmx.de"
password = "geheim"
sender = "a@gmx.de"
reciever = "b@gmx.de"
subject = "Mail"
msg = MIMEMultipart()
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = reciever
smtpObj = smtplib.SMTP(smtpServer, smtpPort)
smtpObj.set_debuglevel(1)
smtpObj.starttls()
smtpObj.login(username, password)
list_of_files = glob.glob('/pfad/zum/*.txt')
latest_file = max(list_of_files, key=os.path.getctime)
print(latest_file)
with open(latest_file) as datei:
    body = datei.read()
    part = MIMEText(body, 'plain')
    msg.attach(part)
    smtpObj.sendmail(sender, reciever, msg.as_string())
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@fred0815: Du hier? 🙂 Hättest Du mal in Stammtisch was gesagt, dann hätte ich früher hier reingeschaut.

Im ersten Beitrag sind die Konstanten ja noch korrekt gross geschrieben und es gibt Funktionen. Mindestens eine sollte es geben.

Namen ausser Konstanten und Klassen (PascalCase) werden klein_mit_unterstrichen geschrieben.

Die Ausnahmebehandlung im ersten Beitrag ist schlecht (ist ja netterweise auch verschwunden) weil da Information zur Fehlersuch einfach weggeworfen wird.

`obj` ist ein unsinniger Namenszusatz. In Python ist *alles* ein Objekt, also könnte man das an jeden Namen noch anhängen, es hat aber keinerlei Information für den Leser.

Das erstellen der Mail und das versenden ist ziemlich wild vermischt. Sinnvolle Reihenfolge wäre Datei laden, Nachricht erstellen, Verbindung zum Server aufbauen, Nachricht verschicken. Wenn einer der Schritt nicht klappt, beispielsweise weil es gar keine Textdatei in dem Verzeichnis gibt, oder die Rechte nicht ausreichen die Datei zu lesen, oder die Kodierung (das Böse Wort der Woche) nicht passt und die Datei deswegen nicht gelesen werden kann, dann braucht man die jeweiligen Folgeschritte ja gar nicht erst anfangen.

Was bei den Schritten die ich da gerade aufgezählt habe fehlt, genau wie im Programm, ist die Verbindung zum Server wieder abzubauen. So weiss man nicht ob die sauber mit dem entsprechenden SMTP-Befehl beendet wird, oder ob das Programm oder das Betriebssystem am Ende einfach die TCP-Verbindung kappt ohne Tschüss zu sagen. `SMTP`-Objekte sind Kontextmanager, die kann man also mit ``with`` verwenden.

`os` und `glob.glob()` verwendet man eher nicht mehr für Sachen die mit `pathlib` gemacht werden können.

Beim öffnen oder einlesen von Textdateien sollte man immer explizit die Kodierung angeben. Sonst wird da ”geraten”.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from pathlib import Path

SMTP_SERVER = "mail.gmx.net"
SMTP_PORT = 587
USERNAME = "a@gmx.de"
PASSWORD = "geheim"
SENDER = "a@gmx.de"
RECIEVER = "b@gmx.de"
SUBJECT = "Mail"


def main():
    body = max(
        Path("/pfad/zum").glob("*.txt"), key=lambda path: path.stat().st_ctime
    ).read_text(encoding="utf-8")

    message = MIMEMultipart()
    message["From"] = SENDER
    message["To"] = RECIEVER
    message["Subject"] = SUBJECT
    message.attach(MIMEText(body, "plain"))

    with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as smtp_client:
        smtp_client.set_debuglevel(1)
        smtp_client.starttls()
        smtp_client.login(USERNAME, PASSWORD)
        smtp_client.sendmail(SENDER, RECIEVER, message.as_string())


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
fred0815
User
Beiträge: 3
Registriert: Dienstag 20. Dezember 2022, 16:00

Ja, das Forum war heute zuerst nur zum testen offen, für Leute mit Anmeldung, deshalb habe ich mal hier gepostet.
Aber ich musste erst warten, bis ein Mod den Beitrag freigeschalten hat.
Antworten