Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c75db0b

Browse files
committed
Added Mime writer module (formerly in Grail)
1 parent cfd8935 commit c75db0b

1 file changed

Lines changed: 131 additions & 0 deletions

File tree

Lib/MimeWriter.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
"""Generic MIME writer.
2+
3+
Classes:
4+
5+
MimeWriter - the only thing here.
6+
7+
"""
8+
9+
__version__ = '$Revision$'
10+
# $Source$
11+
12+
13+
import string
14+
import mimetools
15+
16+
17+
class MimeWriter:
18+
19+
"""Generic MIME writer.
20+
21+
Methods:
22+
23+
__init__()
24+
addheader()
25+
flushheaders()
26+
startbody()
27+
startmultipartbody()
28+
nextpart()
29+
lastpart()
30+
31+
A MIME writer is much more primitive than a MIME parser. It
32+
doesn't seek around on the output file, and it doesn't use large
33+
amounts of buffer space, so you have to write the parts in the
34+
order they should occur on the output file. It does buffer the
35+
headers you add, allowing you to rearrange their order.
36+
37+
General usage is:
38+
39+
f = <open the output file>
40+
w = MimeWriter(f)
41+
...call w.addheader(key, value) 0 or more times...
42+
43+
followed by either:
44+
45+
f = w.startbody(content_type)
46+
...call f.write(data) for body data...
47+
48+
or:
49+
50+
w.startmultipartbody(subtype)
51+
for each part:
52+
subwriter = w.nextpart()
53+
...use the subwriter's methods to create the subpart...
54+
w.lastpart()
55+
56+
The subwriter is another MimeWriter instance, and should be
57+
treated in the same way as the toplevel MimeWriter. This way,
58+
writing recursive body parts is easy.
59+
60+
Warning: don't forget to call lastpart()!
61+
62+
XXX There should be more state so calls made in the wrong order
63+
are detected.
64+
65+
Some special cases:
66+
67+
- startbody() just returns the file passed to the constructor;
68+
but don't use this knowledge, as it may be changed.
69+
70+
- startmultipartbody() actually returns a file as well;
71+
this can be used to write the initial 'if you can read this your
72+
mailer is not MIME-aware' message.
73+
74+
- If you call flushheaders(), the headers accumulated so far are
75+
written out (and forgotten); this is useful if you don't need a
76+
body part at all, e.g. for a subpart of type message/rfc822
77+
that's (mis)used to store some header-like information.
78+
79+
- Passing a keyword argument 'prefix=<flag>' to addheader(),
80+
start*body() affects where the header is inserted; 0 means
81+
append at the end, 1 means insert at the start; default is
82+
append for addheader(), but insert for start*body(), which use
83+
it to determine where the Content-Type header goes.
84+
85+
"""
86+
87+
def __init__(self, fp):
88+
self._fp = fp
89+
self._headers = []
90+
91+
def addheader(self, key, value, prefix=0):
92+
lines = string.splitfields(value, "\n")
93+
while lines and not lines[-1]: del lines[-1]
94+
while lines and not lines[0]: del lines[0]
95+
for i in range(1, len(lines)):
96+
lines[i] = " " + string.strip(lines[i])
97+
value = string.joinfields(lines, "\n") + "\n"
98+
line = key + ": " + value
99+
if prefix:
100+
self._headers.insert(0, line)
101+
else:
102+
self._headers.append(line)
103+
104+
def flushheaders(self):
105+
self._fp.writelines(self._headers)
106+
self._headers = []
107+
108+
def startbody(self, ctype, plist=[], prefix=1):
109+
for name, value in plist:
110+
ctype = ctype + ';\n %s=\"%s\"' % (name, value)
111+
self.addheader("Content-Type", ctype, prefix=prefix)
112+
self.flushheaders()
113+
self._fp.write("\n")
114+
return self._fp
115+
116+
def startmultipartbody(self, subtype, boundary=None, plist=[], prefix=1):
117+
self._boundary = boundary or mimetools.choose_boundary()
118+
return self.startbody("multipart/" + subtype,
119+
[("boundary", self._boundary)] + plist,
120+
prefix=prefix)
121+
122+
def nextpart(self):
123+
self._fp.write("\n--" + self._boundary + "\n")
124+
return self.__class__(self._fp)
125+
126+
def lastpart(self):
127+
self._fp.write("\n--" + self._boundary + "--\n")
128+
129+
130+
if __name__ == '__main__':
131+
print "To test the MimeWriter module, run TestMimeWriter.py."

0 commit comments

Comments
 (0)