From nicholas.cole at gmail.com Wed Sep 24 16:37:53 2008 From: nicholas.cole at gmail.com (Nicholas Cole) Date: Wed, 24 Sep 2008 15:37:53 +0100 Subject: [Email-SIG] Creating message parts Message-ID: Hi all, I may have the wrong end of the stick entirely, but I'll try to be as clear as possible. I'm trying to create a message part that will later be attached to another message. However, if I do E = email.mime.multipart.MIMEMultipart() print E.as_string() Then E is given a "MIME-Version: 1.0" header, which I don't think it should have (the "parent" email message will have that header, of course). I have a feeling, therefore, that I am doing something wrong! Should I not be using the MIMEMultipart() calss for this purpose? And if not, what should I be using? Best wishes, Nicholas From phd at phd.pp.ru Wed Sep 24 17:06:54 2008 From: phd at phd.pp.ru (Oleg Broytmann) Date: Wed, 24 Sep 2008 19:06:54 +0400 Subject: [Email-SIG] Creating message parts In-Reply-To: References: Message-ID: <20080924150654.GB16537@phd.pp.ru> On Wed, Sep 24, 2008 at 03:37:53PM +0100, Nicholas Cole wrote: > E = email.mime.multipart.MIMEMultipart() > print E.as_string() > > Then E is given a "MIME-Version: 1.0" header, which I don't think it > should have (the "parent" email message will have that header, of > course). > > I have a feeling, therefore, that I am doing something wrong! Should > I not be using the MIMEMultipart() calss for this purpose? And if not, > what should I be using? MIMEMultipart is a class for the top-level part (the entire message). For subparts use classes like MIMEText et al. Compare these 3 examples: ----- 1 ----- from email import MIMEText msg = MIMEText.MIMEText("This is a simple message", _charset="latin-1") msg["Subject"] = "Text" print str(msg) ----- /1 ----- ----- 2 ----- from email import MIMENonMultipart msg = MIMENonMultipart.MIMENonMultipart("text", "plain", charset="latin-1") msg["Subject"] = "Simple" msg.set_payload("This is a simple message") print str(msg) ----- /2 ----- ----- 3 ----- from email import MIMEMultipart, MIMEText msg = MIMEMultipart.MIMEMultipart() msg["Subject"] = "Multipart" part = MIMEText.MIMEText("This is a subpart", _charset="latin-1") part["Subject"] = "Subpart" msg.attach(part) print str(msg) ----- /3 ----- Oleg. -- Oleg Broytmann http://phd.pp.ru/ phd at phd.pp.ru Programmers don't die, they just GOSUB without RETURN. From mark at msapiro.net Wed Sep 24 17:13:55 2008 From: mark at msapiro.net (Mark Sapiro) Date: Wed, 24 Sep 2008 08:13:55 -0700 Subject: [Email-SIG] Creating message parts In-Reply-To: Message-ID: Nicholas Cole wrote: > >I'm trying to create a message part that will later be attached to >another message. However, if I do > >E = email.mime.multipart.MIMEMultipart() >print E.as_string() > >Then E is given a "MIME-Version: 1.0" header, which I don't think it >should have (the "parent" email message will have that header, of >course). > >I have a feeling, therefore, that I am doing something wrong! Should >I not be using the MIMEMultipart() calss for this purpose? And if not, >what should I be using? See . You should use classes like email.mime.application.MIMEApplication, email.mime.image.MIMEImage, email.mime.text.MIMEText, etc. to create the various message parts and then append them to the payload of the parent message. -- Mark Sapiro The highway is for gamblers, San Francisco Bay Area, California better use your sense - B. Dylan From nicholas.cole at gmail.com Wed Sep 24 17:46:01 2008 From: nicholas.cole at gmail.com (Nicholas Cole) Date: Wed, 24 Sep 2008 16:46:01 +0100 Subject: [Email-SIG] Creating message parts In-Reply-To: <20080924150654.GB16537@phd.pp.ru> References: <20080924150654.GB16537@phd.pp.ru> Message-ID: On Wed, Sep 24, 2008 at 4:06 PM, Oleg Broytmann wrote: > On Wed, Sep 24, 2008 at 03:37:53PM +0100, Nicholas Cole wrote: >> E = email.mime.multipart.MIMEMultipart() >> print E.as_string() >> >> Then E is given a "MIME-Version: 1.0" header, which I don't think it >> should have (the "parent" email message will have that header, of >> course). >> >> I have a feeling, therefore, that I am doing something wrong! Should >> I not be using the MIMEMultipart() calss for this purpose? And if not, >> what should I be using? > > MIMEMultipart is a class for the top-level part (the entire message). > For subparts use classes like MIMEText et al. Compare these 3 examples: > > ----- 3 ----- > from email import MIMEMultipart, MIMEText > msg = MIMEMultipart.MIMEMultipart() > msg["Subject"] = "Multipart" > > part = MIMEText.MIMEText("This is a subpart", _charset="latin-1") > part["Subject"] = "Subpart" > > msg.attach(part) > print str(msg) > ----- /3 ----- > > Oleg. Dear Oleg, Thanks for the examples - things are looking clearer. However, in version 3, on my system the subpart is still given a MIME-Version header. Is this not incorrect? Also, according to the documentation "A MIME-Version: header will also be added" to the MIMEMultipart class, even though it actually seems to be added by the MIMEBase class, and therefore to all subclasses. Best wishes, Nicholas From nicholas.cole at gmail.com Wed Sep 24 21:25:37 2008 From: nicholas.cole at gmail.com (Nicholas Cole) Date: Wed, 24 Sep 2008 20:25:37 +0100 Subject: [Email-SIG] Converting to quoted printable encoding Message-ID: My naive attempt to convert a MIMEText message part to quoted printable (having read the documentation) looked something like this: E = email.mime.text.MIMEText("This is some text") email.encoders.encode_quopri(E) print E.as_string() But it yields a message with two Content-Transfer-Encoding headers. I'm assuming that this is not a bug - but what is "The Right Way"(TM) to change the encoding of text? Best, N From phd at phd.pp.ru Wed Sep 24 21:37:46 2008 From: phd at phd.pp.ru (Oleg Broytmann) Date: Wed, 24 Sep 2008 23:37:46 +0400 Subject: [Email-SIG] Converting to quoted printable encoding In-Reply-To: References: Message-ID: <20080924193746.GB4518@phd.pp.ru> On Wed, Sep 24, 2008 at 08:25:37PM +0100, Nicholas Cole wrote: > but what is "The Right Way"(TM) > to change the encoding of text? Why not to allow email to choose the best suited encoding? Wel, you may change the idea of "best" by setting encoders for your charset; this is how I do it: Charset.add_charset("koi8-r", Charset.BASE64) If you want quted-printable for both headers and body, call Charset.add_charset("koi8-r", Charset.QP, Charset.QP) Oleg. -- Oleg Broytmann http://phd.pp.ru/ phd at phd.pp.ru Programmers don't die, they just GOSUB without RETURN. From nicholas.cole at gmail.com Wed Sep 24 21:46:18 2008 From: nicholas.cole at gmail.com (Nicholas Cole) Date: Wed, 24 Sep 2008 20:46:18 +0100 Subject: [Email-SIG] Converting to quoted printable encoding In-Reply-To: <20080924193746.GB4518@phd.pp.ru> References: <20080924193746.GB4518@phd.pp.ru> Message-ID: On Wed, Sep 24, 2008 at 8:37 PM, Oleg Broytmann wrote: > On Wed, Sep 24, 2008 at 08:25:37PM +0100, Nicholas Cole wrote: >> but what is "The Right Way"(TM) >> to change the encoding of text? > > Why not to allow email to choose the best suited encoding? Wel, you may > change the idea of "best" by setting encoders for your charset; this is how Because the RFC I am trying to follow specifies a particular encoding. ;-) From nicholas.cole at gmail.com Wed Sep 24 22:10:32 2008 From: nicholas.cole at gmail.com (Nicholas Cole) Date: Wed, 24 Sep 2008 21:10:32 +0100 Subject: [Email-SIG] Converting to quoted printable encoding In-Reply-To: References: Message-ID: On Wed, Sep 24, 2008 at 8:25 PM, Nicholas Cole wrote: > My naive attempt to convert a MIMEText message part to quoted > printable (having read the documentation) looked something like this: > > E = email.mime.text.MIMEText("This is some text") > email.encoders.encode_quopri(E) > print E.as_string() > > But it yields a message with two Content-Transfer-Encoding headers. > > I'm assuming that this is not a bug - but what is "The Right Way"(TM) > to change the encoding of text? I can't see that this isn't a bug - in that encode_quopri is (as the documentation says) adding a header, but not replacing the one that was there already. But I am confused. Doing this results in a truly mangled message, suggesting that encode_quopri is not as aware of existing encoding as I thought: E = email.mime.text.MIMEText("This is some text") email.encoders.encode_quopri(E) email.encoders.encode_quopri(E) So, it looks like I'm going to be better off using the quopri module directly... Best, N From mark at msapiro.net Thu Sep 25 22:30:28 2008 From: mark at msapiro.net (Mark Sapiro) Date: Thu, 25 Sep 2008 13:30:28 -0700 Subject: [Email-SIG] Converting to quoted printable encoding In-Reply-To: Message-ID: Nicholas Cole wrote: >On Wed, Sep 24, 2008 at 8:25 PM, Nicholas Cole wrote: >> My naive attempt to convert a MIMEText message part to quoted >> printable (having read the documentation) looked something like this: >> >> E = email.mime.text.MIMEText("This is some text") >> email.encoders.encode_quopri(E) >> print E.as_string() >> >> But it yields a message with two Content-Transfer-Encoding headers. We do E = email.mime.text.MIMEText("This is some text") del E.['content-transfer_encoding'] email.encoders.encode_quopri(E) >> I'm assuming that this is not a bug - but what is "The Right Way"(TM) >> to change the encoding of text? > >I can't see that this isn't a bug - in that encode_quopri is (as the >documentation says) adding a header, but not replacing the one that >was there already. > >But I am confused. Doing this results in a truly mangled message, >suggesting that encode_quopri is not as aware of existing encoding as >I thought: > >E = email.mime.text.MIMEText("This is some text") >email.encoders.encode_quopri(E) >email.encoders.encode_quopri(E) Yes, doubly encoding the payload will result in a payload that has to be doubly decoded. I suppose the ideal solution to all of this is that the encoder should first look at the existing Content-Transfer_Encoding header if any to see if the payload is already encoded, and if no header, encode and add the header; if existing header with target encoding, do nothing, and if existing header with other encoding, decode, encode and replace the header. However it doesn't work that way. >So, it looks like I'm going to be better off using the quopri module directly... Consider this email.Charset.add_charset('us-ascii', body_enc=email.Charset.QP) E = email.mime.text.MIMEText("This is some text") print E.as_string() -- Mark Sapiro The highway is for gamblers, San Francisco Bay Area, California better use your sense - B. Dylan From barry at python.org Fri Sep 26 22:53:57 2008 From: barry at python.org (Barry Warsaw) Date: Fri, 26 Sep 2008 16:53:57 -0400 Subject: [Email-SIG] Converting to quoted printable encoding In-Reply-To: References: Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Sep 25, 2008, at 4:30 PM, Mark Sapiro wrote: > I suppose the ideal solution to all of this is that the encoder should > first look at the existing Content-Transfer_Encoding header if any to > see if the payload is already encoded, and if no header, encode and > add the header; if existing header with target encoding, do nothing, > and if existing header with other encoding, decode, encode and replace > the header. However it doesn't work that way. I think there are lots of opportunities for cleaning up the email package API. I still believe there are fundamental semantic problems in the 3.0 version of the package, mostly due to the bytes/unicode split. I really wish I had had time to complete that work, but alas we never got around to it at Pycon. I'd like to jump start the discussion on a next version of the email package, one that plays better with Python 3.0 (but would still be Python 2.6 and possibly 2.5 compatible). We should probably begin by enumerating all the things we think are wrong with the current email package. Perhaps we could use the wiki on python.org for that. Thoughts? If you agree, I'll try to set some things up over there. - -Barry -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (Darwin) iQCVAwUBSN1L5XEjvBPtnXfVAQJCqAP/cSm6DfgxkZ0TaoMWdFW8/8WfcYqRAH1F NxvaklfRoy++Hz67HaoMExkWMfAJhg19QYv3WYnH/nofWUtWgB2r5IXXvg4Np3uJ bdmURV9bkzKhRbRTjzCoVPV6A/4Ftps1sSWC6NS48pDZSPqpyT3D8DtlulFy4bnz YjzdAeAJG10= =Sl+Y -----END PGP SIGNATURE-----