email 8bit encoding

R

rurpy

How, using Python-3.3's email module, do I "flatten" (I think
that's the right term) a Message object to get utf-8 encoded
body with the headers:
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
when the message payload was set to a python (unicode) string?
 
W

W. Trevor King

How, using Python-3.3's email module, do I "flatten" (I think
that's the right term) a Message object to get utf-8 encoded
body with the headers:
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
when the message payload was set to a python (unicode) string?

I asked about this a while back [1], but never got a response. My
current best-guess is here [2]. My fallback flattening works for
everything except the 8-bit encoded messages using the UTF-16 charset,
but it's pretty ugly.

Let me know if you figure out something cleaner :).

Cheers,
Trevor

[1]: http://thread.gmane.org/gmane.comp.python.general/725425
[2]: https://github.com/wking/rss2email/blob/master/rss2email/email.py#L226

--
This email may be signed or encrypted with GnuPG (http://www.gnupg.org).
For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.20 (GNU/Linux)

iQIcBAEBAgAGBQJR9giiAAoJEKKfehoaNkbto/AP/2lN0kcKTO9FHwRs5bKlhxLs
4KZ03VRDAOocVnL7mRwAIhvcA0WVRl6PJRb83zqS8UKAacGxcsUNXaZHXAbzaGrB
3RPrpVKtwwycLHpCsEoQiTVDSglNiXypbjgzorXlv9Mb/ZlqN8nvMavntbJ7IVSA
2elOiQcQeEq6ofQQbJkf6RVzbJA+bUbAomthbK5QoLi/CKiaLy0AEc78ZFFmVUAZ
mLHmxW7Z3PsQrXCDX56TrHulUfbmPMmbpmrEb1JW1dJgnNry8lL5xjUUj8cZemS6
oLL+EIWLkPiNEknonas3qVpj5yylJYuyF318ZY5iPdKLy7J5DW4Id6ILuyFxQej9
u2LAbpSZcbup88CVq/zM4AikvFb4ibF0MOwbMXdZVAwFGnGr6wKLe3rQZOBepbVG
3gHekfhTe+7fnea/qdl91wpm4L92UJHoinLFX8A9cQOmz3LjxzF+XZXS5PN2qdiT
SyewiNizeC91VvH23SIpC4ezxqlX+LtoTh1n821di3+2EperYDBL6wfzpXe3DA8a
nPK5cX1j9AIOEMHs9o+PBPPTChPfTDa6oxcE567nLW0n1uYj83qvazXXuvZB/YbZ
+i+Z0Ex0/IB7ZWOETqmhFXAykV0M6to4SqN4yMtkcxRebihkz6FOFFAxgx4+W3EM
c+XK+FKJfolhRHl7Yagh
=1XE8
-----END PGP SIGNATURE-----
 
A

Antoon Pardon

Op 29-07-13 01:41, (e-mail address removed) schreef:
How, using Python-3.3's email module, do I "flatten" (I think
that's the right term) a Message object to get utf-8 encoded
body with the headers:
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
when the message payload was set to a python (unicode) string?

I am just trying out some things for my self on python 3.2 so
be sure to test this out but you could try the following.

msg.set_charset('utf-8')
msg['Content-Transfer-Encoding'] = '8bit'
 
R

rurpy

How, using Python-3.3's email module, do I "flatten" (I think
that's the right term) a Message object to get utf-8 encoded
body with the headers:
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
when the message payload was set to a python (unicode) string?

I asked about this a while back [1], but never got a response. My
current best-guess is here [2]. My fallback flattening works for
everything except the 8-bit encoded messages using the UTF-16 charset,
but it's pretty ugly.

Let me know if you figure out something cleaner :).

Cheers,
Trevor

[1]: http://thread.gmane.org/gmane.comp.python.general/725425
[2]: https://github.com/wking/rss2email/blob/master/rss2email/email.py#L226

Thanks, that was very helpful.

My code is just a quick utility tool for internal use so
I am able to be fairly hackish without shame. :)

Since I am synthesizing the mails from scratch and the
encoding requirements fairly simple, I could probably
dispense with the email/smtplib packages altogether and
just pipe my text directly to sendmail. But I thought
using Python's email package would be easier. Silly me.

Thanks again.
 
R

rurpy

Op 29-07-13 01:41, (e-mail address removed) schreef:
How, using Python-3.3's email module, do I "flatten" (I think
that's the right term) a Message object to get utf-8 encoded
body with the headers:
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
when the message payload was set to a python (unicode) string?

I am just trying out some things for my self on python 3.2 so
be sure to test this out but you could try the following.

msg.set_charset('utf-8')
msg['Content-Transfer-Encoding'] = '8bit'

You can do that but the problem occurs when you call
email.generator.flatten (or it is called on your behalf by
somthing like smtplib.send_message) with such a message.
flatten always assumes a 7bit encoding and uses the ascii
codec to encode the message resulting in a UnicodeEncode
exception when it hits an 8 bit character. So gymnastics
like W. Trevor King implemented are necessary.
 
A

Antoon Pardon

Op 01-08-13 17:20, (e-mail address removed) schreef:
Op 29-07-13 01:41, (e-mail address removed) schreef:
How, using Python-3.3's email module, do I "flatten" (I think
that's the right term) a Message object to get utf-8 encoded
body with the headers:
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
when the message payload was set to a python (unicode) string?

I am just trying out some things for my self on python 3.2 so
be sure to test this out but you could try the following.

msg.set_charset('utf-8')
msg['Content-Transfer-Encoding'] = '8bit'

You can do that but the problem occurs when you call
email.generator.flatten (or it is called on your behalf by
somthing like smtplib.send_message) with such a message.
flatten always assumes a 7bit encoding and uses the ascii
codec to encode the message resulting in a UnicodeEncode
exception when it hits an 8 bit character. So gymnastics
like W. Trevor King implemented are necessary.

Well this works for me. I had a little look in the code
and it seems buggy to me, at least the 3.2 version is.
There is a _encode but (1) The bytes generator version
is defined to allways use us-ascii as encoding and (2)
I couldn't find it actually being called on a mesg part.

------------------------------------------------------------

import smtplib

from email.mime.text import MIMEText

txt = '''\
Het adres is

Fréderic Boëven
Frère Orbanstraat 17
'''

recipient = "..."
sender = "..."

msg = MIMEText(txt)
msg.set_charset("utf-8")

msg['Subject'] = 'Python email tets'
msg['From'] = sender
msg['To'] = recipient

s = smtplib.SMTP('localhost')
s.sendmail(sender, [recipient], msg.as_string().encode("utf-8"))
s.quit()
 
A

Antoon Pardon

Op 01-08-13 17:20, (e-mail address removed) schreef:
Op 29-07-13 01:41, (e-mail address removed) schreef:
How, using Python-3.3's email module, do I "flatten" (I think
that's the right term) a Message object to get utf-8 encoded
body with the headers:
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
when the message payload was set to a python (unicode) string?

I am just trying out some things for my self on python 3.2 so
be sure to test this out but you could try the following.

msg.set_charset('utf-8')
msg['Content-Transfer-Encoding'] = '8bit'

You can do that but the problem occurs when you call
email.generator.flatten (or it is called on your behalf by
somthing like smtplib.send_message) with such a message.
flatten always assumes a 7bit encoding and uses the ascii
codec to encode the message resulting in a UnicodeEncode
exception when it hits an 8 bit character. So gymnastics
like W. Trevor King implemented are necessary.

This works too, but I don't know how usefull it is with
multipart messages.

import smtplib
import os
import io

from email.mime.text import MIMEText
from email.generator import BytesGenerator

from email.generator import BytesGenerator

class EncodeGenerator(BytesGenerator):

def flatten(self, msg, unixfrom=False, linesep='\n'):
self._encoding = str(msg.get_charset())
super().flatten(msg, unixfrom, linesep)

def write(self, s):
self._fp.write(s.encode(self._encoding))

def _encode(self, s):
return s.encode(self._encoding)


txt = '''\
Het adres is

Fréderic Boëven
Frère Orbanstraat 17
'''

recipient = " ... "
sender = " ... "

msg = MIMEText(txt)
msg.set_charset("utf-8")

msg['Subject'] = 'Python email test: %d' % os.getpid()
msg['From'] = sender
msg['To'] = recipient

print(msg['Subject'])

# Send the message via our own SMTP server.
s = smtplib.SMTP('localhost')

with io.BytesIO() as bytesmsg:
g = EncodeGenerator(bytesmsg)
g.flatten(msg, linesep='\r\n')
flat_msg = bytesmsg.getvalue()

print(flat_msg)
s.sendmail(sender, [recipient], flat_msg)
s.quit()
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top