Project

General

Profile

0002-mdel-improve-code-style-36471.patch

Benjamin Dauvergne, 26 Sep 2019 10:41 PM

Download (8.98 KB)

View differences:

Subject: [PATCH 2/2] mdel: improve code style (#36471)

 passerelle/apps/mdel/mdel.py   | 52 +++++++++++++++++++---------------
 passerelle/apps/mdel/models.py | 16 +++++++----
 passerelle/apps/mdel/utils.py  | 11 ++++---
 tests/test_mdel.py             |  2 +-
 4 files changed, 46 insertions(+), 35 deletions(-)
passerelle/apps/mdel/mdel.py
1
# Passerelle - uniform access to data and services
2
# Copyright (C) 2016  Entr'ouvert
1
# coding: utf-8
2
# passerelle - uniform access to data and services-
3
# Copyright (C) 2019  Entr'ouvert
3 4
#
4 5
# This program is free software: you can redistribute it and/or modify it
5 6
# under the terms of the GNU Affero General Public License as published
......
14 15
# You should have received a copy of the GNU Affero General Public License
15 16
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 17

  
18
from __future__ import unicode_literals
19

  
17 20
import os
18 21
import base64
19 22
import datetime
......
51 54

  
52 55

  
53 56
class MDELBase(object):
54

  
55 57
    def to_string(self):
56 58
        raw_string = etree.tostring(self.xml, encoding='utf-8')
57 59
        parsed_string = minidom.parseString(raw_string)
......
247 249

  
248 250
        return data
249 251

  
252
    @classmethod
253
    def path_to_xml(cls, path, value, parent):
254
        '''Resolve an XML `path` starting from `parent` and the target node content to `value`.'''
255

  
256
        if isinstance(path, list) and len(path) > 1:
257
            parent_child = parent.find(path[0])
258
            if parent_child is not None:
259
                element = parent_child
260
                path.pop(0)
261
            else:
262
                element = ElementFactory(path.pop(0))
263
            element.append(cls.path_to_xml(path, value, element), allow_new=False)
264
        else:
265
            element = ElementFactory(path[0], text=value)
266
        return element
267

  
250 268
    @property
251 269
    def xml(self):
252
        elements = []
270
        '''Generate an XML document applying values from `self.data` to `self.mapping`'''
253 271

  
272
        # extract text content from data for each path in mapping
273
        elements = []
254 274
        for key, path in self.mapping:
255 275
            if key in self.data:
256 276
                elements.append((path, self.data[key]))
257 277

  
278
        # recursively create XML nodes using self.path_to_xml()
258 279
        root = ElementFactory(self.root_element, **self.root_attributes)
259

  
260 280
        for path, value in elements:
261 281
            path_splitted = path.split('_')
262
            root.append(json_to_xml(path_splitted, value, root), allow_new=False)
282
            root.append(self.path_to_xml(path_splitted, value, root), allow_new=False)
263 283

  
264 284
        return root
265 285

  
286

  
266 287
class ILEData(Data):
288
    '''Démarche inscription sur les listes électorales'''
267 289

  
268 290
    mapping = [
269 291
        ('nom_famille', 'Inscription_Electeur_Noms_NomFamille'),
......
359 381

  
360 382

  
361 383
class AECData(Data):
384
    '''Démarche acte d'état civil'''
362 385

  
363 386
    mapping = [
364 387
        ('aec_type_raw', 'DemandeActe_TypeActe_Code'),
......
444 467
        self.root_attributes = {'canal_utilise': '0'}
445 468

  
446 469
        super(AECData, self).__init__(demand_id, data)
447

  
448

  
449
def json_to_xml(path, value, parent):
450

  
451
    if isinstance(path, list) and len(path) > 1:
452
        parent_child = parent.find(path[0])
453
        if parent_child is not None:
454
            element = parent_child
455
            path.pop(0)
456
        else:
457
            element = ElementFactory(path.pop(0))
458

  
459
        element.append(json_to_xml(path, value, element), allow_new=False)
460
    else:
461
        element = ElementFactory(path[0], text=value)
462

  
463
    return element
passerelle/apps/mdel/models.py
1
# -*- coding: utf-8 -*-
2
# Passerelle - uniform access to data and services
1
# coding: utf-8
2
# passerelle - uniform access to data and services
3 3
# Copyright (C) 2016  Entr'ouvert
4 4
#
5 5
# This program is free software: you can redistribute it and/or modify it
......
15 15
# You should have received a copy of the GNU Affero General Public License
16 16
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 17

  
18
from __future__ import unicode_literals
18 19
import os
19 20
import json
20 21

  
21 22
from django.db import models
22 23
from django.utils.translation import ugettext_lazy as _
24
from django.utils import six
23 25

  
24 26
from passerelle.base.models import BaseResource
25 27
from passerelle.utils.api import endpoint
......
101 103

  
102 104
        demand_type = formdata.pop('demand_type', '').upper()
103 105
        if demand_type not in DEMAND_TYPES:
104
            raise APIError('demand_type must be : %r' % DEMAND_TYPES)
106
            raise APIError('demand_type must be one of : %s' % ', '.join(DEMAND_TYPES))
105 107

  
106 108
        if 'display_id' not in formdata:
107 109
            raise APIError('display_id is required')
......
151 153
                if item.get('id') not in without.split(',')]}
152 154

  
153 155

  
156
@six.python_2_unicode_compatible
154 157
class Demand(models.Model):
155 158
    created_at = models.DateTimeField(auto_now_add=True)
156 159
    updated_at = models.DateTimeField(auto_now=True)
......
162 165
    step = models.IntegerField(default=0)
163 166
    demand_id = models.CharField(max_length=128, null=True)
164 167

  
165
    def __unicode__(self):
168
    def __str__(self):
166 169
        return '%s - %s - %s' % (self.resource.slug, self.demand_id, self.status)
167 170

  
168 171
    class Meta:
......
203 206
            for proof_code, proof_attribute in proofs:
204 207

  
205 208
                documents = [value for key, value in formdata.items()
206
                             if key.startswith(proof_attribute) and isinstance(value, dict) and 'filename' in value and 'content' in value]
209
                             if (key.startswith(proof_attribute)
210
                                 and isinstance(value, dict)
211
                                 and 'filename' in value
212
                                 and 'content' in value)]
207 213
                if not documents:
208 214
                    raise APIError('%s and all its attributes are required' % proof_attribute)
209 215
                for document in documents:
passerelle/apps/mdel/utils.py
1
# Passerelle - uniform access to data and services
1
# passerelle - uniform access to data and services
2 2
# Copyright (C) 2016  Entr'ouvert
3 3
#
4 4
# This program is free software: you can redistribute it and/or modify it
......
14 14
# You should have received a copy of the GNU Affero General Public License
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 16

  
17
from __future__ import unicode_literals
18

  
17 19
import os
18 20
import zipfile
19 21
from xml.etree import ElementTree as etree
......
22 24

  
23 25
from passerelle.utils.jsonresponse import APIError
24 26

  
27

  
25 28
def parse_date(date):
26 29
    try:
27 30
        parsed_date = django_parse_date(date)
28 31
    except ValueError as e:
29
        raise APIError('Invalid date: %r (%r)' % ( date, e))
32
        raise APIError('invalid date: %s (%s)' % (date, e))
30 33
    if not parsed_date:
31 34
        raise APIError('date %r not iso-formated' % date)
32 35
    return parsed_date.isoformat()
33 36

  
34 37

  
35 38
class ElementFactory(etree.Element):
36

  
37 39
    def __init__(self, *args, **kwargs):
38 40
        self.text = kwargs.pop('text', None)
39 41
        namespace = kwargs.pop('namespace', None)
......
46 48
            super(ElementFactory, self).__init__(*args, **kwargs)
47 49

  
48 50
    def append(self, element, allow_new=True):
49

  
50 51
        if not allow_new:
51 52
            if isinstance(element.tag, etree.QName):
52 53
                found = self.find(element.tag.text)
53 54
            else:
54 55
                found = self.find(element.tag)
55

  
56 56
            if found is not None:
57 57
                return self
58

  
59 58
        super(ElementFactory, self).append(element)
60 59
        return self
61 60

  
tests/test_mdel.py
109 109
    ILE_PAYLOAD_INVALID = copy.deepcopy(ile_payload)
110 110
    ILE_PAYLOAD_INVALID['extra']['demand_type'] = 'whatever'
111 111
    resp = app.post_json('/mdel/test/create', params=ILE_PAYLOAD_INVALID, status=200)
112
    assert resp.json['err_desc'] == "demand_type must be : ['ILE-LA', 'RCO-LA', 'AEC-LA']"
112
    assert resp.json['err_desc'] == "demand_type must be one of : ILE-LA, RCO-LA, AEC-LA"
113 113

  
114 114

  
115 115
def test_invalid_demand_no_form_number(app, ile_payload):
116
-