132 lines
4.5 KiB
Python
132 lines
4.5 KiB
Python
# Passerelle - uniform access to data and services
|
|
# Copyright (C) 2015-2020 Entr'ouvert
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify it
|
|
# under the terms of the GNU Affero General Public License as published
|
|
# by the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Affero General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import xml.etree.ElementTree as ET
|
|
|
|
try:
|
|
import phpserialize
|
|
except ImportError:
|
|
phpserialize = None
|
|
|
|
from django.db import models
|
|
from django.utils.encoding import force_str
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from passerelle.base.models import BaseResource
|
|
from passerelle.utils.api import endpoint
|
|
from passerelle.utils.jsonresponse import APIError
|
|
|
|
|
|
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_str(k)] = deep_bytes2str(v)
|
|
return new_d
|
|
return obj
|
|
|
|
|
|
def phpserialize_loads(s):
|
|
try:
|
|
return deep_bytes2str(phpserialize.loads(s.encode('utf-8')))
|
|
except ValueError:
|
|
truncated = s[:128] if isinstance(s, str) else s
|
|
raise APIError(f'Could not deserialize GDC response {truncated!r}', data={'content': s})
|
|
|
|
|
|
class Gdc(BaseResource):
|
|
service_url = models.CharField(
|
|
max_length=128, blank=False, verbose_name=_('Service URL'), help_text=_('GDC Web Service URL')
|
|
)
|
|
|
|
category = _('Business Process Connectors')
|
|
|
|
class Meta:
|
|
verbose_name = _('GDC Web Service')
|
|
|
|
def call_soap(self, action, *args, **kwargs):
|
|
def escape(s):
|
|
return force_str(s).replace('&', '&').replace('>', '>').replace('<', '<')
|
|
|
|
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': escape(arg)}
|
|
)
|
|
for key, value in kwargs.items():
|
|
if value is None:
|
|
params.append('<%s xsi:null="1"/>' % key)
|
|
continue
|
|
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': escape(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:xsi="http://www.w3.org/1999/XMLSchema-instance"
|
|
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
|
xmlns:xsd="http://www.w3.org/1999/XMLSchema"
|
|
>
|
|
<SOAP-ENV:Body>
|
|
<%(action)s SOAP-ENC:root="1">
|
|
%(params)s
|
|
</%(action)s>
|
|
</SOAP-ENV:Body>
|
|
</SOAP-ENV:Envelope>""" % {
|
|
'action': action,
|
|
'params': '\n'.join(params),
|
|
}
|
|
resp = self.requests.post(
|
|
self.service_url,
|
|
data=data.encode('utf-8'),
|
|
headers={'SOAPAction': '"%s"' % action, 'Content-type': 'text/xml; charset=UTF-8'},
|
|
)
|
|
|
|
return ET.ElementTree(ET.fromstring(resp.content))
|
|
|
|
@endpoint(perm='OPEN')
|
|
def communes(self, request, *args, **kwargs):
|
|
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_str(v, 'utf-8')})
|
|
result.sort(key=lambda x: x['id'])
|
|
return result
|
|
|
|
@endpoint(perm='OPEN')
|
|
def objets(self, request, *args, **kwargs):
|
|
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_str(v, 'utf-8')})
|
|
result.sort(key=lambda x: x['id'])
|
|
return result
|