MythTV  master
MultipartPostHandler.py
Go to the documentation of this file.
1 # From http://peerit.blogspot.com/2007/07/multipartposthandler-doesnt-work-for.html
2 
3 
18 """
19 Usage:
20  Enables the use of multipart/form-data for posting forms
21 
22 Inspirations:
23  Upload files in python:
24  http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306
25  urllib2_file:
26  Fabien Seisen: <fabien@seisen.org>
27 
28 Example:
29  import MultipartPostHandler, urllib2, cookielib
30 
31  cookies = cookielib.CookieJar()
32  opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies),
33  MultipartPostHandler.MultipartPostHandler)
34  params = { "username" : "bob", "password" : "riviera",
35  "file" : open("filename", "rb") }
36  opener.open("http://wwww.bobsite.com/upload/", params)
37 
38 Further Example:
39  The main function of this file is a sample which downloads a page and
40  then uploads it to the W3C validator.
41 """
42 from __future__ import print_function
43 
44 from future import standard_library
45 standard_library.install_aliases()
46 from builtins import object
47 from email.generator import _make_boundary
48 import mimetypes
49 import os, stat
50 import sys
51 from io import StringIO
52 
53 IS_PY2 = sys.version_info[0] == 2
54 
55 if IS_PY2:
56  from urllib2 import BaseHandler, build_opener, HTTPHandler
57 else:
58  from urllib.request import BaseHandler, build_opener, HTTPHandler
59 
60 if IS_PY2:
61  import urllib as ulib
62 else:
63  import urllib.parse as ulib
64 
65 
66 class Callable(object):
67  def __init__(self, anycallable):
68  self.__call__ = anycallable
69 
70 # Controls how sequences are uncoded. If true, elements may be given multiple values by
71 # assigning a sequence.
72 doseq = 1
73 
74 class MultipartPostHandler(BaseHandler):
75  handler_order = HTTPHandler.handler_order - 10 # needs to run first
76 
77  def http_request(self, request):
78  data = request.data
79  if data is not None and type(data) != str:
80  v_files = []
81  v_vars = []
82  try:
83  for(key, value) in list(data.items()):
84  # 'file' type doesn't exist in python3 and we didn't use it. Removed if:
85  v_vars.append((key, value))
86  except TypeError:
87  systype, value, traceback = sys.exc_info()
88  raise TypeError("not a valid non-string sequence or mapping object", traceback)
89 
90  if len(v_files) == 0:
91  data = ulib.urlencode(v_vars, doseq)
92  else:
93  boundary, data = self.multipart_encode(v_vars, v_files)
94 
95  contenttype = 'multipart/form-data; boundary=%s' % boundary
96  if(request.has_header('Content-Type')
97  and request.get_header('Content-Type').find('multipart/form-data') != 0):
98  print("Replacing %s with %s" % (request.get_header('content-type'), 'multipart/form-data'))
99  request.add_unredirected_header('Content-Type', contenttype)
100 
101  request.data = bytearray(data, 'latin1')
102 
103  return request
104 
105  def multipart_encode(self, these_vars, files, boundary = None, buf = None):
106  if boundary is None:
107  boundary = _make_boundary(os.getuid + os.getpid())
108  if buf is None:
109  buf = StringIO()
110  for(key, value) in these_vars:
111  buf.write('--%s\r\n' % boundary)
112  buf.write('Content-Disposition: form-data; name="%s"' % key)
113  buf.write('\r\n\r\n' + value + '\r\n')
114  for(key, fd) in files:
115  file_size = os.fstat(fd.fileno())[stat.ST_SIZE]
116  filename = fd.name.split('/')[-1]
117  contenttype = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
118  buf.write('--%s\r\n' % boundary)
119  buf.write('Content-Disposition: form-data; name="%s"; filename="%s"\r\n' % (key, filename))
120  buf.write('Content-Type: %s\r\n' % contenttype)
121  # buffer += 'Content-Length: %s\r\n' % file_size
122  fd.seek(0)
123  buf.write('\r\n' + fd.read() + '\r\n')
124  buf.write('--' + boundary + '--\r\n\r\n')
125  buf = buf.getvalue()
126  return boundary, buf
127  multipart_encode = Callable(multipart_encode)
128 
129  https_request = http_request
130 
131 def main():
132  import tempfile, sys
133 
134  validatorURL = "http://validator.w3.org/check"
135  opener = build_opener(MultipartPostHandler)
136 
137  def validateFile(url):
138  temp = tempfile.mkstemp(suffix=".html")
139  os.write(temp[0], opener.open(url).read())
140  params = { "ss" : "0", # show source
141  "doctype" : "Inline",
142  "uploaded_file" : open(temp[1], "rb") }
143  print(opener.open(validatorURL, params).read())
144  os.remove(temp[1])
145 
146  if len(sys.argv[1:]) > 0:
147  for arg in sys.argv[1:]:
148  validateFile(arg)
149  else:
150  validateFile("http://www.google.com")
151 
152 if __name__=="__main__":
153  main()
hardwareprofile.MultipartPostHandler.MultipartPostHandler.multipart_encode
multipart_encode
Definition: MultipartPostHandler.py:127
discid.disc.read
def read(device=None, features=[])
Definition: disc.py:35
print
static void print(const QList< uint > &raw_minimas, const QList< uint > &raw_maximas, const QList< float > &minimas, const QList< float > &maximas)
Definition: vbi608extractor.cpp:29
hardwareprofile.MultipartPostHandler.MultipartPostHandler
Definition: MultipartPostHandler.py:74
hardwareprofile.MultipartPostHandler.MultipartPostHandler.http_request
def http_request(self, request)
Definition: MultipartPostHandler.py:77
hardwareprofile.MultipartPostHandler.Callable.__call__
__call__
Definition: MultipartPostHandler.py:68
hardwareprofile.MultipartPostHandler.Callable
Definition: MultipartPostHandler.py:66
hardwareprofile.MultipartPostHandler.Callable.__init__
def __init__(self, anycallable)
Definition: MultipartPostHandler.py:67
hardwareprofile.MultipartPostHandler.main
def main()
Definition: MultipartPostHandler.py:131
find
static pid_list_t::iterator find(const PIDInfoMap &map, pid_list_t &list, pid_list_t::iterator begin, pid_list_t::iterator end, bool find_open)
Definition: dvbstreamhandler.cpp:363