Hallo,
ich experimentiere gerade ein wenig mit dem Modul "email" herum. Dabei bin ich auf einen Effekt gestoßen, der mir zeigt, wie wenig ich bisher von den eMail-Kodierungen verstanden habe. Vielleicht kann mir jemand von euch weiterhelfen.
Und zwar gehe ich folgendermaßen vor, um ein eMail-Gateway zu bauen:
- ich sende eine eMail mit dem SUBJECT "ich will jetzt endlich Würstchen..." an eine eigene eMail-Adresse z.B. "gateway@web.de"
- ich verwende ein Python-Skript und das Modul "imapclient", um die eMail von gateway@web.de per IMAP zu holen. Per imapclient.fetch() .
- ich dekodiere die eMail über email.message_from_string() und hole mir per message.get_all('subject')[0] den SUBJECT
Nun sehe ich folgendes im zurückgegebenen SUBJECT-String:
'ich will jetzt endlich =?UTF-8?B?V8O8cnN0Y2hlbi4uLg==?='
Wenn ich KEINE Umlaute verwende, also z.B. "ue" anstatt "ü", so erhalte ich an dieser Stelle einen komplett lesbaren String.
FRAGEN
(1) Kann mir jemand erläutern, was unterwegs mit meinem SUBJECT passiert ist?
(2) Gibt es eine Möglichkeit, den Betreff einer eMail (trotz Umlauten) sauber zu übertragen?
Danke.
Nnako
email modul - subject (Betreff) nicht lesbar darstellbar
@nnako: das Mail-Protokoll ist ein 7bit Protokoll, daher müssen Zeichen die außerhalb von ASCII liegen codiert werden, hier mit base64-encoded utf8. Zwischen =? und dem nächsten ? steht das Encoding und dann bis ?= steht der base64-codierte String.
Code: Alles auswählen
>>> text = 'ich will jetzt endlich =?UTF-8?B?V8O8cnN0Y2hlbi4uLg==?='
>>> re.sub('=\?(.*?)\?B\?(.*?)\?=', lambda m: m.group(2).decode('base64').decode(m.group(1)), text)
u'ich will jetzt endlich W\xfcrstchen...'
Wobei das `email`-Package da auch etwas für hat:
Aus den (Bytestring, Encoding)-Tupeln kann man dann eine Unicode-Zeichenkette zusammenbasteln.
Code: Alles auswählen
In [14]: email.Header.decode_header('ich will jetzt endlich =?UTF-8?B?V8O8cnN0Y2hlbi4uLg==?=')
Out[14]: [('ich will jetzt endlich', None), ('W\xc3\xbcrstchen...', 'utf-8')]
Hallo ihr beiden,
vielen Dank, habe nun letztere Variante verwendet:
vielen Dank, habe nun letztere Variante verwendet:
Code: Alles auswählen
#get the module
import email
# decode subject if there were special characters
tmpSubject = email.header.decode_header(strOriginalSubject)
# run through encoded subject
result = ''
for part in tmpSubject:
# check if there is an encoding
if part[1] == None:
# copy part
result = result + part[0].decode('iso-8859-1')
else:
# decode part
result = result + part[0].decode(part[1])
oder kurz:
Code: Alles auswählen
result = ''.join(text.decode(encoding or 'iso-8859-1') for text, encoding in tmpSubject)