Projet

Général

Profil

0001-gdc-replace-SOAPpy-usage-by-straight-POSTs-43756.patch

Frédéric Péters, 08 juin 2020 21:59

Télécharger (9,94 ko)

Voir les différences:

Subject: [PATCH] gdc: replace SOAPpy usage by straight POSTs (#43756)

 passerelle/apps/gdc/models.py | 62 ++++++++++++++++++++++++++++-------
 passerelle/apps/gdc/views.py  | 50 +++++++++++-----------------
 2 files changed, 71 insertions(+), 41 deletions(-)
passerelle/apps/gdc/models.py
1
try:
2
    import SOAPpy
3
except ImportError:
4
    SOAPpy = None
1
import xml.etree.ElementTree as ET
5 2

  
6 3
try:
7 4
    import phpserialize
......
17 14
from passerelle.utils.api import endpoint
18 15

  
19 16

  
17
def deep_bytes2str(obj):
18
    if obj is None or isinstance(obj, (int, str)):
19
        return obj
20
    if isinstance(obj, bytes):
21
        try:
22
            return obj.decode('utf-8')
23
        except UnicodeDecodeError:
24
            return obj
25
    if isinstance(obj, list):
26
        return [deep_bytes2str(x) for x in obj]
27
    if isinstance(obj, dict):
28
        new_d = {}
29
        for k, v in obj.items():
30
            new_d[force_text(k)] = deep_bytes2str(v)
31
        return new_d
32
    return obj
33

  
34

  
20 35
def phpserialize_loads(s):
21
    return phpserialize.loads(s.encode('utf-8'))
36
    return deep_bytes2str(phpserialize.loads(s.encode('utf-8')))
22 37

  
23 38

  
24 39
class Gdc(BaseResource):
......
31 46
    class Meta:
32 47
        verbose_name = _('GDC Web Service')
33 48

  
49
    def call_soap(self, action, *args, **kwargs):
50
        params = []
51
        for i, arg in enumerate(args):
52
            params.append('<v%(i)s xsi:type="xsd:string">%(value)s</v%(i)s>' % {'i': i + 1, 'value': arg})
53
        for key, value in kwargs.items():
54
            type_ = 'int' if isinstance(value, int) else 'string'
55
            params.append('<%(key)s xsi:type="xsd:%(type)s">%(value)s</%(key)s>' % {
56
                'key': key, 'type': type_, 'value': value})
57

  
58
        data = """<?xml version="1.0" encoding="UTF-8"?>
59
<SOAP-ENV:Envelope
60
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
61
  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
62
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
63
>
64
<SOAP-ENV:Body>
65
<%(action)s SOAP-ENC:root="1">
66
%(params)s
67
</%(action)s>
68
</SOAP-ENV:Body>
69
</SOAP-ENV:Envelope>""" % {'action': action, 'params': ''.join(params)}
70
        resp = self.requests.post(self.service_url, data=data)
71
        return ET.ElementTree(ET.fromstring(resp.content))
72

  
73

  
34 74
    @endpoint()
35 75
    def communes(self, request, *args, **kwargs):
36
        server = SOAPpy.SOAPProxy(self.service_url)
37
        soap_result = phpserialize_loads(server.getListeCommune()['listeCommune'])
76
        resp = self.call_soap('getListeCommune')
77
        soap_result = phpserialize_loads(resp.findall('.//listeCommune')[0].text)
38 78
        result = []
39 79
        for k, v in soap_result.items():
40 80
            result.append({'id': k, 'text': force_text(v, 'utf-8')})
41
        result.sort(lambda x,y: cmp(x['id'], y['id']))
81
        result.sort(key=lambda x: x['id'])
42 82
        return result
43 83

  
44 84
    @endpoint()
45 85
    def objets(self, request, *args, **kwargs):
46
        server = SOAPpy.SOAPProxy(self.service_url)
47
        soap_result = phpserialize_loads(server.getListeObjet()['listeObjet'])
86
        resp = self.call_soap('getListeObjet')
87
        soap_result = phpserialize_loads(resp.findall('.//listeObjet')[0].text)
48 88
        result = []
49 89
        for k, v in soap_result.items():
50 90
            result.append({'id': k, 'text': force_text(v, 'utf-8')})
51
        result.sort(lambda x,y: cmp(x['id'], y['id']))
91
        result.sort(key=lambda x: x['id'])
52 92
        return result
passerelle/apps/gdc/views.py
1 1
from django.http import Http404
2
from django.utils.encoding import force_text
2 3
from django.views.generic.base import View
3 4
from django.views.generic.detail import SingleObjectMixin, DetailView
4 5

  
......
6 7
import passerelle.utils as utils
7 8
from passerelle.utils.conversion import normalize
8 9

  
9
from .models import Gdc, phpserialize, phpserialize_loads, SOAPpy
10
from .models import Gdc, phpserialize, phpserialize_loads
10 11

  
11 12

  
12 13
class GdcCrash(Exception):
......
17 18
    model = Gdc
18 19

  
19 20
    def get(self, request, *args, **kwargs):
20
        if SOAPpy is None:
21
            raise Http404
22 21
        ref = int(kwargs.get('ref'))
23
        server = SOAPpy.SOAPProxy(self.get_object().service_url)
22
        service = self.get_object()
24 23
        try:
25
            soap_result = server.getDemandeControleurEtat(ref)['listeInfo']
24
            resp = service.call_soap('getDemandeControleurEtat', ref)
25
            soap_result = resp.findall('.//listeInfo')[0].text
26 26
        except:
27 27
            # if there's a gdc crash don't return anything and hopefully the
28 28
            # w.c.s. workflow will handle that and retry later.
......
30 30
        else:
31 31
            gdc_result = phpserialize_loads(soap_result)
32 32
            result = {
33
                'status_id': gdc_result['STATUT_ID']
33
                'status_id': gdc_result['STATUT_ID'],
34 34
            }
35 35
        return utils.response_for_json(request, {'data': result})
36 36

  
37 37

  
38
def get_voies(service_url, insee):
39
    server = SOAPpy.SOAPProxy(service_url)
40
    try:
41
        raw_soap_result = server.getListeVoieCommune(insee)
42
    except:
43
        raise GdcCrash()
44
    soap_result = phpserialize_loads(raw_soap_result['listeVoie'])
38
def get_voies(service, insee):
39
    resp = service.call_soap('getListeVoieCommune', insee)
40
    soap_result = phpserialize_loads(resp.findall('.//listeVoie')[0].text)
45 41
    result = []
46 42
    prefix_map = {
47 43
            'ALL': 'ALLEE',
......
84 80
            if v.startswith(prefix + ' '):
85 81
                v = (full + v[len(prefix):]).strip()
86 82
        result.append({'id': k, 'text': v})
87
    result.sort(lambda x,y: cmp(x['id'], y['id']))
83
    result.sort(key=lambda x: x['id'])
88 84
    return result
89 85

  
90 86

  
......
92 88
    model = Gdc
93 89

  
94 90
    def get(self, request, *args, **kwargs):
95
        if SOAPpy is None:
96
            raise Http404
97 91
        insee = kwargs.get('insee')
98 92
        try:
99
            result = get_voies(self.get_object().service_url, insee)
93
            result = get_voies(self.get_object(), insee)
100 94
        except GdcCrash:
101 95
            result = []
102 96
        q = request.GET.get('q')
......
110 104
    model = Gdc
111 105

  
112 106
    @utils.protected_api('can_post_request')
113
    def post(self, request, *args, **kwargs):
107
    def get(self, request, *args, **kwargs):
114 108
        # <wsdl:message name='addDemandeExterneParticulierRequest'>
115 109
        #   <wsdl:part name='nom' type='xsd:string'></wsdl:part>
116 110
        #   <wsdl:part name='prenom' type='xsd:string'></wsdl:part>
......
122 116
        #   <wsdl:part name='voie_id' type='xsd:string'></wsdl:part>
123 117
        #   <wsdl:part name='voie_num' type='xsd:string'></wsdl:part>
124 118
        # </wsdl:message>
125
        if SOAPpy is None:
126
            raise Http404
127 119
        data = json_loads(request.body)
128
        server = SOAPpy.SOAPProxy(self.get_object().service_url)
129 120
        voie_id = data['fields'].get('voie_raw')
130 121
        voie_str = data['fields'].get('voie')
131 122
        insee = data['fields'].get('commune_raw')
......
133 124
            # look for a voie with that name, so we can provide an identifier
134 125
            # to gdc
135 126
            try:
136
                voies = get_voies(self.get_object().service_url, insee)
127
                voies = get_voies(self.get_object(), insee)
137 128
            except GdcCrash:
138 129
                result = {'result': 'gdc soap crash'}
139 130
                return utils.response_for_json(request, result)
......
152 143
            'prenom': data['fields'].get('prenom'),
153 144
            'mail': data['fields'].get('mail'),
154 145
            'telephone': data['fields'].get('telephone'),
155
            'objet_externe': objet,
146
            'objet_externe': int(objet),
156 147
            'commentaire': data['fields'].get('commentaire'),
157
            'insee_commune': insee,
148
            'insee_commune': int(insee),
158 149
            'voie_id': voie_id,
159 150
            'voie_str': voie_str,
160 151
            'voie_num': data['fields'].get('voie_num'),
......
165 156
            kwargs['picture_b64'] = data['fields']['picture']['content']
166 157

  
167 158
        try:
168
            soap_result = server.addDemandeExterneParticulier(**kwargs)
169
        except:
159
            resp = self.get_object().call_soap('addDemandeExterneParticulier', **kwargs)
160
        except IOError:
170 161
            result = {'result': 'gdc soap crash'}
171 162
        else:
172
            result = phpserialize_loads(soap_result['listeInfo'])
173
            result = {'result': soap_result['code_retour'],
163
            code_retour = force_text(resp.findall('.//code_retour')[0].text)
164
            result = phpserialize_loads(resp.findall('.//listeInfo')[0].text)
165
            result = {'result': code_retour,
174 166
                    'display_id': result.get('IDENTIFIANT'),
175 167
                    'id': result.get('IDENTIFIANT'),
176 168
                    'details': result}
......
185 177
        context = super(GdcDetailView, self).get_context_data(**kwargs)
186 178
        if phpserialize is None:
187 179
            context['missing_phpserialize'] = True
188
        if SOAPpy is None:
189
            context['missing_soappy'] = True
190 180
        return context
191
-