| 1 | #! /usr/bin/env python
|
|---|
| 2 |
|
|---|
| 3 | """Conversions to/from quoted-printable transport encoding as per RFC 1521."""
|
|---|
| 4 |
|
|---|
| 5 | # (Dec 1991 version).
|
|---|
| 6 |
|
|---|
| 7 | __all__ = ["encode", "decode", "encodestring", "decodestring"]
|
|---|
| 8 |
|
|---|
| 9 | ESCAPE = '='
|
|---|
| 10 | MAXLINESIZE = 76
|
|---|
| 11 | HEX = '0123456789ABCDEF'
|
|---|
| 12 | EMPTYSTRING = ''
|
|---|
| 13 |
|
|---|
| 14 | try:
|
|---|
| 15 | from binascii import a2b_qp, b2a_qp
|
|---|
| 16 | except ImportError:
|
|---|
| 17 | a2b_qp = None
|
|---|
| 18 | b2a_qp = None
|
|---|
| 19 |
|
|---|
| 20 |
|
|---|
| 21 | def needsquoting(c, quotetabs, header):
|
|---|
| 22 | """Decide whether a particular character needs to be quoted.
|
|---|
| 23 |
|
|---|
| 24 | The 'quotetabs' flag indicates whether embedded tabs and spaces should be
|
|---|
| 25 | quoted. Note that line-ending tabs and spaces are always encoded, as per
|
|---|
| 26 | RFC 1521.
|
|---|
| 27 | """
|
|---|
| 28 | if c in ' \t':
|
|---|
| 29 | return quotetabs
|
|---|
| 30 | # if header, we have to escape _ because _ is used to escape space
|
|---|
| 31 | if c == '_':
|
|---|
| 32 | return header
|
|---|
| 33 | return c == ESCAPE or not (' ' <= c <= '~')
|
|---|
| 34 |
|
|---|
| 35 | def quote(c):
|
|---|
| 36 | """Quote a single character."""
|
|---|
| 37 | i = ord(c)
|
|---|
| 38 | return ESCAPE + HEX[i//16] + HEX[i%16]
|
|---|
| 39 |
|
|---|
| 40 |
|
|---|
| 41 |
|
|---|
| 42 | def encode(input, output, quotetabs, header = 0):
|
|---|
| 43 | """Read 'input', apply quoted-printable encoding, and write to 'output'.
|
|---|
| 44 |
|
|---|
| 45 | 'input' and 'output' are files with readline() and write() methods.
|
|---|
| 46 | The 'quotetabs' flag indicates whether embedded tabs and spaces should be
|
|---|
| 47 | quoted. Note that line-ending tabs and spaces are always encoded, as per
|
|---|
| 48 | RFC 1521.
|
|---|
| 49 | The 'header' flag indicates whether we are encoding spaces as _ as per
|
|---|
| 50 | RFC 1522.
|
|---|
| 51 | """
|
|---|
| 52 |
|
|---|
| 53 | if b2a_qp is not None:
|
|---|
| 54 | data = input.read()
|
|---|
| 55 | odata = b2a_qp(data, quotetabs = quotetabs, header = header)
|
|---|
| 56 | output.write(odata)
|
|---|
| 57 | return
|
|---|
| 58 |
|
|---|
| 59 | def write(s, output=output, lineEnd='\n'):
|
|---|
| 60 | # RFC 1521 requires that the line ending in a space or tab must have
|
|---|
| 61 | # that trailing character encoded.
|
|---|
| 62 | if s and s[-1:] in ' \t':
|
|---|
| 63 | output.write(s[:-1] + quote(s[-1]) + lineEnd)
|
|---|
| 64 | elif s == '.':
|
|---|
| 65 | output.write(quote(s) + lineEnd)
|
|---|
| 66 | else:
|
|---|
| 67 | output.write(s + lineEnd)
|
|---|
| 68 |
|
|---|
| 69 | prevline = None
|
|---|
| 70 | while 1:
|
|---|
| 71 | line = input.readline()
|
|---|
|
|---|