smtplib formatiert text nicht um \n\t\t

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
Chris0814
User
Beiträge: 4
Registriert: Mittwoch 17. Oktober 2018, 12:10

Hallo liebe Python Gemeinde,

ich bin Neue.

Zu meinem kleinen Problem
Ich wollte mir ein kleines gadget schreiben welches mir morgens automatisch eine Email mit einem "weisen" Spruch schickt.
mit fortune und schon vorhandenem smtp Server kein Problem, dachte ich.

wenn ich über die cli den script mit python starte funktioniert das ganze hervorragend.
Bsp.:
Ein Mathematiker betritt ein Fotogeschäft:
"Ich hätte gern einen Farbfilm."
"24x36?", fragt der Verkäufer.
Der Mathematiker: "864, warum fragen Sie?"

über cron wird das ganze leider nicht formatiert.
Bsp.:
b'NT ist auch ein UNIX - es ist ja schlie\xc3\x9flich in C geschrieben.\n\t\t-- Compaq Techsupport Hotline\n'

Mein python code sieht so aus:

Code: Alles auswählen

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

senderEmail = "sender@email"
empfangsEmail = 'empfänger@email'
msg = MIMEMultipart()
msg['MIME-Version']="1.0"
msg['From'] = senderEmail
msg['To'] = empfangsEmail
msg['Subject'] = "Zitat des Tages"
msg['Content-Type'] = "text/html; charset=utf-8"
msg['Content-Transfer-Encoding'] = "quoted-printable"

zitat = subprocess.check_output(['/usr/games/fortune', 'de', '-s'])
emailText = """%s""" % zitat

msg.attach(MIMEText(emailText))

server = smtplib.SMTP('>serverip<', >port<) # Die Server Daten
server.starttls()
server.login(senderEmail, ">meinpw<") # Das Passwort
text = msg.as_string()
server.sendmail(senderEmail, empfangsEmail.split(','), text)
server.quit()
cron

Code: Alles auswählen

15 6 * * 1-5 /home/pi/spruchdestages.py > /home/pi/spruchdestages.log 2>&1
Mit Content-Type html und plain hab ich gerade rumprobiert ergab aber auch keine Besserung
Ich gehe eventuell davon aus, dass cron irgendeine Berechtigung in der smtp lib fehlt wäre das möglich? :roll:
Hat jemand eine Idee

Grüße Christian
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Eigentlich sollte immer ein Bytes-Objekt von check_output geliefert werden. Ansonsten hängt das Encoding bei Python 3 von Umgebungsvariablen (LANG) ab, die beim cron-Job-Aufruf anders gesetzt sein könnten.

Eigentlich müßte es also

Code: Alles auswählen

emailText = zitat.decode('utf8')
heißen.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Dass es Bytes sind, sieht man auch an dem vorangestellten "b" beim Text. Das ist halt die Repräsention eines Byte-Objektes, wenn man "%s" % text anwendet. Lösen kann man das so:

Code: Alles auswählen

zitat = subprocess.run(['/usr/games/fortune', 'de', '-s'], text=True, check=True)
Chris0814
User
Beiträge: 4
Registriert: Mittwoch 17. Oktober 2018, 12:10

Hallo zusammen,

danke für die schnellen Antworten.

subprocess.run gibts laut google erst ab python3.5

ab python3.5 ist openssl leider nichtmehr standart.
und Raspbian macht anscheinend Probleme mit python3.5+
Openssl zu aktivieren funktioniert momentan noch nicht.

gibt es eine alternative zu subprocess.run?
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Die Alternative wurde von Sirius3 ja schon beschrieben:

Code: Alles auswählen

zitat.decode('utf8')
Chris0814
User
Beiträge: 4
Registriert: Mittwoch 17. Oktober 2018, 12:10

Da hast du recht, tut mir Leid :oops:

Der Vorschlag von Sirius funktioniert einwandfrei.
Vielen dank dafür.

Euch beiden natürlich.
Chris0814
User
Beiträge: 4
Registriert: Mittwoch 17. Oktober 2018, 12:10

Falls es jemanden interessieren sollte, mit Python version 2.7.9 läuft es so:

Code: Alles auswählen

#!/usr/bin/env python
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import subprocess

senderEmail = "sender@mail.com"
empfangsEmail = 'empfänger@mail.com,empfänger2@mail.com'
msg = MIMEMultipart()
msg['MIME-Version']="1.0"
msg['From'] = senderEmail
msg['To'] = empfangsEmail
msg['Subject'] = "Zitat des Tages"

zitat = subprocess.check_output(['/usr/games/fortune', 'de', '-s'])
zitat.decode('utf8')
emailText = """%s""" % zitat

msg.attach(MIMEText(emailText))

server = smtplib.SMTP('serverIP', serverport) # Die Server Daten
server.starttls()
server.login(senderEmail, "Passwort") # Das Passwort
text = msg.as_string()
server.sendmail(senderEmail, empfangsEmail.split(','), text)
server.quit()

Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wenn schon emailText = """%s""" % zitat.decode('utf-8'), sonst arbeitest du immer noch auf den Bytes anstatt auf dem String und es hätte sich somit überhaupt nichts verändert am Ergebnis. Außerdem ist das String-Formatting unnötig, da man durch den decode()-Aufruf bereits hat, was man will. Richtig wäre demnach:

Code: Alles auswählen

email_text = zitat.decode('utf-8')
Antworten