27 __docformat__ = "restructuredtext en" |
27 __docformat__ = "restructuredtext en" |
28 |
28 |
29 from email import message, message_from_string |
29 from email import message, message_from_string |
30 from Cookie import SimpleCookie |
30 from Cookie import SimpleCookie |
31 from StringIO import StringIO |
31 from StringIO import StringIO |
32 from cgi import parse_header, parse_qsl |
32 from cgi import parse_header |
33 from pprint import pformat as _pformat |
33 from pprint import pformat as _pformat |
34 |
34 |
35 |
35 |
36 def pformat(obj): |
36 def pformat(obj): |
37 """pretty prints `obj` if possible""" |
37 """pretty prints `obj` if possible""" |
38 try: |
38 try: |
39 return _pformat(obj) |
39 return _pformat(obj) |
40 except Exception: |
40 except Exception: |
41 return u'<could not parse>' |
41 return u'<could not parse>' |
42 |
|
43 def qs2dict(qs): |
|
44 """transforms a query string into a regular python dict""" |
|
45 result = {} |
|
46 for key, value in parse_qsl(qs, True): |
|
47 result.setdefault(key, []).append(value) |
|
48 return result |
|
49 |
42 |
50 def normalize_header(header): |
43 def normalize_header(header): |
51 """returns a normalized header name |
44 """returns a normalized header name |
52 |
45 |
53 >>> normalize_header('User_Agent') |
46 >>> normalize_header('User_Agent') |
68 buf = fsrc.read(min(length, size)) |
61 buf = fsrc.read(min(length, size)) |
69 if not buf: |
62 if not buf: |
70 break |
63 break |
71 fdst.write(buf) |
64 fdst.write(buf) |
72 size -= len(buf) |
65 size -= len(buf) |
73 |
|
74 def parse_file_upload(header_dict, post_data): |
|
75 """This is adapted FROM DJANGO""" |
|
76 raw_message = '\r\n'.join('%s:%s' % pair for pair in header_dict.iteritems()) |
|
77 raw_message += '\r\n\r\n' + post_data |
|
78 msg = message_from_string(raw_message) |
|
79 post, files = {}, {} |
|
80 for submessage in msg.get_payload(): |
|
81 name_dict = parse_header(submessage['Content-Disposition'])[1] |
|
82 key = name_dict['name'] |
|
83 # name_dict is something like {'name': 'file', 'filename': 'test.txt'} for file uploads |
|
84 # or {'name': 'blah'} for POST fields |
|
85 # We assume all uploaded files have a 'filename' set. |
|
86 if 'filename' in name_dict: |
|
87 assert type([]) != type(submessage.get_payload()), "Nested MIME messages are not supported" |
|
88 if not name_dict['filename'].strip(): |
|
89 continue |
|
90 # IE submits the full path, so trim everything but the basename. |
|
91 # (We can't use os.path.basename because that uses the server's |
|
92 # directory separator, which may not be the same as the |
|
93 # client's one.) |
|
94 filename = name_dict['filename'][name_dict['filename'].rfind("\\")+1:] |
|
95 mimetype = 'Content-Type' in submessage and submessage['Content-Type'] or None |
|
96 content = StringIO(submessage.get_payload()) |
|
97 files[key] = [filename, mimetype, content] |
|
98 else: |
|
99 post.setdefault(key, []).append(submessage.get_payload()) |
|
100 return post, files |
|