ยปCore Development>Code coverage>Lib/MimeWriter.py

Python code coverage for Lib/MimeWriter.py

#countcontent
1n/a"""Generic MIME writer.
2n/a
3n/aThis module defines the class MimeWriter. The MimeWriter class implements
4n/aa basic formatter for creating MIME multi-part files. It doesn't seek around
5n/athe output file nor does it use large amounts of buffer space. You must write
6n/athe parts out in the order that they should occur in the final file.
7n/aMimeWriter does buffer the headers you add, allowing you to rearrange their
8n/aorder.
9n/a
101"""
11n/a
12n/a
131import mimetools
14n/a
151__all__ = ["MimeWriter"]
16n/a
171import warnings
18n/a
191warnings.warn("the MimeWriter module is deprecated; use the email package instead",
201 DeprecationWarning, 2)
21n/a
222class MimeWriter:
23n/a
24n/a """Generic MIME writer.
25n/a
26n/a Methods:
27n/a
28n/a __init__()
29n/a addheader()
30n/a flushheaders()
31n/a startbody()
32n/a startmultipartbody()
33n/a nextpart()
34n/a lastpart()
35n/a
36n/a A MIME writer is much more primitive than a MIME parser. It
37n/a doesn't seek around on the output file, and it doesn't use large
38n/a amounts of buffer space, so you have to write the parts in the
39n/a order they should occur on the output file. It does buffer the
40n/a headers you add, allowing you to rearrange their order.
41n/a
42n/a General usage is:
43n/a
44n/a f = <open the output file>
45n/a w = MimeWriter(f)
46n/a ...call w.addheader(key, value) 0 or more times...
47n/a
48n/a followed by either:
49n/a
50n/a f = w.startbody(content_type)
51n/a ...call f.write(data) for body data...
52n/a
53n/a or:
54n/a
55n/a w.startmultipartbody(subtype)
56n/a for each part:
57n/a subwriter = w.nextpart()
58n/a ...use the subwriter's methods to create the subpart...
59n/a w.lastpart()
60n/a
61n/a The subwriter is another MimeWriter instance, and should be
62n/a treated in the same way as the toplevel MimeWriter. This way,
63n/a writing recursive body parts is easy.
64n/a
65n/a Warning: don't forget to call lastpart()!
66n/a
67n/a XXX There should be more state so calls made in the wrong order
68n/a are detected.
69n/a
70n/a Some special cases:
71n/a
72n/a - startbody() just returns the file passed to the constructor;
73n/a but don't use this knowledge, as it may be changed.
74n/a
75n/a - startmultipartbody() actually returns a file as well;
76n/a this can be used to write the initial 'if you can read this your
77n/a mailer is not MIME-aware' message.
78n/a
79n/a - If you call flushheaders(), the headers accumulated so far are
80n/a written out (and forgotten); this is useful if you don't need a
81n/a body part at all, e.g. for a subpart of type message/rfc822
82n/a that's (mis)used to store some header-like information.
83n/a
84n/a - Passing a keyword argument 'prefix=<flag>' to addheader(),
85n/a start*body() affects where the header is inserted; 0 means
86n/a append at the end, 1 means insert at the start; default is
87n/a append for addheader(), but insert for start*body(), which use
88n/a it to determine where the Content-Type header goes.
89n/a
901 """
91n/a
921 def __init__(self, fp):
9311 self._fp = fp
9411 self._headers = []
95n/a
961 def addheader(self, key, value, prefix=0):
97n/a """Add a header line to the MIME message.
98n/a
99n/a The key is the name of the header, where the value obviously provides
100n/a the value of the header. The optional argument prefix determines
101n/a where the header is inserted; 0 means append at the end, 1 means
102n/a insert at the start. The default is to append.
103n/a
104n/a """
10538 lines = value.split("\n")
10638 while lines and not lines[-1]: del lines[-1]
10738 while lines and not lines[0]: del lines[0]
10845 for i in range(1, len(lines)):
1097 lines[i] = " " + lines[i].strip()
11038 value = "\n".join(lines) + "\n"
11138 line = key + ": " + value
11238 if prefix:
1139 self._headers.insert(0, line)
114n/a else:
11529 self._headers.append(line)
116n/a
1171 def flushheaders(self):
118n/a """Writes out and forgets all headers accumulated so far.
119n/a
120n/a This is useful if you don't need a body part at all; for example,
121n/a for a subpart of type message/rfc822 that's (mis)used to store some
122n/a header-like information.
123n/a
124n/a """
12511 self._fp.writelines(self._headers)
12611 self._headers = []
127n/a
1281 def startbody(self, ctype, plist=[], prefix=1):
129n/a """Returns a file-like object for writing the body of the message.
130n/a
131n/a The content-type is set to the provided ctype, and the optional
132n/a parameter, plist, provides additional parameters for the
133n/a content-type declaration. The optional argument prefix determines
134n/a where the header is inserted; 0 means append at the end, 1 means
135n/a insert at the start. The default is to insert at the start.
136n/a
137n/a """
13817 for name, value in plist:
1397 ctype = ctype + ';\n %s=\"%s\"' % (name, value)
14010 self.addheader("Content-Type", ctype, prefix=prefix)
14110 self.flushheaders()
14210 self._fp.write("\n")
14310 return self._fp
144n/a
1451 def startmultipartbody(self, subtype, boundary=None, plist=[], prefix=1):
146n/a """Returns a file-like object for writing the body of the message.
147n/a
148n/a Additionally, this method initializes the multi-part code, where the
149n/a subtype parameter provides the multipart subtype, the boundary
150n/a parameter may provide a user-defined boundary specification, and the
151n/a plist parameter provides optional parameters for the subtype. The
152n/a optional argument, prefix, determines where the header is inserted;
153n/a 0 means append at the end, 1 means insert at the start. The default
154n/a is to insert at the start. Subparts should be created using the
155n/a nextpart() method.
156n/a
157n/a """
1584 self._boundary = boundary or mimetools.choose_boundary()
1594 return self.startbody("multipart/" + subtype,
1604 [("boundary", self._boundary)] + plist,
1614 prefix=prefix)
162n/a
1631 def nextpart(self):
164n/a """Returns a new instance of MimeWriter which represents an
165n/a individual part in a multipart message.
166n/a
167n/a This may be used to write the part as well as used for creating
168n/a recursively complex multipart messages. The message must first be
169n/a initialized with the startmultipartbody() method before using the
170n/a nextpart() method.
171n/a
172n/a """
1738 self._fp.write("\n--" + self._boundary + "\n")
1748 return self.__class__(self._fp)
175n/a
1761 def lastpart(self):
177n/a """This is used to designate the last part of a multipart message.
178n/a
179n/a It should always be used when writing multipart messages.
180n/a
181n/a """
1824 self._fp.write("\n--" + self._boundary + "--\n")
183n/a
184n/a
1851if __name__ == '__main__':
1860 import test.test_MimeWriter