Mercurial > public > mercurial-scm > hg
comparison mercurial/mail.py @ 30089:040f23ed6963
mail: take --encoding and HGENCODING into account
Fall back to our encoding strategy for sending MIME text
that's neither ASCII nor UTF-8.
author | G?bor Stefanik <gabor.stefanik@nng.com> |
---|---|
date | Wed, 05 Oct 2016 13:45:22 +0200 |
parents | 87b8e40eb812 |
children | f6369544bf85 |
comparison
equal
deleted
inserted
replaced
30088:d1f5f158768e | 30089:040f23ed6963 |
---|---|
6 # GNU General Public License version 2 or any later version. | 6 # GNU General Public License version 2 or any later version. |
7 | 7 |
8 from __future__ import absolute_import, print_function | 8 from __future__ import absolute_import, print_function |
9 | 9 |
10 import email | 10 import email |
11 import email.charset | |
11 import email.header | 12 import email.header |
12 import os | 13 import os |
13 import quopri | 14 import quopri |
14 import smtplib | 15 import smtplib |
15 import socket | 16 import socket |
202 else: | 203 else: |
203 if not util.findexe(method): | 204 if not util.findexe(method): |
204 raise error.Abort(_('%r specified as email transport, ' | 205 raise error.Abort(_('%r specified as email transport, ' |
205 'but not in PATH') % method) | 206 'but not in PATH') % method) |
206 | 207 |
208 def codec2iana(cs): | |
209 '''''' | |
210 cs = email.charset.Charset(cs).input_charset.lower() | |
211 | |
212 # "latin1" normalizes to "iso8859-1", standard calls for "iso-8859-1" | |
213 if cs.startswith("iso") and not cs.startswith("iso-"): | |
214 return "iso-" + cs[3:] | |
215 return cs | |
216 | |
207 def mimetextpatch(s, subtype='plain', display=False): | 217 def mimetextpatch(s, subtype='plain', display=False): |
208 '''Return MIME message suitable for a patch. | 218 '''Return MIME message suitable for a patch. |
209 Charset will be detected as utf-8 or (possibly fake) us-ascii. | 219 Charset will be detected by first trying to decode as us-ascii, then utf-8, |
220 and finally the global encodings. If all those fail, fall back to | |
221 ISO-8859-1, an encoding with that allows all byte sequences. | |
210 Transfer encodings will be used if necessary.''' | 222 Transfer encodings will be used if necessary.''' |
211 | 223 |
212 cs = 'us-ascii' | 224 cs = ['us-ascii', 'utf-8', encoding.encoding, encoding.fallbackencoding] |
213 if not display: | 225 if display: |
214 try: | 226 return mimetextqp(s, subtype, 'us-ascii') |
215 s.decode('us-ascii') | 227 for charset in cs: |
228 try: | |
229 s.decode(charset) | |
230 return mimetextqp(s, subtype, codec2iana(charset)) | |
216 except UnicodeDecodeError: | 231 except UnicodeDecodeError: |
217 try: | 232 pass |
218 s.decode('utf-8') | 233 |
219 cs = 'utf-8' | 234 return mimetextqp(s, subtype, "iso-8859-1") |
220 except UnicodeDecodeError: | |
221 # We'll go with us-ascii as a fallback. | |
222 pass | |
223 | |
224 return mimetextqp(s, subtype, cs) | |
225 | 235 |
226 def mimetextqp(body, subtype, charset): | 236 def mimetextqp(body, subtype, charset): |
227 '''Return MIME message. | 237 '''Return MIME message. |
228 Quoted-printable transfer encoding will be used if necessary. | 238 Quoted-printable transfer encoding will be used if necessary. |
229 ''' | 239 ''' |