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 builtins import object
45 from email.generator import _make_boundary
46 import mimetypes
47 import os, stat
48 import sys
49 from io import StringIO
50 
51 IS_PY2 = sys.version_info[0] == 2
52 
53 if IS_PY2:
54  from urllib2 import BaseHandler, build_opener, HTTPHandler
55 else:
56  from urllib.request import BaseHandler, build_opener, HTTPHandler
57 
58 if IS_PY2:
59  import urllib as ulib
60 else:
61  import urllib.parse as ulib
62 
63 
64 class Callable(object):
65  def __init__(self, anycallable):
66  self.__call__ = anycallable
67 
68 # Controls how sequences are uncoded. If true, elements may be given multiple values by
69 # assigning a sequence.
70 doseq = 1
71 
72 class MultipartPostHandler(BaseHandler):
73  handler_order = HTTPHandler.handler_order - 10 # needs to run first
74 
75  def http_request(self, request):
76  data = request.data
77  if data is not None and type(data) != str:
78  v_files = []
79  v_vars = []
80  try:
81  for(key, value) in list(data.items()):
82  # 'file' type doesn't exist in python3 and we didn't use it. Removed if:
83  v_vars.append((key, value))
84  except TypeError:
85  systype, value, traceback = sys.exc_info()
86  raise TypeError("not a valid non-string sequence or mapping object", traceback)
87 
88  if len(v_files) == 0:
89  data = ulib.urlencode(v_vars, doseq)
90  else:
91  boundary, data = self.multipart_encode(v_vars, v_files)
92 
93  contenttype = 'multipart/form-data; boundary=%s' % boundary
94  if(request.has_header('Content-Type')
95  and request.get_header('Content-Type').find('multipart/form-data') != 0):
96  print("Replacing %s with %s" % (request.get_header('content-type'), 'multipart/form-data'))
97  request.add_unredirected_header('Content-Type', contenttype)
98 
99  request.data = bytearray(data, 'latin1')
100 
101  return request
102 
103  def multipart_encode(self, these_vars, files, boundary = None, buf = None):
104  if boundary is None:
105  boundary = _make_boundary(os.getuid + os.getpid())
106  if buf is None:
107  buf = StringIO()
108  for(key, value) in these_vars:
109  buf.write('--%s\r\n' % boundary)
110  buf.write('Content-Disposition: form-data; name="%s"' % key)
111  buf.write('\r\n\r\n' + value + '\r\n')
112  for(key, fd) in files:
113  file_size = os.fstat(fd.fileno())[stat.ST_SIZE]
114  filename = fd.name.split('/')[-1]
115  contenttype = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
116  buf.write('--%s\r\n' % boundary)
117  buf.write('Content-Disposition: form-data; name="%s"; filename="%s"\r\n' % (key, filename))
118  buf.write('Content-Type: %s\r\n' % contenttype)
119  # buffer += 'Content-Length: %s\r\n' % file_size
120  fd.seek(0)
121  buf.write('\r\n' + fd.read() + '\r\n')
122  buf.write('--' + boundary + '--\r\n\r\n')
123  buf = buf.getvalue()
124  return boundary, buf
125  multipart_encode = Callable(multipart_encode)
126 
127  https_request = http_request
128 
129 def main():
130  import tempfile, sys
131 
132  validatorURL = "http://validator.w3.org/check"
133  opener = build_opener(MultipartPostHandler)
134 
135  def validateFile(url):
136  temp = tempfile.mkstemp(suffix=".html")
137  os.write(temp[0], opener.open(url).read())
138  params = { "ss" : "0", # show source
139  "doctype" : "Inline",
140  "uploaded_file" : open(temp[1], "rb") }
141  print(opener.open(validatorURL, params).read())
142  os.remove(temp[1])
143 
144  if len(sys.argv[1:]) > 0:
145  for arg in sys.argv[1:]:
146  validateFile(arg)
147  else:
148  validateFile("http://www.google.com")
149 
150 if __name__=="__main__":
151  main()
hardwareprofile.MultipartPostHandler.MultipartPostHandler.multipart_encode
multipart_encode
Definition: MultipartPostHandler.py:125
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:72
hardwareprofile.MultipartPostHandler.MultipartPostHandler.http_request
def http_request(self, request)
Definition: MultipartPostHandler.py:75
hardwareprofile.MultipartPostHandler.Callable.__call__
__call__
Definition: MultipartPostHandler.py:66
hardwareprofile.MultipartPostHandler.Callable
Definition: MultipartPostHandler.py:64
hardwareprofile.MultipartPostHandler.Callable.__init__
def __init__(self, anycallable)
Definition: MultipartPostHandler.py:65
hardwareprofile.MultipartPostHandler.main
def main()
Definition: MultipartPostHandler.py:129
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