blob: 6851094e9bd73f2cd9103ecbcbcd51c7cebdc245 [file] [log] [blame]
Barry Warsaw61e56162004-05-13 22:50:12 +00001# Copyright (C) 2001-2004 Python Software Foundation
2# Author: barry@python.org (Barry Warsaw)
Barry Warsawba925802001-09-23 03:17:28 +00003
Barry Warsaw61e56162004-05-13 22:50:12 +00004"""Encodings and related functions."""
Barry Warsawba925802001-09-23 03:17:28 +00005
6import base64
Barry Warsawba925802001-09-23 03:17:28 +00007
8
Barry Warsawe968ead2001-10-04 17:05:11 +00009
Barry Warsawba925802001-09-23 03:17:28 +000010# Helpers
Barry Warsaw8c1aac22002-05-19 23:44:19 +000011try:
12 from quopri import encodestring as _encodestring
13
14 def _qencode(s):
15 enc = _encodestring(s, quotetabs=1)
16 # Must encode spaces, which quopri.encodestring() doesn't do
17 return enc.replace(' ', '=20')
18except ImportError:
19 # Python 2.1 doesn't have quopri.encodestring()
20 from cStringIO import StringIO
21 import quopri as _quopri
22
23 def _qencode(s):
24 if not s:
25 return s
26 hasnewline = (s[-1] == '\n')
27 infp = StringIO(s)
28 outfp = StringIO()
29 _quopri.encode(infp, outfp, quotetabs=1)
30 # Python 2.x's encode() doesn't encode spaces even when quotetabs==1
31 value = outfp.getvalue().replace(' ', '=20')
32 if not hasnewline and value[-1] == '\n':
33 return value[:-1]
34 return value
Barry Warsawba925802001-09-23 03:17:28 +000035
Barry Warsaw6f70c412001-09-26 05:26:22 +000036
Barry Warsawba925802001-09-23 03:17:28 +000037def _bencode(s):
38 # We can't quite use base64.encodestring() since it tacks on a "courtesy
39 # newline". Blech!
40 if not s:
41 return s
42 hasnewline = (s[-1] == '\n')
43 value = base64.encodestring(s)
44 if not hasnewline and value[-1] == '\n':
45 return value[:-1]
46 return value
47
48
Barry Warsawe968ead2001-10-04 17:05:11 +000049
Barry Warsawba925802001-09-23 03:17:28 +000050def encode_base64(msg):
51 """Encode the message's payload in Base64.
52
Barry Warsaw12272a22002-10-01 00:05:24 +000053 Also, add an appropriate Content-Transfer-Encoding header.
Barry Warsawba925802001-09-23 03:17:28 +000054 """
55 orig = msg.get_payload()
56 encdata = _bencode(orig)
57 msg.set_payload(encdata)
58 msg['Content-Transfer-Encoding'] = 'base64'
59
60
Barry Warsawe968ead2001-10-04 17:05:11 +000061
Barry Warsawba925802001-09-23 03:17:28 +000062def encode_quopri(msg):
Barry Warsaw12272a22002-10-01 00:05:24 +000063 """Encode the message's payload in quoted-printable.
Barry Warsawba925802001-09-23 03:17:28 +000064
Barry Warsaw12272a22002-10-01 00:05:24 +000065 Also, add an appropriate Content-Transfer-Encoding header.
Barry Warsawba925802001-09-23 03:17:28 +000066 """
67 orig = msg.get_payload()
68 encdata = _qencode(orig)
69 msg.set_payload(encdata)
70 msg['Content-Transfer-Encoding'] = 'quoted-printable'
71
72
Barry Warsawe968ead2001-10-04 17:05:11 +000073
Barry Warsawba925802001-09-23 03:17:28 +000074def encode_7or8bit(msg):
Barry Warsaw12272a22002-10-01 00:05:24 +000075 """Set the Content-Transfer-Encoding header to 7bit or 8bit."""
Barry Warsawba925802001-09-23 03:17:28 +000076 orig = msg.get_payload()
Barry Warsaw409a4c02002-04-10 21:01:31 +000077 if orig is None:
78 # There's no payload. For backwards compatibility we use 7bit
79 msg['Content-Transfer-Encoding'] = '7bit'
80 return
Barry Warsawba925802001-09-23 03:17:28 +000081 # We play a trick to make this go fast. If encoding to ASCII succeeds, we
82 # know the data must be 7bit, otherwise treat it as 8bit.
83 try:
84 orig.encode('ascii')
85 except UnicodeError:
Barry Warsaw61e56162004-05-13 22:50:12 +000086 # iso-2022-* is non-ASCII but still 7-bit
87 charset = msg.get_charset()
88 output_cset = charset and charset.output_charset
89 if output_cset and output_cset.lower().startswith('iso-2202-'):
90 msg['Content-Transfer-Encoding'] = '7bit'
91 else:
92 msg['Content-Transfer-Encoding'] = '8bit'
Barry Warsawba925802001-09-23 03:17:28 +000093 else:
94 msg['Content-Transfer-Encoding'] = '7bit'
95
96
Barry Warsawe968ead2001-10-04 17:05:11 +000097
Barry Warsawba925802001-09-23 03:17:28 +000098def encode_noop(msg):
99 """Do nothing."""