Mercurial > hg > simpypi
annotate tests/multipart.py @ 63:af1476a936fc
add a multipart processor so we can post damn files
author | Jeff Hammel <jhammel@mozilla.com> |
---|---|
date | Thu, 01 Mar 2012 16:57:00 -0800 |
parents | |
children | bb8d993376aa |
rev | line source |
---|---|
63
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
1 """ |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
2 from |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
3 http://www.doughellmann.com/PyMOTW/urllib2/#uploading-files |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
4 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
5 Very very sad that python2 stdlib doesn't have this |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
6 """ |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
7 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
8 import itertools |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
9 import mimetools |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
10 import mimetypes |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
11 from cStringIO import StringIO |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
12 import urllib |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
13 import urllib2 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
14 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
15 class MultiPartForm(object): |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
16 """Accumulate the data to be used when posting a form.""" |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
17 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
18 def __init__(self): |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
19 self.form_fields = [] |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
20 self.files = [] |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
21 self.boundary = mimetools.choose_boundary() |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
22 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
23 def get_content_type(self): |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
24 return 'multipart/form-data; boundary=%s' % self.boundary |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
25 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
26 def add_field(self, name, value): |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
27 """Add a simple field to the form data.""" |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
28 self.form_fields.append((name, value)) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
29 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
30 def add_file(self, fieldname, filename, fileHandle, mimetype=None): |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
31 """Add a file to be uploaded.""" |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
32 body = fileHandle.read() |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
33 if mimetype is None: |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
34 mimetype = mimetypes.guess_type(filename)[0] or 'application/octet-stream' |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
35 self.files.append((fieldname, filename, mimetype, body)) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
36 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
37 def post(self, url): |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
38 request = urllib2.Request(url) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
39 body = str(self) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
40 request.add_header('Content-type', self.get_content_type()) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
41 request.add_header('Content-length', len(body)) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
42 request.add_data(body) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
43 return urllib2.urlopen(request) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
44 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
45 def __str__(self): |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
46 """Return a string representing the form data, including attached files.""" |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
47 # Build a list of lists, each containing "lines" of the |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
48 # request. Each part is separated by a boundary string. |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
49 # Once the list is built, return a string where each |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
50 # line is separated by '\r\n'. |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
51 parts = [] |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
52 part_boundary = '--' + self.boundary |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
53 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
54 # Add the form fields |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
55 parts.extend( |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
56 [ part_boundary, |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
57 'Content-Disposition: form-data; name="%s"' % name, |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
58 '', |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
59 value, |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
60 ] |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
61 for name, value in self.form_fields |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
62 ) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
63 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
64 # Add the files to upload |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
65 parts.extend( |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
66 [ part_boundary, |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
67 'Content-Disposition: file; name="%s"; filename="%s"' % \ |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
68 (field_name, filename), |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
69 'Content-Type: %s' % content_type, |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
70 '', |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
71 body, |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
72 ] |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
73 for field_name, filename, content_type, body in self.files |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
74 ) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
75 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
76 # Flatten the list and add closing boundary marker, |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
77 # then return CR+LF separated data |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
78 flattened = list(itertools.chain(*parts)) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
79 flattened.append('--' + self.boundary + '--') |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
80 flattened.append('') |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
81 return '\r\n'.join(flattened) |