3
"""Conversions to/from quoted-printable transport encoding as per RFC-1521."""
7
__all__ = ["encode","decode"]
11
HEX = '0123456789ABCDEF'
13
def needsquoting(c, quotetabs):
14
"""Decide whether a particular character needs to be quoted.
16
The 'quotetabs' flag indicates whether tabs should be quoted."""
19
return c == ESCAPE or not(' ' <= c <= '~')
22
"""Quote a single character."""
24
return ESCAPE + HEX[i/16] + HEX[i%16]
26
def encode(input, output, quotetabs):
27
"""Read 'input', apply quoted-printable encoding, and write to 'output'.
29
'input' and 'output' are files with readline() and write() methods.
30
The 'quotetabs' flag indicates whether tabs should be quoted.
33
line = input.readline()
44
if needsquoting(c, quotetabs):
46
if len(new) + len(c) >= MAXLINESIZE:
47
output.write(new + ESCAPE + '\n')
51
if prev in (' ', '\t'):
52
output.write(new + ESCAPE + '\n\n')
54
output.write(new + '\n')
56
def decode(input, output):
57
"""Read 'input', apply quoted-printable decoding, and write to 'output'.
59
'input' and 'output' are files with readline() and write() methods."""
62
line = input.readline()
65
if n > 0 and line[n-1] == '\n':
67
# Strip trailing whitespace
68
while n > 0 and line[n-1] in " \t\r":
75
new = new + c; i = i+1
76
elif i+1 == n and not partial:
78
elif i+1 < n and line[i+1] == ESCAPE:
79
new = new + ESCAPE; i = i+2
80
elif i+2 < n and ishex(line[i+1]) and ishex(line[i+2]):
81
new = new + chr(unhex(line[i+1:i+3])); i = i+3
82
else: # Bad escape sequence -- leave it in
83
new = new + c; i = i+1
85
output.write(new + '\n')
91
"""Return true if the character 'c' is a hexadecimal digit."""
92
return '0' <= c <= '9' or 'a' <= c <= 'f' or 'A' <= c <= 'F'
95
"""Get the integer value of a hexadecimal number."""
100
elif 'a' <= c <= 'f':
102
elif 'A' <= c <= 'F':
106
bits = bits*16 + (ord(c) - i)
113
opts, args = getopt.getopt(sys.argv[1:], 'td')
114
except getopt.error, msg:
115
sys.stdout = sys.stderr
117
print "usage: quopri [-t | -d] [file] ..."
118
print "-t: quote tabs"
119
print "-d: decode; default encode"
124
if o == '-t': tabs = 1
125
if o == '-d': deco = 1
127
sys.stdout = sys.stderr
128
print "-t and -d are mutually exclusive"
130
if not args: args = ['-']
139
sys.stderr.write("%s: can't open (%s)\n" % (file, msg))
143
decode(fp, sys.stdout)
145
encode(fp, sys.stdout, tabs)
146
if fp is not sys.stdin:
151
if __name__ == '__main__':