Projet

Général

Profil

0001-add-possibility-to-create-a-formdef-object-from-a-js.patch

Frédéric Péters, 29 août 2014 14:14

Télécharger (11,3 ko)

Voir les différences:

Subject: [PATCH] add possibility to create a formdef object from a json value
 (#5348)

 tests/test_formdef_import.py |  39 ++++++++++++++---
 wcs/fields.py                |  27 ++++--------
 wcs/formdef.py               | 102 +++++++++++++++++++++++++++++++++++++------
 3 files changed, 130 insertions(+), 38 deletions(-)
tests/test_formdef_import.py
22 22
def teardown_module(module):
23 23
    shutil.rmtree(pub.APP_DIR)
24 24

  
25
def assert_import_export_works(formdef, include_id=False):
25
def assert_xml_import_export_works(formdef, include_id=False):
26 26
    formdef2 = FormDef.import_from_xml_tree(
27 27
            formdef.export_to_xml(include_id=include_id), include_id=include_id)
28 28
    assert ET.tostring(indent(formdef.export_to_xml(include_id=include_id))
29 29
            ) == ET.tostring(indent(formdef2.export_to_xml(include_id=include_id)))
30 30
    return formdef2
31 31

  
32
def assert_json_import_export_works(formdef, include_id=False):
33
    formdef2 = FormDef.import_from_json(
34
            StringIO.StringIO(formdef.export_to_json(include_id=include_id)), include_id=include_id)
35
    assert ET.tostring(indent(formdef.export_to_xml(include_id=include_id))
36
            ) == ET.tostring(indent(formdef2.export_to_xml(include_id=include_id)))
37
    return formdef2
38

  
32 39
def test_empty():
33 40
    formdef = FormDef()
34 41
    formdef.name = 'empty'
35
    assert_import_export_works(formdef)
42
    assert_xml_import_export_works(formdef)
43
    assert_json_import_export_works(formdef)
36 44

  
37 45
def test_text_attributes():
38 46
    formdef = FormDef()
39 47
    formdef.name = 'Foo'
40 48
    formdef.url_name = 'foo'
41
    f2 = assert_import_export_works(formdef)
49
    f2 = assert_xml_import_export_works(formdef)
50
    assert f2.url_name == formdef.url_name
51
    f2 = assert_json_import_export_works(formdef)
42 52
    assert f2.url_name == formdef.url_name
43 53

  
44 54
def test_boolean_attributes():
......
47 57
    formdef.url_name = 'foo'
48 58
    formdef.confirmation = True
49 59
    formdef.allow_drafts = True
50
    f2 = assert_import_export_works(formdef)
60
    f2 = assert_xml_import_export_works(formdef)
61
    assert f2.allow_drafts == formdef.allow_drafts
62
    assert f2.confirmation == formdef.confirmation
63
    f2 = assert_json_import_export_works(formdef)
51 64
    assert f2.allow_drafts == formdef.allow_drafts
52 65
    assert f2.confirmation == formdef.confirmation
53 66

  
......
57 70
    formdef.fields = [
58 71
            fields.StringField(type='string', id=1, label='Bar', size=40)
59 72
            ]
60
    f2 = assert_import_export_works(formdef)
73
    f2 = assert_xml_import_export_works(formdef)
74
    assert len(f2.fields) == len(formdef.fields)
75
    f2 = assert_json_import_export_works(formdef)
61 76
    assert len(f2.fields) == len(formdef.fields)
62 77

  
63 78
def test_more_fields():
......
70 85
            fields.DateField(type='date', label='Bar', minimum_date='2014-01-01'),
71 86
            fields.ItemField(type='item', label='Bar', items=['foo', 'bar', 'baz']),
72 87
            ]
73
    f2 = assert_import_export_works(formdef)
88
    f2 = assert_xml_import_export_works(formdef)
89
    assert len(f2.fields) == len(formdef.fields)
90
    assert f2.fields[2].type == formdef.fields[2].type
91
    assert f2.fields[3].minimum_date == formdef.fields[3].minimum_date
92
    assert f2.fields[4].items == formdef.fields[4].items
93

  
94
    f2 = assert_json_import_export_works(formdef)
74 95
    assert len(f2.fields) == len(formdef.fields)
75 96
    assert f2.fields[2].type == formdef.fields[2].type
76 97
    assert f2.fields[3].minimum_date == formdef.fields[3].minimum_date
......
89 110
    for field in formdef.fields:
90 111
        field.id = formdef.get_new_field_id()
91 112
    formdef.fields[4].id = '10'
92
    f2 = assert_import_export_works(formdef, include_id=True)
113
    f2 = assert_xml_import_export_works(formdef, include_id=True)
93 114
    assert len(f2.fields) == len(formdef.fields)
94 115
    assert f2.fields[0].id == formdef.fields[0].id
95 116
    assert f2.fields[4].id == formdef.fields[4].id
96 117

  
118
    f2 = assert_json_import_export_works(formdef, include_id=True)
119
    assert len(f2.fields) == len(formdef.fields)
120
    assert f2.fields[0].id == formdef.fields[0].id
121
    assert f2.fields[4].id == formdef.fields[4].id
wcs/fields.py
125 125
    def get_admin_attributes(self):
126 126
        return ['label', 'type']
127 127

  
128
    def export_to_json(self, charset, include_id=False):
128
    def export_to_json(self, include_id=False):
129 129
        field = {}
130 130
        if include_id:
131 131
            extra_fields = ['id']
......
136 136
                continue
137 137
            if hasattr(self, attribute) and getattr(self, attribute) is not None:
138 138
                val = getattr(self, attribute)
139
                if type(val) is dict:
140
                    if not val: continue
141
                    field[attribute] = {}
142
                    for k, v in val.items():
143
                        field[attribute][k] = unicode(v, charset, 'replace')
144
                elif type(val) is list:
145
                    if not val: continue
146
                    field[attribute] = []
147
                    for v in val:
148
                        field[attribute].append(unicode(v, charset, 'replace'))
149
                elif type(val) in (str, unicode):
150
                    if type(val) is unicode:
151
                        field[attribute] = val
152
                    else:
153
                        field[attribute] = unicode(val, charset, 'replace')
154
                else:
155
                    field[attribute] = str(val)
139
                field[attribute] = val
156 140
        return field
157 141

  
142
    def init_with_json(self, elem, include_id=False):
143
        if include_id:
144
            self.id = elem.get('id')
145
        for attribute in self.get_admin_attributes():
146
            if attribute in elem:
147
                setattr(self, attribute, elem.get(attribute))
148

  
158 149
    def export_to_xml(self, charset, include_id=False):
159 150
        field = ET.Element('field')
160 151
        if include_id:
wcs/formdef.py
82 82

  
83 83

  
84 84
    # declarations for serialization
85
    TEXT_ATTRIBUTES = ('name', 'url_name',
86
            'publication_date', 'expiration_date')
87
    BOOLEAN_ATTRIBUTES = ('discussion', 'detailed_emails', 'disabled',
85
    TEXT_ATTRIBUTES = ['name', 'url_name',
86
            'publication_date', 'expiration_date']
87
    BOOLEAN_ATTRIBUTES = ['discussion', 'detailed_emails', 'disabled',
88 88
            'only_allow_one', 'allow_drafts', 'disabled_redirection',
89
            'always_advertise', 'private_status_and_history')
89
            'always_advertise', 'private_status_and_history']
90 90

  
91 91
    def migrate(self):
92 92
        changed = False
......
390 390
        charset = get_publisher().site_charset
391 391
        root = {}
392 392
        root['name'] = unicode(self.name, charset)
393
        if include_id and self.id:
394
            root['id'] = str(self.id)
393 395
        if self.category:
394 396
            root['category'] = unicode(self.category.name, charset)
395
        for boolean_attribute in self.BOOLEAN_ATTRIBUTES:
396
            value = getattr(self, boolean_attribute)
397
            if value:
398
                value = 'true'
399
            else:
400
                value = 'false'
401
            root[boolean_attribute] = value
397
            root['category_id'] = str(self.category.id)
398
        if self.workflow:
399
            root['workflow'] = unicode(self.workflow.name, charset)
400
            root['workflow_id'] = str(self.workflow.id)
401

  
402
        more_attributes = []
403
        if self.max_field_id:
404
            more_attributes.append('max_field_id')
405
        if self.last_modification_time:
406
            more_attributes.append('last_modification_time')
407
            if include_id:
408
                more_attributes.append('last_modification_user_id')
409

  
410
        for attribute in self.TEXT_ATTRIBUTES + self.BOOLEAN_ATTRIBUTES + more_attributes:
411
            if not hasattr(self, attribute):
412
                continue
413
            root[attribute] = getattr(self, attribute)
414

  
402 415
        root['fields'] = []
403
        for field in self.fields:
404
            root['fields'].append(field.export_to_json(charset=charset, include_id=include_id))
416
        if self.fields:
417
            for field in self.fields:
418
                root['fields'].append(field.export_to_json(include_id=include_id))
405 419

  
406 420
        return json.dumps(root)
407 421

  
422
    def import_from_json(cls, fd, charset=None, include_id=False):
423
        if charset is None:
424
            charset = get_publisher().site_charset
425
        formdef = cls()
426

  
427
        def unicode2str(v):
428
            if isinstance(v, dict):
429
                return dict([(unicode2str(k), unicode2str(v)) for k, v in v.items()])
430
            elif isinstance(v, list):
431
                return [unicode2str(x) for x in v]
432
            elif isinstance(v, unicode):
433
                return v.encode(charset)
434
            else:
435
                return v
436

  
437
        # we have to make sure all strings are str object, not unicode.
438
        value = unicode2str(json.load(fd))
439

  
440
        if include_id and 'id' in value:
441
            formdef.id = value.get('id')
442

  
443
        if include_id and 'category_id' in value:
444
            formdef.category_id = value.get('category_id')
445
        elif 'category' in value:
446
            category = value.get('category')
447
            for c in Category.select():
448
                if c.name == category:
449
                    formdef.category_id = c.id
450
                    break
451

  
452
        if include_id and 'workflow_id' in value:
453
            formdef.workflow_id = value.get('workflow_id')
454
        elif 'workflow' in value:
455
            workflow = value.get('workflow')
456
            for w in Workflow.select():
457
                if w.name == workflow:
458
                    formdef.workflow_id = w.id
459
                    break
460

  
461
        more_attributes = ['max_field_id', 'last_modification_time',
462
                'last_modification_user_id']
463
        for attribute in cls.TEXT_ATTRIBUTES + cls.BOOLEAN_ATTRIBUTES + more_attributes:
464
            setattr(formdef, attribute, value.get(attribute))
465

  
466
        formdef.fields = []
467
        for i, field in enumerate(value.get('fields', [])):
468
            try:
469
                field_o = fields.get_field_class_by_type(field.get('type'))()
470
            except KeyError:
471
                raise ValueError()
472
            field_o.init_with_json(field, include_id=include_id)
473
            if not field_o.id:
474
                # this assumes all fields will have id, or none of them
475
                field_o.id = str(i)
476
            formdef.fields.append(field_o)
477

  
478
        if formdef.fields and not formdef.max_field_id:
479
            formdef.max_field_id = max([lax_int(x.id) for x in formdef.fields])+1
480

  
481
        return formdef
482
    import_from_json = classmethod(import_from_json)
483

  
408 484
    def export_to_xml(self, include_id=False):
409 485
        charset = get_publisher().site_charset
410 486
        root = ET.Element('formdef')
411
-