Statistics
| Revision:

root / tags / v1_0_2_Build_910 / extensions / extScripting / scripts / jython / Lib / quopri.py @ 11275

History | View | Annotate | Download (4.17 KB)

1 5782 jmvivo
#! /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"]
8
9
ESCAPE = '='
10
MAXLINESIZE = 76
11
HEX = '0123456789ABCDEF'
12
13
def needsquoting(c, quotetabs):
14
    """Decide whether a particular character needs to be quoted.
15

16
    The 'quotetabs' flag indicates whether tabs should be quoted."""
17
    if c == '\t':
18
        return not quotetabs
19
    return c == ESCAPE or not(' ' <= c <= '~')
20
21
def quote(c):
22
    """Quote a single character."""
23
    i = ord(c)
24
    return ESCAPE + HEX[i/16] + HEX[i%16]
25
26
def encode(input, output, quotetabs):
27
    """Read 'input', apply quoted-printable encoding, and write to 'output'.
28

29
    'input' and 'output' are files with readline() and write() methods.
30
    The 'quotetabs' flag indicates whether tabs should be quoted.
31
        """
32
    while 1:
33
        line = input.readline()
34
        if not line:
35
            break
36
        new = ''
37
        last = line[-1:]
38
        if last == '\n':
39
            line = line[:-1]
40
        else:
41
            last = ''
42
        prev = ''
43
        for c in line:
44
            if needsquoting(c, quotetabs):
45
                c = quote(c)
46
            if len(new) + len(c) >= MAXLINESIZE:
47
                output.write(new + ESCAPE + '\n')
48
                new = ''
49
            new = new + c
50
            prev = c
51
        if prev in (' ', '\t'):
52
            output.write(new + ESCAPE + '\n\n')
53
        else:
54
            output.write(new + '\n')
55
56
def decode(input, output):
57
    """Read 'input', apply quoted-printable decoding, and write to 'output'.
58

59
    'input' and 'output' are files with readline() and write() methods."""
60
    new = ''
61
    while 1:
62
        line = input.readline()
63
        if not line: break
64
        i, n = 0, len(line)
65
        if n > 0 and line[n-1] == '\n':
66
            partial = 0; n = n-1
67
            # Strip trailing whitespace
68
            while n > 0 and line[n-1] in " \t\r":
69
                n = n-1
70
        else:
71
            partial = 1
72
        while i < n:
73
            c = line[i]
74
            if c != ESCAPE:
75
                new = new + c; i = i+1
76
            elif i+1 == n and not partial:
77
                partial = 1; break
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
84
        if not partial:
85
            output.write(new + '\n')
86
            new = ''
87
    if new:
88
        output.write(new)
89
90
def ishex(c):
91
    """Return true if the character 'c' is a hexadecimal digit."""
92
    return '0' <= c <= '9' or 'a' <= c <= 'f' or 'A' <= c <= 'F'
93
94
def unhex(s):
95
    """Get the integer value of a hexadecimal number."""
96
    bits = 0
97
    for c in s:
98
        if '0' <= c <= '9':
99
            i = ord('0')
100
        elif 'a' <= c <= 'f':
101
            i = ord('a')-10
102
        elif 'A' <= c <= 'F':
103
            i = ord('A')-10
104
        else:
105
            break
106
        bits = bits*16 + (ord(c) - i)
107
    return bits
108
109
def test():
110
    import sys
111
    import getopt
112
    try:
113
        opts, args = getopt.getopt(sys.argv[1:], 'td')
114
    except getopt.error, msg:
115
        sys.stdout = sys.stderr
116
        print msg
117
        print "usage: quopri [-t | -d] [file] ..."
118
        print "-t: quote tabs"
119
        print "-d: decode; default encode"
120
        sys.exit(2)
121
    deco = 0
122
    tabs = 0
123
    for o, a in opts:
124
        if o == '-t': tabs = 1
125
        if o == '-d': deco = 1
126
    if tabs and deco:
127
        sys.stdout = sys.stderr
128
        print "-t and -d are mutually exclusive"
129
        sys.exit(2)
130
    if not args: args = ['-']
131
    sts = 0
132
    for file in args:
133
        if file == '-':
134
            fp = sys.stdin
135
        else:
136
            try:
137
                fp = open(file)
138
            except IOError, msg:
139
                sys.stderr.write("%s: can't open (%s)\n" % (file, msg))
140
                sts = 1
141
                continue
142
        if deco:
143
            decode(fp, sys.stdout)
144
        else:
145
            encode(fp, sys.stdout, tabs)
146
        if fp is not sys.stdin:
147
            fp.close()
148
    if sts:
149
        sys.exit(sts)
150
151
if __name__ == '__main__':
152
    test()