Projet

Général

Profil

0001-datasources-avoid-error-500-on-lost-datasource-18431.patch

Nicolas Roche, 10 octobre 2019 09:10

Télécharger (9,91 ko)

Voir les différences:

Subject: [PATCH] datasources: avoid error 500 on lost datasource (#18431)

 tests/test_form_pages.py | 20 ++++++++++++++++++
 wcs/fields.py            | 45 ++++++++++++++++++++++++++++------------
 wcs/formdef.py           |  5 ++++-
 wcs/forms/common.py      |  5 ++++-
 4 files changed, 60 insertions(+), 15 deletions(-)
tests/test_form_pages.py
4238 4238
    resp = resp.forms[0].submit('submit')
4239 4239
    assert 'Check values then click submit.' in resp.body
4240 4240

  
4241
def test_unknown_datasource(pub):
4242
    formdef = create_formdef()
4243
    formdef.fields = [
4244
        fields.StringField(id='1', label='string',
4245
                varname='string', required=False, data_source={'type': 'foobar'}),
4246
        fields.ItemField(id='2', label='item',
4247
                varname='item', required=False, data_source={'type': 'foobar'}),
4248
        fields.ItemsField(id='3', label='items',
4249
                varname='items', required=False, data_source={'type': 'foobar'}),
4250
    ]
4251
    formdef.store()
4252

  
4253
    data_class = formdef.data_class()
4254
    data_class.wipe()
4255

  
4256
    resp = get_app(pub).get('/test/')
4257
    formdef.data_class().wipe()
4258
    resp = resp.forms[0].submit('submit') # should go straight to validation
4259
    assert 'Check values then click submit.' in resp.body
4260

  
4241 4261
def test_form_items_datasource(pub):
4242 4262
    formdef = create_formdef()
4243 4263
    formdef.fields = [fields.ItemsField(id='1', label='items',
wcs/fields.py
574 574
            return [self.convert_value_to_str(element)]
575 575
        return [element]
576 576

  
577
    def call_data_source(self, fonction, **kwargs):
578
        try:
579
            return fonction(self.data_source, **kwargs)
580
        except KeyError as e:
581
            get_logger().warn('%s from %s field on %s form'
582
                              % (e, self.label, self.formdef.name))
583
            return None
584

  
585
    def get_data_source_iter(self, fonction, **kwargs):
586
        try:
587
            return fonction(self.data_source, **kwargs)
588
        except KeyError as e:
589
            get_logger().warn('%s from %s field on %s form'
590
                              % (e, self.label, self.formdef.name))
591
            return []
592

  
577 593
field_classes = []
578 594
field_types = []
579 595

  
......
724 740

  
725 741
    def perform_more_widget_changes(self, form, kwargs, edit=True):
726 742
        if self.data_source:
727
            real_data_source = data_sources.get_real(self.data_source)
743
            real_data_source = self.call_data_source(data_sources.get_real)
744
            if not real_data_source:
745
                return
728 746
            if real_data_source.get('type') == 'jsonp':
729 747
                kwargs['url'] = real_data_source.get('value')
730 748
                self.widget_class = AutocompleteStringWidget
......
1304 1322

  
1305 1323
    def get_options(self, mode=None):
1306 1324
        if self.data_source:
1307
            return [x[:3] for x in data_sources.get_items(self.data_source, mode=mode)]
1325
            return [x[:3] for x in self.get_data_source_iter(data_sources.get_items, mode=mode)]
1308 1326
        if self.items:
1309 1327
            return [(x, x) for x in self.items]
1310 1328
        return []
1311 1329

  
1312 1330
    def perform_more_widget_changes(self, form, kwargs, edit=True):
1313
        data_source = data_sources.get_object(self.data_source)
1331
        data_source = self.call_data_source(data_sources.get_object)
1314 1332

  
1315 1333
        if data_source and data_source.type == 'jsonp':
1316 1334
            # a source defined as JSONP can only be used in autocomplete mode
......
1324 1342
        if self.items:
1325 1343
            kwargs['options'] = self.get_options()
1326 1344
        elif self.data_source:
1327
            items = data_sources.get_items(self.data_source,
1345
            items = self.get_data_source_iter(data_sources.get_items,
1328 1346
                    include_disabled=self.display_disabled_items)
1329 1347
            kwargs['options'] = [x[:3] for x in items if not x[-1].get('disabled')]
1330 1348
            kwargs['options_with_attributes'] = items[:]
......
1346 1364
            kwargs['select2'] = True
1347 1365

  
1348 1366
    def get_display_value(self, value):
1349
        data_source = data_sources.get_object(self.data_source)
1367
        data_source = self.call_data_source(data_sources.get_object)
1350 1368
        if data_source is None:
1351 1369
            return value or ''
1352 1370

  
......
1378 1396

  
1379 1397
    def store_display_value(self, data, field_id):
1380 1398
        value = data.get(field_id)
1381
        data_source = data_sources.get_object(self.data_source)
1399
        data_source = self.call_data_source(data_sources.get_object)
1382 1400
        if data_source and data_source.type == 'jsonp':
1383 1401
            if get_request():
1384 1402
                display_value = get_request().form.get('f%s_display' % field_id)
......
1397 1415
        return self.get_display_value(value)
1398 1416

  
1399 1417
    def store_structured_value(self, data, field_id):
1400
        data_source = data_sources.get_object(self.data_source)
1418
        data_source = self.call_data_source(data_sources.get_object)
1401 1419
        if data_source is None:
1402 1420
            return
1403 1421

  
......
1454 1472
        return item_items_stats(self, values)
1455 1473

  
1456 1474
    def feed_session(self, value, display_value):
1457
        real_data_source = data_sources.get_real(self.data_source)
1475
        real_data_source = self.call_data_source(data_sources.get_real)
1458 1476
        if real_data_source and real_data_source.get('type') == 'jsonp':
1459 1477
            if not get_session().jsonp_display_values:
1460 1478
                get_session().jsonp_display_values = {}
......
1476 1494
    def export_to_json(self, include_id=False, anonymise=True):
1477 1495
        field = super(ItemField, self).export_to_json(include_id=include_id, anonymise=anonymise)
1478 1496
        if self.data_source and not anonymise:
1479
            structured_items = data_sources.get_structured_items(self.data_source)
1497
            structured_items = self.call_data_source(data_sources.get_structured_items)
1480 1498
            if structured_items:
1481 1499
                field['structured_items'] = structured_items
1482 1500
                if not field.get('items'):
......
1509 1527
        if self.data_source:
1510 1528
            if self._cached_data_source:
1511 1529
                return self._cached_data_source
1512
            self._cached_data_source = [x[:3] for x in data_sources.get_items(self.data_source)]
1530
            self._cached_data_source = [x[:3]
1531
                    for x in self.get_data_source_iter(data_sources.get_items)]
1513 1532
            return self._cached_data_source[:]
1514 1533
        elif self.items:
1515 1534
            return [(x, x) for x in self.items]
......
1520 1539
        kwargs['options'] = self.get_options()
1521 1540
        kwargs['max_choices'] = self.max_choices
1522 1541
        if self.data_source:
1523
            items = data_sources.get_items(self.data_source,
1542
            items = self.get_data_source_iter(data_sources.get_items,
1524 1543
                    include_disabled=self.display_disabled_items)
1525 1544
            kwargs['options'] = [x[:3] for x in items if not x[-1].get('disabled')]
1526 1545
            kwargs['options_with_attributes'] = items[:]
......
1634 1653
        value = data.get(field_id)
1635 1654
        if not self.data_source:
1636 1655
            return
1637
        structured_options = data_sources.get_structured_items(self.data_source)
1656
        structured_options = self.call_data_source(data_sources.get_structured_items)
1638 1657
        if not structured_options:
1639 1658
            return
1640 1659
        if not set(structured_options[0].keys()) != set(['id', 'text']):
......
1649 1668
    def export_to_json(self, include_id=False, anonymise=True):
1650 1669
        field = super(ItemsField, self).export_to_json(include_id=include_id, anonymise=True)
1651 1670
        if self.data_source and not anonymise:
1652
            structured_items = data_sources.get_structured_items(self.data_source)
1671
            structured_items = self.call_data_source(data_sources.get_structured_items)
1653 1672
            if structured_items:
1654 1673
                field['structured_items'] = structured_items
1655 1674
                if not field.get('items'):
wcs/formdef.py
667 667
                        live_condition_fields[varname] = []
668 668
                    live_condition_fields[varname].append(field)
669 669
            if field.key == 'item' and field.data_source:
670
                real_data_source = data_sources.get_real(field.data_source)
670
                try:
671
                    real_data_source = data_sources.get_real(field.data_source)
672
                except KeyError as e:
673
                    continue
671 674
                if real_data_source.get('type') != 'json':
672 675
                    continue
673 676
                varnames = field.get_referenced_varnames(
wcs/forms/common.py
651 651

  
652 652
        for field in displayed_fields:
653 653
            if field.key == 'item' and field.data_source:
654
                data_source = data_sources.get_object(field.data_source)
654
                try:
655
                    data_source = data_sources.get_object(field.data_source)
656
                except KeyError as e:
657
                    continue
655 658
                if data_source.type != 'json':
656 659
                    continue
657 660
                varnames = field.get_referenced_varnames(
658
-