[wwwsearch-commits] r22471 - wwwsearch/ClientForm/trunk

jjlee at codespeak.net jjlee at codespeak.net
Fri Jan 20 22:30:58 CET 2006


Author: jjlee
Date: Fri Jan 20 22:30:57 2006
New Revision: 22471

Modified:
   wwwsearch/ClientForm/trunk/ClientForm.py
   wwwsearch/ClientForm/trunk/test.py
Log:
Fix POST multipart/form-data parameter ordering (Balazs Ree  <ree at ree.hu>) and ImageControl ordering

Modified: wwwsearch/ClientForm/trunk/ClientForm.py
==============================================================================
--- wwwsearch/ClientForm/trunk/ClientForm.py	(original)
+++ wwwsearch/ClientForm/trunk/ClientForm.py	Fri Jan 20 22:30:57 2006
@@ -1001,8 +1001,9 @@
             type, name, attrs = controls[ii]
             attrs = fp.unescape_attrs_if_required(attrs)
             name = fp.unescape_attr_if_required(name)
+            # index=ii*10 allows ImageControl to return multiple ordered pairs
             form.new_control(type, name, attrs, select_default=select_default,
-                             index=ii)
+                             index=ii*10)
         forms.append(form)
     for form in forms:
         form.fixup()
@@ -1134,15 +1135,14 @@
         """
         raise NotImplementedError()
 
-    def _write_mime_data(self, mw):
-        """Write data for this control to a MimeWriter."""
+    def _write_mime_data(self, mw, name, value):
+        """Write data for a subitem of this control to a MimeWriter."""
         # called by HTMLForm
-        for name, value in self.pairs():
-            mw2 = mw.nextpart()
-            mw2.addheader("Content-disposition",
-                          'form-data; name="%s"' % name, 1)
-            f = mw2.startbody(prefix=0)
-            f.write(value)
+        mw2 = mw.nextpart()
+        mw2.addheader("Content-disposition",
+                      'form-data; name="%s"' % name, 1)
+        f = mw2.startbody(prefix=0)
+        f.write(value)
 
     def __str__(self):
         raise NotImplementedError()
@@ -1303,8 +1303,9 @@
             return []
         return [(self._index, self.name, "")]
 
-    def _write_mime_data(self, mw):
+    def _write_mime_data(self, mw, _name, _value):
         # called by HTMLForm
+        # assert _name == self.name and _value == ''
         if len(self._upload_data) == 1:
             # single file
             file_object, content_type, filename = self._upload_data[0]
@@ -2336,11 +2337,11 @@
         if name is None: return []
         pairs = [
             (self._index, "%s.x" % name, str(clicked[0])),
-            (self._index, "%s.y" % name, str(clicked[1])),
+            (self._index+1, "%s.y" % name, str(clicked[1])),
             ]
         value = self._value
         if value:
-            pairs.append((self._index, name, value))
+            pairs.append((self._index+2, name, value))
         return pairs
 
     get_labels = ScalarControl.get_labels
@@ -3148,17 +3149,22 @@
 
     def _pairs(self):
         """Return sequence of (key, value) pairs suitable for urlencoding."""
-        opairs = []
-        for control in self.controls:
-            opairs.extend(control._totally_ordered_pairs())
+        return [(k, v) for (i, k, v, c_i) in self._pairs_and_controls()]
+
+
+    def _pairs_and_controls(self):
+        """Return sequence of (index, key, value, control_index)
+        of totally ordered pairs suitable for urlencoding.
+
+        control_index is the index of the control in self.controls
+        """
+        pairs = []
+        for control_index, control in enumerate(self.controls):
+            for ii, key, val in control._totally_ordered_pairs():
+                pairs.append((ii, key, val, control_index))
 
         # stable sort by ONLY first item in tuple
-        sorter = []
-        for jj in range(len(opairs)):
-            ii, key, val = opairs[jj]
-            sorter.append((ii, jj, key, val))
-        sorter.sort()
-        pairs = [(key, val) for (ii, jj, key, val) in sorter]
+        pairs.sort()
 
         return pairs
 
@@ -3188,8 +3194,8 @@
                 mw = MimeWriter(data, http_hdrs)
                 f = mw.startmultipartbody("form-data", add_to_http_hdrs=True,
                                           prefix=0)
-                for control in self.controls:
-                    control._write_mime_data(mw)
+                for ii, k, v, control_index in self._pairs_and_controls():
+                    self.controls[control_index]._write_mime_data(mw, k, v)
                 mw.lastpart()
                 return uri, data.getvalue(), http_hdrs
             else:

Modified: wwwsearch/ClientForm/trunk/test.py
==============================================================================
--- wwwsearch/ClientForm/trunk/test.py	(original)
+++ wwwsearch/ClientForm/trunk/test.py	Fri Jan 20 22:30:57 2006
@@ -1216,7 +1216,7 @@
         attrs = {"type": "this is ignored",
                  "name": "name_value",
                  "img": "foo.gif"}
-        c = ClientForm.ImageControl("image", "name_value", attrs)
+        c = ClientForm.ImageControl("image", "name_value", attrs, index=0)
         self.assert_(c.type == "image")
         self.assert_(c.name == "name_value")
         self.assert_(c.value == "")
@@ -1242,8 +1242,8 @@
                       None, []))
         c.value = "blah"
         request = c._click(form, (0, 55), "request")
-        self.assert_(request.get_full_url() ==
-                     "http://foo.bar.com/?name_value.x=0&name_value.y=55&name_value=blah")
+        self.assertEqual(request.get_full_url(), "http://foo.bar.com/?"
+                         "name_value.x=0&name_value.y=55&name_value=blah")
 
         c.disabled = True
         self.assertEqual(c.value, "blah")
@@ -1258,7 +1258,9 @@
         self.assert_(c._click(form, (1,1), return_type="pairs") == [])
         c.disabled = c.readonly = False
         self.assert_(c._click(form, (1,1), return_type="pairs") ==
-                     [("name_value.x", "1"), ("name_value.y", "1"), ('name_value', 'blah')])
+                     [("name_value.x", "1"),
+                      ("name_value.y", "1"),
+                      ('name_value', 'blah')])
 
     def testCheckboxControl(self):
         attrs = {"type": "this is ignored",
@@ -2728,6 +2730,19 @@
                 ("murphy", "c"),
                 ])
 
+        form.method = "POST"
+        form.enctype = "multipart/form-data"
+        lines = [line for line in form.click_request_data()[1].split("\r\n") if
+                 line != '' and not line.startswith("--")]
+        self.assertEqual(
+            lines,
+            ['Content-disposition: form-data; name="murphy"', 'a',
+             'Content-disposition: form-data; name="woof"', 'd',
+             'Content-disposition: form-data; name="murphy"', 'b',
+             'Content-disposition: form-data; name="murphy"', 'c',
+             ]
+            )
+
     def make_form(self):
         f = StringIO("""\
 <form blah="nonsense" name="formname">


More information about the wwwsearch-commits mailing list