Projet

Général

Profil

0001-add-query-string-parameters-to-webservice-call-actio.patch

Benjamin Dauvergne, 06 juin 2016 10:13

Télécharger (7,77 ko)

Voir les différences:

Subject: [PATCH] add query string parameters to webservice call action

 help/fr/wf-wscall.page  |  9 ++++++++
 tests/test_workflows.py | 23 ++++++++++++++++++++
 wcs/wf/wscall.py        | 58 +++++++++++++++++++++++++++++++++++++++++--------
 3 files changed, 81 insertions(+), 9 deletions(-)
help/fr/wf-wscall.page
29 29
</example>
30 30

  
31 31
<p>
32
Le tableau « Données à envoyer en paramètre » permet de décrire des données qui
33
seront transmises sous la forme de paramètres d'URL.  Sur chaque ligne, la
34
colonne de gauche est le nom de la clé, celle de droite la valeur. La valeur
35
peut être une expression Python, pour cela elle doit commencer par le signe
36
« = ». Les paramètres d'URL ne peuvent être que des chaînes si ce n'est pas le
37
cas la donnée sera transformée en chaîne de force.
38
</p>
39

  
40
<p>
32 41
La case à cocher « Envoyer le formulaire (POST, en JSON) » indique que
33 42
l'ensemble des données du formulaire doivent être transmises, avec un appel de
34 43
type <code>POST</code>, dont le contenu correspondra au formulaire encodé au
tests/test_workflows.py
3 3
import shutil
4 4
import time
5 5
import urllib2
6
import urlparse
6 7

  
7 8
import mock
8 9

  
......
849 850
    rendered = formdata.evolution[-1].parts[-1].view()
850 851
    assert 'Error during webservice call &quot;do that&quot;' in str(rendered)
851 852

  
853
    item = WebserviceCallStatusItem()
854
    item.method = 'GET'
855
    item.post = False
856
    item.url = 'http://remote.example.net?in_url=1'
857
    item.qs_data = {
858
        'str': 'abcd',
859
        'one': '=1',
860
        'evalme': '=form_number',
861
        'error': '=1=3',
862
        'in_url': '2',
863
    }
864
    pub.substitutions.feed(formdata)
865
    item.perform(formdata)
866
    assert http_requests.get_last('method') == 'GET'
867
    qs = urlparse.parse_qs(http_requests.get_last('url').split('?')[1])
868
    assert set(qs.keys()) == set(['in_url', 'str', 'one', 'evalme'])
869
    assert qs['in_url'] == ['1', '2']
870
    assert qs['one'] == ['1']
871
    assert qs['evalme'] == [formdata.get_display_id()]
872
    assert qs['str'] == ['abcd']
873

  
874

  
852 875
def test_timeout(pub):
853 876
    workflow = Workflow(name='timeout')
854 877
    st1 = workflow.add_status('Status1', 'st1')
wcs/wf/wscall.py
22 22
import collections
23 23
import mimetypes
24 24
from StringIO import StringIO
25
import urllib
26
import urlparse
27

  
25 28

  
26 29
from quixote.html import TemplateIO, htmltext
27 30
from qommon.errors import ConnectionError
......
103 106
    post = True
104 107
    request_signature_key = None
105 108
    post_data = None
109
    qs_data = None
106 110
    _method = None
107 111
    response_type = 'json'
108 112

  
......
135 139
        return ('url', 'post', 'varname', 'request_signature_key', 'post_data',
136 140
                'action_on_4xx', 'action_on_5xx', 'action_on_bad_data',
137 141
                'action_on_network_errors', 'notify_on_errors',
138
                'record_errors', 'label', 'method', 'response_type')
142
                'record_errors', 'label', 'method', 'response_type',
143
                'qs_data')
139 144

  
140 145
    def add_parameters_widgets(self, form, parameters, prefix='', formdef=None):
141 146
        if 'label' in parameters:
......
150 155
            form.add(ComputedExpressionWidget, '%srequest_signature_key' % prefix,
151 156
                    title=_('Request Signature Key'),
152 157
                    value=self.request_signature_key)
158
        if 'qs_data' in parameters:
159
            form.add(WidgetDict, '%sqs_data' % prefix,
160
                    title=_('Query string data'),
161
                    value=self.qs_data or {},
162
                    element_value_type=ComputedExpressionWidget)
153 163
        methods = collections.OrderedDict(
154 164
                [('GET', _('GET')), ('POST', _('POST (JSON)'))])
155 165
        if 'method' in parameters:
......
234 244
            variables = get_publisher().substitutions.get_context_variables()
235 245
            url = get_variadic_url(url, variables)
236 246

  
247
        if self.qs_data:  # merge qs_data into url
248
            publisher = get_publisher()
249
            parsed = urlparse.urlparse(url)
250
            qs = list(urlparse.parse_qsl(parsed.query))
251
            for key, value in self.qs_data.iteritems():
252
                try:
253
                    value = self.compute(value, raises=True)
254
                    value = str(value)
255
                except:
256
                    get_publisher().notify_of_exception(sys.exc_info())
257
                else:
258
                    key = publisher.sitecharset2utf8(key)
259
                    value = publisher.sitecharset2utf8(value)
260
                    qs.append((key, value))
261
            qs = urllib.urlencode(qs)
262
            url = urlparse.urlunparse(parsed[:4] + (qs,) + parsed[5:6])
263

  
237 264
        if self.request_signature_key:
238 265
            signature_key = self.compute(self.request_signature_key)
239 266
            if signature_key:
......
372 399
    def get_jump_label(self):
373 400
        return _('Error calling webservice')
374 401

  
375
    def post_data_export_to_xml(self, xml_item, charset, include_id=False):
376
        if not self.post_data:
402
    def _kv_data_export_to_xml(self, xml_item, charset, include_id, attribute):
403
        assert attribute
404
        if not getattr(self, attribute):
377 405
            return
378
        el = ET.SubElement(xml_item, 'post_data')
379
        for (key, value) in self.post_data.items():
406
        el = ET.SubElement(xml_item, attribute)
407
        for (key, value) in getattr(self, attribute).items():
380 408
            item = ET.SubElement(el, 'item')
381 409
            if type(key) is unicode:
382 410
                ET.SubElement(item, 'name').text = key
......
391 419
            else:
392 420
                raise AssertionError('unknown type for value (%r)' % key)
393 421

  
394

  
395
    def post_data_init_with_xml(self, elem, charset, include_id=False):
422
    def _kv_data_init_with_xml(self, elem, charset, include_id, attribute):
396 423
        if elem is None:
397 424
            return
398
        self.post_data = {}
425
        setattr(self, attribute, {})
399 426
        for item in elem.findall('item'):
400 427
            key = item.find('name').text.encode(charset)
401 428
            value = item.find('value').text.encode(charset)
402
            self.post_data[key] = value
429
            getattr(self, attribute)[key] = value
430

  
431
    def post_data_export_to_xml(self, xml_item, charset, include_id=False):
432
        self._kv_data_export_to_xml(self, xml_item, charset, include_id=include_id,
433
                                    attribute='post_data')
434

  
435
    def post_data_init_with_xml(self, elem, charset, include_id=False):
436
        self._kv_data_init_with_xml(elem, charset, include_id=include_id, attribute='post_data')
437

  
438
    def qs_data_export_to_xml(self, xml_item, charset, include_id=False):
439
        self._kv_data_export_to_xml(xml_item, charset, include_id=include_id, attribute='qs_data')
440

  
441
    def qs_data_init_with_xml(self, elem, charset, include_id=False):
442
        self._kv_data_init_with_xml(element, charset, include_id=include_id, attribute='qs_data')
403 443

  
404 444
register_item_class(WebserviceCallStatusItem)
405
-