From ed4aaf862a80244d965ad279597e9e09084a2944 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Tue, 23 Feb 2016 15:17:23 +0100 Subject: [PATCH] api: handle submit of forms with date, file and map fields (#10059) --- tests/test_api.py | 12 ++++++++++++ wcs/api.py | 7 +++++++ wcs/fields.py | 25 +++++++++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/tests/test_api.py b/tests/test_api.py index e4e9f0e..158a186 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -440,6 +440,8 @@ def test_formdef_submit_with_varname(pub, local_user): data_source={'type': 'foobar'}), fields.ItemField(id='2', label='foobar2', varname='foobar2', data_source={'type': 'foobar_jsonp'}), + fields.DateField(id='3', label='foobar3', varname='date'), + fields.FileField(id='4', label='foobar4', varname='file'), ] formdef.store() data_class = formdef.data_class() @@ -462,6 +464,11 @@ def test_formdef_submit_with_varname(pub, local_user): }, 'foobar2': 'bar', 'foobar2_raw': '10', + 'date': '1970-01-01', + 'file': { + 'filename': 'test.txt', + 'content': base64.b64encode('test'), + }, } }) assert resp.json['err'] == 0 @@ -473,6 +480,11 @@ def test_formdef_submit_with_varname(pub, local_user): assert data_class.get(resp.json['data']['id']).data['1_structured'] == source[0] assert data_class.get(resp.json['data']['id']).data['2'] == '10' assert data_class.get(resp.json['data']['id']).data['2_display'] == 'bar' + assert data_class.get(resp.json['data']['id']).data['3'] == time.struct_time((1970, 1, 1, 0, 0, + 0, 3, 1, -1)) + + assert data_class.get(resp.json['data']['id']).data['4'].orig_filename == 'test.txt' + assert data_class.get(resp.json['data']['id']).data['4'].get_content() == 'test' data_class.wipe() diff --git a/wcs/api.py b/wcs/api.py index 3617452..6fb723c 100644 --- a/wcs/api.py +++ b/wcs/api.py @@ -243,6 +243,13 @@ class ApiFormdefDirectory(Directory): data[field.id] = data.pop(field.varname) if field.store_structured_value and structured in data: data['%s_structured' % field.id] = data.pop(structured) + # parse special fields + for field in self.formdef.fields: + if not hasattr(field, 'from_json_value'): + continue + if not field.id in data: + continue + data[field.id] = field.from_json_value(data[field.id]) formdata.data = json_input['data'] meta = json_input.get('meta') or {} if meta.get('backoffice-submission'): diff --git a/wcs/fields.py b/wcs/fields.py index e0e4395..fcc448e 100644 --- a/wcs/fields.py +++ b/wcs/fields.py @@ -763,6 +763,19 @@ class FileField(WidgetField): 'content': base64.b64encode(value.get_content()) } + def from_json_value(self, value): + if 'filename' in value and 'content' in value: + content = base64.b64decode(value['content']) + content_type = value.get('content_type', 'application/octet-stream') + if content_type.startswith('text/'): + charset = 'utf-8' + else: + charset = None + upload = PicklableUpload(value['filename'], content_type, charset) + upload.receive([content]) + return upload + return None + def perform_more_widget_changes(self, form, kwargs, edit = True): if not edit: value = get_request().get_field(self.field_key) @@ -915,6 +928,12 @@ class DateField(WidgetField): except TypeError: return '' + def from_json_value(self, value): + try: + return time.strptime(value, '%Y-%m-%d') + except (TypeError, ValueError): + return None + register_field_class(DateField) @@ -1756,6 +1775,12 @@ class MapField(WidgetField): return None return {'lat': lat, 'lon': lon} + def from_json_value(self, value): + if 'lat' in value and 'lon' in value: + return '%s;%s' % (value['lat'], value['lon']) + else: + return None + register_field_class(MapField) -- 2.1.4