gdc: replace SOAPpy usage by straight POSTs (#43756)

This commit is contained in:
Frédéric Péters 2020-06-08 21:58:35 +02:00
parent f44a95ac7f
commit 07b56cdddb
2 changed files with 71 additions and 41 deletions

View File

@ -1,7 +1,4 @@
try:
import SOAPpy
except ImportError:
SOAPpy = None
import xml.etree.ElementTree as ET
try:
import phpserialize
@ -17,8 +14,26 @@ from passerelle.base.models import BaseResource
from passerelle.utils.api import endpoint
def deep_bytes2str(obj):
if obj is None or isinstance(obj, (int, str)):
return obj
if isinstance(obj, bytes):
try:
return obj.decode('utf-8')
except UnicodeDecodeError:
return obj
if isinstance(obj, list):
return [deep_bytes2str(x) for x in obj]
if isinstance(obj, dict):
new_d = {}
for k, v in obj.items():
new_d[force_text(k)] = deep_bytes2str(v)
return new_d
return obj
def phpserialize_loads(s):
return phpserialize.loads(s.encode('utf-8'))
return deep_bytes2str(phpserialize.loads(s.encode('utf-8')))
class Gdc(BaseResource):
@ -31,22 +46,47 @@ class Gdc(BaseResource):
class Meta:
verbose_name = _('GDC Web Service')
def call_soap(self, action, *args, **kwargs):
params = []
for i, arg in enumerate(args):
params.append('<v%(i)s xsi:type="xsd:string">%(value)s</v%(i)s>' % {'i': i + 1, 'value': arg})
for key, value in kwargs.items():
type_ = 'int' if isinstance(value, int) else 'string'
params.append('<%(key)s xsi:type="xsd:%(type)s">%(value)s</%(key)s>' % {
'key': key, 'type': type_, 'value': value})
data = """<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
>
<SOAP-ENV:Body>
<%(action)s SOAP-ENC:root="1">
%(params)s
</%(action)s>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>""" % {'action': action, 'params': ''.join(params)}
resp = self.requests.post(self.service_url, data=data)
return ET.ElementTree(ET.fromstring(resp.content))
@endpoint()
def communes(self, request, *args, **kwargs):
server = SOAPpy.SOAPProxy(self.service_url)
soap_result = phpserialize_loads(server.getListeCommune()['listeCommune'])
resp = self.call_soap('getListeCommune')
soap_result = phpserialize_loads(resp.findall('.//listeCommune')[0].text)
result = []
for k, v in soap_result.items():
result.append({'id': k, 'text': force_text(v, 'utf-8')})
result.sort(lambda x,y: cmp(x['id'], y['id']))
result.sort(key=lambda x: x['id'])
return result
@endpoint()
def objets(self, request, *args, **kwargs):
server = SOAPpy.SOAPProxy(self.service_url)
soap_result = phpserialize_loads(server.getListeObjet()['listeObjet'])
resp = self.call_soap('getListeObjet')
soap_result = phpserialize_loads(resp.findall('.//listeObjet')[0].text)
result = []
for k, v in soap_result.items():
result.append({'id': k, 'text': force_text(v, 'utf-8')})
result.sort(lambda x,y: cmp(x['id'], y['id']))
result.sort(key=lambda x: x['id'])
return result

View File

@ -1,4 +1,5 @@
from django.http import Http404
from django.utils.encoding import force_text
from django.views.generic.base import View
from django.views.generic.detail import SingleObjectMixin, DetailView
@ -6,7 +7,7 @@ from passerelle.compat import json_loads
import passerelle.utils as utils
from passerelle.utils.conversion import normalize
from .models import Gdc, phpserialize, phpserialize_loads, SOAPpy
from .models import Gdc, phpserialize, phpserialize_loads
class GdcCrash(Exception):
@ -17,12 +18,11 @@ class StatusView(View, SingleObjectMixin):
model = Gdc
def get(self, request, *args, **kwargs):
if SOAPpy is None:
raise Http404
ref = int(kwargs.get('ref'))
server = SOAPpy.SOAPProxy(self.get_object().service_url)
service = self.get_object()
try:
soap_result = server.getDemandeControleurEtat(ref)['listeInfo']
resp = service.call_soap('getDemandeControleurEtat', ref)
soap_result = resp.findall('.//listeInfo')[0].text
except:
# if there's a gdc crash don't return anything and hopefully the
# w.c.s. workflow will handle that and retry later.
@ -30,18 +30,14 @@ class StatusView(View, SingleObjectMixin):
else:
gdc_result = phpserialize_loads(soap_result)
result = {
'status_id': gdc_result['STATUT_ID']
'status_id': gdc_result['STATUT_ID'],
}
return utils.response_for_json(request, {'data': result})
def get_voies(service_url, insee):
server = SOAPpy.SOAPProxy(service_url)
try:
raw_soap_result = server.getListeVoieCommune(insee)
except:
raise GdcCrash()
soap_result = phpserialize_loads(raw_soap_result['listeVoie'])
def get_voies(service, insee):
resp = service.call_soap('getListeVoieCommune', insee)
soap_result = phpserialize_loads(resp.findall('.//listeVoie')[0].text)
result = []
prefix_map = {
'ALL': 'ALLEE',
@ -84,7 +80,7 @@ def get_voies(service_url, insee):
if v.startswith(prefix + ' '):
v = (full + v[len(prefix):]).strip()
result.append({'id': k, 'text': v})
result.sort(lambda x,y: cmp(x['id'], y['id']))
result.sort(key=lambda x: x['id'])
return result
@ -92,11 +88,9 @@ class VoiesView(View, SingleObjectMixin):
model = Gdc
def get(self, request, *args, **kwargs):
if SOAPpy is None:
raise Http404
insee = kwargs.get('insee')
try:
result = get_voies(self.get_object().service_url, insee)
result = get_voies(self.get_object(), insee)
except GdcCrash:
result = []
q = request.GET.get('q')
@ -110,7 +104,7 @@ class PostDemandeView(View, SingleObjectMixin):
model = Gdc
@utils.protected_api('can_post_request')
def post(self, request, *args, **kwargs):
def get(self, request, *args, **kwargs):
# <wsdl:message name='addDemandeExterneParticulierRequest'>
# <wsdl:part name='nom' type='xsd:string'></wsdl:part>
# <wsdl:part name='prenom' type='xsd:string'></wsdl:part>
@ -122,10 +116,7 @@ class PostDemandeView(View, SingleObjectMixin):
# <wsdl:part name='voie_id' type='xsd:string'></wsdl:part>
# <wsdl:part name='voie_num' type='xsd:string'></wsdl:part>
# </wsdl:message>
if SOAPpy is None:
raise Http404
data = json_loads(request.body)
server = SOAPpy.SOAPProxy(self.get_object().service_url)
voie_id = data['fields'].get('voie_raw')
voie_str = data['fields'].get('voie')
insee = data['fields'].get('commune_raw')
@ -133,7 +124,7 @@ class PostDemandeView(View, SingleObjectMixin):
# look for a voie with that name, so we can provide an identifier
# to gdc
try:
voies = get_voies(self.get_object().service_url, insee)
voies = get_voies(self.get_object(), insee)
except GdcCrash:
result = {'result': 'gdc soap crash'}
return utils.response_for_json(request, result)
@ -152,9 +143,9 @@ class PostDemandeView(View, SingleObjectMixin):
'prenom': data['fields'].get('prenom'),
'mail': data['fields'].get('mail'),
'telephone': data['fields'].get('telephone'),
'objet_externe': objet,
'objet_externe': int(objet),
'commentaire': data['fields'].get('commentaire'),
'insee_commune': insee,
'insee_commune': int(insee),
'voie_id': voie_id,
'voie_str': voie_str,
'voie_num': data['fields'].get('voie_num'),
@ -165,12 +156,13 @@ class PostDemandeView(View, SingleObjectMixin):
kwargs['picture_b64'] = data['fields']['picture']['content']
try:
soap_result = server.addDemandeExterneParticulier(**kwargs)
except:
resp = self.get_object().call_soap('addDemandeExterneParticulier', **kwargs)
except IOError:
result = {'result': 'gdc soap crash'}
else:
result = phpserialize_loads(soap_result['listeInfo'])
result = {'result': soap_result['code_retour'],
code_retour = force_text(resp.findall('.//code_retour')[0].text)
result = phpserialize_loads(resp.findall('.//listeInfo')[0].text)
result = {'result': code_retour,
'display_id': result.get('IDENTIFIANT'),
'id': result.get('IDENTIFIANT'),
'details': result}
@ -185,6 +177,4 @@ class GdcDetailView(DetailView):
context = super(GdcDetailView, self).get_context_data(**kwargs)
if phpserialize is None:
context['missing_phpserialize'] = True
if SOAPpy is None:
context['missing_soappy'] = True
return context