0001-general-switch-map-field-value-to-be-a-dictionary-46.patch
tests/test_admin_pages.py | ||
---|---|---|
3044 | 3044 |
resp = resp.click('Geolocation') |
3045 | 3045 |
assert 'value="1.234;-1.234' in resp.text |
3046 | 3046 |
pub.reload_cfg() |
3047 |
assert pub.cfg['misc']['default-position'] == '1.234;-1.234'
|
|
3047 |
assert pub.cfg['misc']['default-position'] == {'lat': 1.234, 'lon': -1.234}
|
|
3048 | 3048 | |
3049 | 3049 | |
3050 | 3050 |
def test_wscalls_new(pub): |
tests/test_api.py | ||
---|---|---|
854 | 854 | |
855 | 855 |
assert data_class.get(resp.json['data']['id']).data['4'].orig_filename == 'test.txt' |
856 | 856 |
assert data_class.get(resp.json['data']['id']).data['4'].get_content() == b'test' |
857 |
assert data_class.get(resp.json['data']['id']).data['5'] == '1.5;2.25'
|
|
857 |
assert data_class.get(resp.json['data']['id']).data['5'] == {'lat': 1.5, 'lon': 2.25}
|
|
858 | 858 |
# test bijectivity |
859 | 859 |
assert (formdef.fields[3].get_json_value(data_class.get(resp.json['data']['id']).data['3']) == |
860 | 860 |
payload['data']['date']) |
... | ... | |
900 | 900 |
'2_display': 'bar', |
901 | 901 |
'3': time.strptime('1970-01-01', '%Y-%m-%d'), |
902 | 902 |
'4': upload, |
903 |
'5': '1.5;2.25', |
|
904 | 903 |
'bo1': 'backoffice field', |
905 | 904 |
} |
906 | 905 |
formdata.just_created() |
907 | 906 |
formdata.evolution[-1].status = 'wf-new' |
908 | 907 |
formdata.store() |
909 | 908 | |
910 |
payload = json.loads( |
|
911 |
json.dumps(formdata.get_json_export_dict(), |
|
912 |
cls=qommon.misc.JSONEncoder)) |
|
913 |
signed_url = sign_url('http://example.net/api/formdefs/test/submit?orig=coucou', '1234') |
|
914 |
url = signed_url[len('http://example.net'):] |
|
915 | ||
916 |
resp = get_app(pub).post_json(url, payload) |
|
917 |
assert resp.json['err'] == 0 |
|
918 |
new_formdata = formdef.data_class().get(resp.json['data']['id']) |
|
919 |
assert new_formdata.data['0'] == formdata.data['0'] |
|
920 |
assert new_formdata.data['1'] == formdata.data['1'] |
|
921 |
assert new_formdata.data['1_display'] == formdata.data['1_display'] |
|
922 |
assert new_formdata.data['1_structured'] == formdata.data['1_structured'] |
|
923 |
assert new_formdata.data['2'] == formdata.data['2'] |
|
924 |
assert new_formdata.data['2_display'] == formdata.data['2_display'] |
|
925 |
assert new_formdata.data['3'] == formdata.data['3'] |
|
926 |
assert new_formdata.data['4'].get_content() == formdata.data['4'].get_content() |
|
927 |
assert new_formdata.data['5'] == formdata.data['5'] |
|
928 |
assert new_formdata.data['bo1'] == formdata.data['bo1'] |
|
929 |
assert not new_formdata.data.get('6') |
|
930 |
assert new_formdata.user_id is None |
|
909 |
for map_value in ('1.5;2.25', {'lat': 1.5, 'lon': 2.25}): |
|
910 |
formdata.data['5'] = map_value |
|
911 | ||
912 |
payload = json.loads( |
|
913 |
json.dumps(formdata.get_json_export_dict(), |
|
914 |
cls=qommon.misc.JSONEncoder)) |
|
915 |
signed_url = sign_url('http://example.net/api/formdefs/test/submit?orig=coucou', '1234') |
|
916 |
url = signed_url[len('http://example.net'):] |
|
917 | ||
918 |
resp = get_app(pub).post_json(url, payload) |
|
919 |
assert resp.json['err'] == 0 |
|
920 |
new_formdata = formdef.data_class().get(resp.json['data']['id']) |
|
921 |
assert new_formdata.data['0'] == formdata.data['0'] |
|
922 |
assert new_formdata.data['1'] == formdata.data['1'] |
|
923 |
assert new_formdata.data['1_display'] == formdata.data['1_display'] |
|
924 |
assert new_formdata.data['1_structured'] == formdata.data['1_structured'] |
|
925 |
assert new_formdata.data['2'] == formdata.data['2'] |
|
926 |
assert new_formdata.data['2_display'] == formdata.data['2_display'] |
|
927 |
assert new_formdata.data['3'] == formdata.data['3'] |
|
928 |
assert new_formdata.data['4'].get_content() == formdata.data['4'].get_content() |
|
929 |
assert new_formdata.data['5'] == {'lat': 1.5, 'lon': 2.25} |
|
930 |
assert new_formdata.data['bo1'] == formdata.data['bo1'] |
|
931 |
assert not new_formdata.data.get('6') |
|
932 |
assert new_formdata.user_id is None |
|
931 | 933 | |
932 | 934 |
# add an extra attribute |
933 | 935 |
payload['extra'] = {'foobar6': 'YYY'} |
tests/test_backoffice_pages.py | ||
---|---|---|
6381 | 6381 |
"will be ignored - type File Upload not supported," |
6382 | 6382 |
"foo@example.com," |
6383 | 6383 |
"value," |
6384 |
"value\r\n" % (pub.get_default_position(), today)) |
|
6384 |
"value\r\n" % ( |
|
6385 |
'%(lat)s;%(lon)s' % pub.get_default_position(), |
|
6386 |
today)) |
|
6385 | 6387 | |
6386 | 6388 |
resp.forms[0]['file'] = Upload('test.csv', b'\0', 'text/csv') |
6387 | 6389 |
resp = resp.forms[0].submit() |
... | ... | |
6409 | 6411 |
assert 'Column File will be ignored: type File Upload not supported.' in resp |
6410 | 6412 |
assert carddef.data_class().count() == 149 |
6411 | 6413 |
card1, card2 = carddef.data_class().select(order_by='id')[:2] |
6412 |
assert card1.data['1'] == '48.81;2.37'
|
|
6414 |
assert card1.data['1'] == {'lat': 48.81, 'lon': 2.37}
|
|
6413 | 6415 |
assert card1.data['2'] == 'data1' |
6414 | 6416 |
assert card1.data['3'] is True |
6415 | 6417 |
assert card1.data['5'].tm_mday == 2 |
tests/test_fields.py | ||
---|---|---|
313 | 313 | |
314 | 314 | |
315 | 315 |
def test_map(): |
316 |
assert fields.MapField().get_json_value('42.2;10.2') == {'lat': 42.2, 'lon': 10.2} |
|
317 |
assert fields.MapField().get_json_value('-42.2;10.2') == {'lat': -42.2, 'lon': 10.2} |
|
318 |
assert fields.MapField().get_json_value(' 42.2 ; 10.2 ') == {'lat': 42.2, 'lon': 10.2} |
|
319 |
assert fields.MapField().get_json_value('') == None |
|
320 |
assert fields.MapField().get_json_value('foobar') == None |
|
316 |
assert fields.MapField().get_json_value({'lat': 42.2, 'lon': 10.2}) == {'lat': 42.2, 'lon': 10.2} |
|
317 |
assert fields.MapField().get_json_value({'lat': -42.2, 'lon': 10.2}) == {'lat': -42.2, 'lon': 10.2} |
|
318 |
assert fields.MapField().get_json_value(None) is None |
|
321 | 319 | |
322 | 320 | |
323 | 321 |
def test_item_render(): |
tests/test_form_pages.py | ||
---|---|---|
4427 | 4427 |
assert formdef.data_class().count() == 1 |
4428 | 4428 |
data_id = formdef.data_class().select()[0].id |
4429 | 4429 |
data = formdef.data_class().get(data_id) |
4430 |
assert data.data == {'1': 'bla', '0': '1.234;-1.234'} |
|
4430 |
assert data.data == {'0': {'lat': 1.234, 'lon': -1.234}, '1': 'bla'} |
|
4431 | ||
4432 | ||
4433 |
def test_map_field_migration(pub): |
|
4434 |
if pub.is_using_postgresql(): |
|
4435 |
pytest.skip('this is not relevant in SQL mode') |
|
4436 |
return |
|
4437 | ||
4438 |
user = create_user(pub) |
|
4439 |
formdef = create_formdef() |
|
4440 |
formdef.data_class().wipe() |
|
4441 |
formdef.fields = [fields.MapField(id='0', label='map', type='map')] |
|
4442 |
formdef.store() |
|
4443 |
formdata = formdef.data_class()() |
|
4444 |
formdata.user_id = user.id |
|
4445 |
formdata.data = {'0': '1;2'} # legacy data type |
|
4446 |
formdata.just_created() |
|
4447 |
formdata.store() |
|
4448 | ||
4449 |
app = login(get_app(pub), username='foo', password='foo') |
|
4450 |
resp = app.get(formdata.get_url()) |
|
4451 |
assert 'data-init-lat="1"' in resp |
|
4452 |
assert 'data-init-lng="2"' in resp |
|
4431 | 4453 | |
4432 | 4454 | |
4433 | 4455 |
def test_form_map_field_prefill_address(pub): |
... | ... | |
4475 | 4497 |
assert formdef.data_class().count() == 1 |
4476 | 4498 |
data_id = formdef.data_class().select()[0].id |
4477 | 4499 |
data = formdef.data_class().get(data_id) |
4478 |
assert data.data == {'1': '1.234;-1.234', '3': 'bar'}
|
|
4500 |
assert data.data == {'1': {'lat': 1.234, 'lon': -1.234}, '3': 'bar'}
|
|
4479 | 4501 | |
4480 | 4502 | |
4481 | 4503 |
def test_form_middle_session_change(pub): |
tests/test_formdata.py | ||
---|---|---|
614 | 614 |
'4_display': 'aa, ac', |
615 | 615 |
'5': PicklableUpload('test.txt', 'text/plain'), |
616 | 616 |
'6': 'other', |
617 |
'7': '2;4', # map
|
|
617 |
'7': {'lat': 2, 'lon': 4}, # map
|
|
618 | 618 |
'8': time.strptime('2018-08-31', '%Y-%m-%d'), |
619 | 619 |
'9': '2018-07-31', |
620 | 620 |
'10': '3', |
... | ... | |
1120 | 1120 |
pub.substitutions.reset() |
1121 | 1121 |
pub.substitutions.feed(formdef) |
1122 | 1122 |
with pub.substitutions.temporary_feed(formdata, force_mode=mode): |
1123 |
assert WorkflowStatusItem.compute('=form_var_map', raises=True) == '2;4'
|
|
1123 |
assert WorkflowStatusItem.compute('=form_var_map["lat"]', raises=True) == 2
|
|
1124 | 1124 |
assert WorkflowStatusItem.compute('{{ form_var_map }}', raises=True) == '2;4' |
1125 |
assert WorkflowStatusItem.compute('=form_var_map.split(";")[0]', raises=True) == '2' |
|
1126 | 1125 |
assert WorkflowStatusItem.compute('{{ form_var_map|split:";"|first }}', raises=True) == '2' |
1127 | 1126 |
assert WorkflowStatusItem.compute('=form_var_map_lat', raises=True) == 2 |
1128 |
assert WorkflowStatusItem.compute('{{ form_var_map_lat }}', raises=True) == '2.0'
|
|
1127 |
assert WorkflowStatusItem.compute('{{ form_var_map_lat }}', raises=True) == '2' |
|
1129 | 1128 |
assert WorkflowStatusItem.compute('=form_var_map_lon', raises=True) == 4 |
1130 |
assert WorkflowStatusItem.compute('{{ form_var_map_lon }}', raises=True) == '4.0'
|
|
1129 |
assert WorkflowStatusItem.compute('{{ form_var_map_lon }}', raises=True) == '4' |
|
1131 | 1130 | |
1132 | 1131 |
assert WorkflowStatusItem.compute('{{ form_var_map|distance:form_var_map|floatformat }}', raises=True) == '0' |
1133 | 1132 |
assert WorkflowStatusItem.compute('{{ form_var_map|distance:"2.1;4.1"|floatformat }}', raises=True) == '15685.4' |
tests/test_publisher.py | ||
---|---|---|
158 | 158 | |
159 | 159 | |
160 | 160 |
def test_get_default_position(): |
161 |
assert pub.get_default_position() == '50.84;4.36'
|
|
161 |
assert pub.get_default_position() == {'lat': 50.84, 'lon': 4.36}
|
|
162 | 162 | |
163 | 163 | |
164 | 164 |
def test_import_config_zip(): |
tests/test_sql.py | ||
---|---|---|
2063 | 2063 |
assert sql.SqlUser.count() == 2 |
2064 | 2064 |
assert sql.SqlUser.get(id=user.id).is_active is False |
2065 | 2065 |
assert sql.SqlUser.get(id=user2.id).is_active is True |
2066 | ||
2067 | ||
2068 |
@postgresql |
|
2069 |
def test_migration_43_map_data_type(): |
|
2070 |
formdef = FormDef() |
|
2071 |
formdef.name = 'test map migration' |
|
2072 |
formdef.fields = [ |
|
2073 |
fields.MapField(id='1', label='map', type='map'), |
|
2074 |
] |
|
2075 |
formdef.store() |
|
2076 | ||
2077 |
formdata1 = formdef.data_class(mode='sql')() |
|
2078 |
formdata1.just_created() |
|
2079 |
formdata1.store() |
|
2080 | ||
2081 |
formdata2 = formdef.data_class(mode='sql')() |
|
2082 |
formdata2.just_created() |
|
2083 |
formdata2.store() |
|
2084 | ||
2085 |
formdata3 = formdef.data_class(mode='sql')() |
|
2086 |
formdata3.just_created() |
|
2087 |
formdata3.store() |
|
2088 | ||
2089 |
conn, cur = sql.get_connection_and_cursor() |
|
2090 |
cur.execute('UPDATE wcs_meta SET value = 42 WHERE key = %s', ('sql_level',)) |
|
2091 |
conn.commit() |
|
2092 |
cur.close() |
|
2093 | ||
2094 |
conn, cur = sql.get_connection_and_cursor() |
|
2095 |
cur.execute('ALTER TABLE %s DROP COLUMN f1 CASCADE' % sql.get_formdef_table_name(formdef)) |
|
2096 |
cur.execute('ALTER TABLE %s ADD COLUMN f1 VARCHAR' % sql.get_formdef_table_name(formdef)) |
|
2097 |
cur.execute('UPDATE ' + sql.get_formdef_table_name(formdef) + ' SET f1 = %s WHERE id = %s', ('1;2', formdata1.id)) |
|
2098 |
cur.execute('UPDATE ' + sql.get_formdef_table_name(formdef) + ' SET f1 = %s WHERE id = %s', ('', formdata2.id)) |
|
2099 |
cur.execute('UPDATE ' + sql.get_formdef_table_name(formdef) + ' SET f1 = %s WHERE id = %s', (None, formdata3.id)) |
|
2100 |
conn.commit() |
|
2101 |
cur.close() |
|
2102 | ||
2103 |
sql.migrate() |
|
2104 | ||
2105 |
conn, cur = sql.get_connection_and_cursor() |
|
2106 |
assert migration_level(cur) >= 43 |
|
2107 |
conn.commit() |
|
2108 |
cur.close() |
|
2109 | ||
2110 |
assert formdef.data_class(mode='sql').get(formdata1.id).data['1'] == {'lat': 1, 'lon': 2} |
|
2111 |
assert formdef.data_class(mode='sql').get(formdata2.id).data['1'] is None |
|
2112 |
assert formdef.data_class(mode='sql').get(formdata3.id).data['1'] is None |
tests/test_widgets.py | ||
---|---|---|
970 | 970 |
widget = MapWidget('test', title='Map') |
971 | 971 |
mock_form_submission(req, widget, hidden_html_vars={'test$latlng': '1.23;2.34'}) |
972 | 972 |
assert not widget.has_error() |
973 |
assert widget.parse() == '1.23;2.34'
|
|
973 |
assert widget.parse() == {'lat': 1.23, 'lon': 2.34}
|
|
974 | 974 | |
975 | 975 |
assert '<label' in str(widget.render()) |
976 | 976 |
assert not '<label ' in str(widget.render_widget_content()) |
tests/test_workflows.py | ||
---|---|---|
2964 | 2964 |
formdef.store() |
2965 | 2965 | |
2966 | 2966 |
formdata = formdef.data_class()() |
2967 |
formdata.data = {'2': '48.8337085;2.3233693'}
|
|
2967 |
formdata.data = {'2': {'lat': 48.8337085, 'lon': 2.3233693}}
|
|
2968 | 2968 |
formdata.just_created() |
2969 | 2969 |
formdata.store() |
2970 | 2970 |
pub.substitutions.feed(formdata) |
... | ... | |
2994 | 2994 |
formdef.store() |
2995 | 2995 | |
2996 | 2996 |
formdata = formdef.data_class()() |
2997 |
formdata.data = {'2': '48.8337085;2.3233693'}
|
|
2997 |
formdata.data = {'2': {'lat': 48.8337085, 'lon': 2.3233693}}
|
|
2998 | 2998 |
formdata.just_created() |
2999 | 2999 |
formdata.store() |
3000 | 3000 |
pub.substitutions.feed(formdata) |
... | ... | |
3007 | 3007 |
assert int(formdata.geolocations['base']['lat']) == 48 |
3008 | 3008 |
assert int(formdata.geolocations['base']['lon']) == 2 |
3009 | 3009 | |
3010 |
formdata.data = {'2': '48.8337085;3.3233693'}
|
|
3010 |
formdata.data = {'2': {'lat': 48.8337085, 'lon': 3.3233693}}
|
|
3011 | 3011 |
item.perform(formdata) |
3012 | 3012 |
assert int(formdata.geolocations['base']['lat']) == 48 |
3013 | 3013 |
assert int(formdata.geolocations['base']['lon']) == 3 |
3014 | 3014 | |
3015 |
formdata.data = {'2': '48.8337085;4.3233693'}
|
|
3015 |
formdata.data = {'2': {'lat': 48.8337085, 'lon': 4.3233693}}
|
|
3016 | 3016 |
item.overwrite = False |
3017 | 3017 |
item.perform(formdata) |
3018 | 3018 |
assert int(formdata.geolocations['base']['lat']) == 48 |
wcs/backoffice/data_management.py | ||
---|---|---|
149 | 149 |
elif isinstance(f, fields.EmailField): |
150 | 150 |
value = 'foo@example.com' |
151 | 151 |
elif isinstance(f, fields.MapField): |
152 |
value = get_publisher().get_default_position() |
|
152 |
value = '%(lat)s;%(lon)s' % get_publisher().get_default_position()
|
|
153 | 153 |
else: |
154 | 154 |
value = 'value' |
155 | 155 |
sample_line.append(value) |
wcs/backoffice/management.py | ||
---|---|---|
2792 | 2792 |
geoloc_value = formdata.geolocations[geoloc_key] |
2793 | 2793 |
map_widget = MapWidget('geoloc_%s' % geoloc_key, |
2794 | 2794 |
readonly=True, |
2795 |
value='%(lat)s;%(lon)s' % geoloc_value,
|
|
2795 |
value=geoloc_value, |
|
2796 | 2796 |
render_br=False) |
2797 | 2797 |
r += map_widget.render() |
2798 | 2798 |
r += htmltext('</div>') |
wcs/fields.py | ||
---|---|---|
2449 | 2449 |
geolocate.method = 'address_string' |
2450 | 2450 |
geolocate.address_string = self.prefill.get('value') |
2451 | 2451 |
coords = geolocate.geolocate_address_string(None) |
2452 |
if not coords: |
|
2453 |
return (None, False) |
|
2454 |
return ('%(lat)s;%(lon)s' % coords, False) |
|
2452 |
return (coords, False) |
|
2455 | 2453 | |
2456 | 2454 |
def get_view_value(self, value, **kwargs): |
2457 | 2455 |
widget = self.widget_class('x%s' % random.random(), value, readonly=True) |
2458 | 2456 |
return widget.render_widget_content() |
2459 | 2457 | |
2460 | 2458 |
def get_rst_view_value(self, value, indent=''): |
2461 |
return indent + value |
|
2459 |
if isinstance(value, str): # compatiblity with old pickled data |
|
2460 |
return indent + value |
|
2461 |
return indent + '%(lat)s;%(lon)s' % value |
|
2462 | 2462 | |
2463 | 2463 |
def convert_value_from_str(self, value): |
2464 | 2464 |
try: |
2465 | 2465 |
lat, lon = [float(x) for x in value.split(';')] |
2466 | 2466 |
except (AttributeError, ValueError): |
2467 | 2467 |
return None |
2468 |
return value
|
|
2468 |
return {'lat': lat, 'lon': lon}
|
|
2469 | 2469 | |
2470 | 2470 |
def get_json_value(self, value, **kwargs): |
2471 |
if not value or ';' not in value: |
|
2472 |
return None |
|
2473 |
lat, lon = value.split(';') |
|
2474 |
try: |
|
2475 |
lat = float(lat) |
|
2476 |
lon = float(lon) |
|
2477 |
except ValueError: |
|
2478 |
return None |
|
2479 |
return {'lat': lat, 'lon': lon} |
|
2471 |
return value |
|
2480 | 2472 | |
2481 | 2473 |
def from_json_value(self, value): |
2482 |
if 'lat' in value and 'lon' in value:
|
|
2483 |
return '%s;%s' % (float(value['lat']), float(value['lon']))
|
|
2484 |
else:
|
|
2485 |
return None
|
|
2474 |
if isinstance(value, str):
|
|
2475 |
# backward compatibility
|
|
2476 |
return self.convert_value_from_str(value)
|
|
2477 |
return value
|
|
2486 | 2478 | |
2487 | 2479 |
def get_structured_value(self, data): |
2488 | 2480 |
return self.get_json_value(data.get(self.id)) |
wcs/formdef.py | ||
---|---|---|
714 | 714 |
def get_field_data(cls, field, widget): |
715 | 715 |
d = {} |
716 | 716 |
d[field.id] = widget.parse() |
717 |
if d.get(field.id) is not None and field.convert_value_from_str:
|
|
717 |
if isinstance(d.get(field.id), str) and field.convert_value_from_str:
|
|
718 | 718 |
d[field.id] = field.convert_value_from_str(d[field.id]) |
719 | 719 |
if d.get(field.id) is not None and field.store_display_value: |
720 | 720 |
display_value = field.store_display_value(d, field.id) |
wcs/qommon/form.py | ||
---|---|---|
2364 | 2364 | |
2365 | 2365 |
def __init__(self, name, value=None, **kwargs): |
2366 | 2366 |
CompositeWidget.__init__(self, name, value, **kwargs) |
2367 |
self.add(HiddenWidget, 'latlng', value=value) |
|
2367 |
latlng_value = None |
|
2368 |
if isinstance(value, str): # legacy data type |
|
2369 |
latlng_value = value |
|
2370 |
elif value: |
|
2371 |
latlng_value = '%s;%s' % (value['lat'], value['lon']) |
|
2372 |
self.add(HiddenWidget, 'latlng', value=latlng_value) |
|
2368 | 2373 |
widget = self.get_widget('latlng') |
2369 | 2374 |
self.readonly = kwargs.pop('readonly', False) |
2370 | 2375 |
self.map_attributes = {} |
... | ... | |
2377 | 2382 |
self.map_attributes['data-def-lat'] = kwargs['default_position'].split(';')[0] |
2378 | 2383 |
self.map_attributes['data-def-lng'] = kwargs['default_position'].split(';')[1] |
2379 | 2384 | |
2385 |
def point2str(self, value): |
|
2386 |
if not value: |
|
2387 |
return None |
|
2388 |
return '%s;%s' % (value['lat'], value['lon']) |
|
2389 | ||
2390 |
def transfer_form_value(self, request): |
|
2391 |
request.form[self.get_widget('latlng').name] = self.point2str(self.value) |
|
2392 | ||
2380 | 2393 |
def initial_position(self): |
2381 |
if self.value:
|
|
2394 |
if isinstance(self.value, str):
|
|
2382 | 2395 |
return {'lat': self.value.split(';')[0], |
2383 | 2396 |
'lng': self.value.split(';')[1]} |
2397 |
if isinstance(self.value, dict): |
|
2398 |
return {'lat': self.value['lat'], |
|
2399 |
'lng': self.value['lon']} |
|
2384 | 2400 |
return None |
2385 | 2401 | |
2386 | 2402 |
def add_media(self): |
... | ... | |
2391 | 2407 |
self.value = self.get('latlng') |
2392 | 2408 |
if self.value: |
2393 | 2409 |
lat, lon = self.value.split(';') |
2394 |
lat_lon = misc.normalize_geolocation({'lat': lat, 'lon': lon}) |
|
2395 |
self.value = '%s;%s' % (lat_lon['lat'], lat_lon['lon']) |
|
2410 |
self.value = misc.normalize_geolocation({'lat': lat, 'lon': lon}) |
|
2396 | 2411 | |
2397 | 2412 | |
2398 | 2413 |
class HiddenErrorWidget(HiddenWidget): |
wcs/qommon/publisher.py | ||
---|---|---|
855 | 855 |
def get_default_position(self): |
856 | 856 |
default_position = self.cfg.get('misc', {}).get('default-position', None) |
857 | 857 |
if not default_position: |
858 |
default_position = self.get_site_option('default_position') |
|
859 |
if not default_position: |
|
860 |
default_position = '50.84;4.36' |
|
858 |
default_position = self.get_site_option('default_position') or '50.84;4.36' |
|
859 | ||
860 |
if isinstance(default_position, str): |
|
861 |
default_position = { |
|
862 |
'lat': float(default_position.split(';')[0]), |
|
863 |
'lon': float(default_position.split(';')[1]), |
|
864 |
} |
|
865 | ||
861 | 866 |
return default_position |
862 | 867 | |
863 | 868 |
def get_map_attributes(self): |
864 | 869 |
attrs = {} |
865 |
attrs['data-def-lat'], attrs['data-def-lng'] = self.get_default_position().split(';') |
|
870 |
default_position = self.get_default_position() |
|
871 |
attrs['data-def-lat'] = default_position['lat'] |
|
872 |
attrs['data-def-lng'] = default_position['lon'] |
|
866 | 873 |
if self.get_site_option('map-bounds-top-left'): |
867 | 874 |
attrs['data-max-bounds-lat1'], attrs['data-max-bounds-lng1'] = \ |
868 | 875 |
self.get_site_option('map-bounds-top-left').split(';') |
wcs/qommon/templates/qommon/forms/widgets/map.html | ||
---|---|---|
1 | 1 |
{% extends "qommon/forms/widget.html" %} |
2 | 2 | |
3 | 3 |
{% block widget-control %} |
4 |
<input type="hidden" name="{{widget.name}}$latlng" {% if widget.value %}value="{{widget.value}}"{% endif %}> |
|
4 |
{% localize off %} |
|
5 |
<input type="hidden" name="{{widget.name}}$latlng" {% if widget.value %}value="{{widget.value.lat}};{{widget.value.lon}}"{% endif %}> |
|
5 | 6 |
<div id="map-{{widget.name}}" class="qommon-map" |
6 | 7 |
{% if widget.readonly %}data-readonly="true"{% endif %} |
7 | 8 |
{% if widget.sync_map_and_address_fields %}data-address-sync="true"{% endif %} |
... | ... | |
11 | 12 |
data-init-lng="{{ widget.initial_position.lng }}" |
12 | 13 |
{% endif %} |
13 | 14 |
></div> |
15 |
{% endlocalize %} |
|
14 | 16 |
{% endblock %} |
wcs/sql.py | ||
---|---|---|
67 | 67 |
'bool': 'boolean', |
68 | 68 |
'file': 'bytea', |
69 | 69 |
'date': 'date', |
70 |
'map': 'jsonb', |
|
70 | 71 |
'items': 'text[]', |
71 | 72 |
'table': 'text[][]', |
72 | 73 |
'table-select': 'text[][]', |
... | ... | |
2672 | 2673 |
return result |
2673 | 2674 | |
2674 | 2675 | |
2675 |
SQL_LEVEL = 42 |
|
2676 |
SQL_LEVEL = 43 |
|
2677 | ||
2678 | ||
2679 |
@guard_postgres |
|
2680 |
def migrate_map_data_type(): |
|
2681 |
conn, cur = get_connection_and_cursor() |
|
2682 | ||
2683 |
from wcs.formdef import FormDef |
|
2684 |
from wcs.carddef import CardDef |
|
2685 |
had_changes = False |
|
2686 |
for formdef in FormDef.select() + CardDef.select(): |
|
2687 |
table_name = get_formdef_table_name(formdef) |
|
2688 |
cur.execute('''SELECT column_name, udt_name FROM information_schema.columns |
|
2689 |
WHERE table_schema = 'public' |
|
2690 |
AND table_name = %s''', (table_name,)) |
|
2691 |
existing_fields = {x[0]: x[1] for x in cur.fetchall()} |
|
2692 | ||
2693 |
for field in formdef.get_all_fields(): |
|
2694 |
if field.type != 'map': |
|
2695 |
continue |
|
2696 |
database_field_id = get_field_id(field) |
|
2697 |
if existing_fields.get(database_field_id) == 'jsonb': |
|
2698 |
# already ok |
|
2699 |
continue |
|
2700 |
sql_type = SQL_TYPE_MAPPING.get(field.key, 'varchar') |
|
2701 |
cur.execute('''ALTER TABLE %s ADD COLUMN %s %s''' % ( |
|
2702 |
table_name, |
|
2703 |
'tmp_' + database_field_id, |
|
2704 |
sql_type)) |
|
2705 |
cur.execute('''UPDATE %(table_name)s |
|
2706 |
SET tmp_%(column)s = jsonb_build_object( |
|
2707 |
'lat', split_part(%(column)s, ';', 1)::float, |
|
2708 |
'lon', split_part(%(column)s, ';', 2)::float) |
|
2709 |
WHERE %(column)s IS NOT NULL |
|
2710 |
AND %(column)s != '' ''' % { |
|
2711 |
'table_name': table_name, |
|
2712 |
'column': database_field_id |
|
2713 |
}) |
|
2714 |
cur.execute('''ALTER TABLE %s DROP COLUMN %s CASCADE''' % ( |
|
2715 |
table_name, |
|
2716 |
database_field_id)) |
|
2717 |
cur.execute('''ALTER TABLE %s RENAME COLUMN tmp_%s TO %s''' % ( |
|
2718 |
table_name, |
|
2719 |
database_field_id, |
|
2720 |
database_field_id)) |
|
2721 |
had_changes = True |
|
2722 | ||
2723 |
if had_changes: |
|
2724 |
# views have to be recreated |
|
2725 |
migrate_views(conn, cur) |
|
2726 | ||
2727 |
conn.commit() |
|
2728 |
cur.close() |
|
2676 | 2729 | |
2677 | 2730 | |
2678 | 2731 |
def migrate_global_views(conn, cur): |
... | ... | |
2823 | 2876 |
if sql_level < 42: |
2824 | 2877 |
# 42: create snapshots table |
2825 | 2878 |
do_snapshots_table() |
2879 |
if sql_level < 43: |
|
2880 |
# 43: migrate map field data type |
|
2881 |
migrate_map_data_type() |
|
2826 | 2882 | |
2827 | 2883 |
cur.execute('''UPDATE wcs_meta SET value = %s WHERE key = %s''', ( |
2828 | 2884 |
str(SQL_LEVEL), 'sql_level')) |
wcs/variables.py | ||
---|---|---|
822 | 822 |
def inspect_keys(self): |
823 | 823 |
return ['lat', 'lon'] |
824 | 824 | |
825 |
def __str__(self): |
|
826 |
# backward compatibility |
|
827 |
value = self._data.get(self._field.id) |
|
828 |
if not value: |
|
829 |
return '' |
|
830 |
return '%(lat)s;%(lon)s' % value |
|
831 | ||
825 | 832 | |
826 | 833 |
class LazyFieldVarPassword(LazyFieldVar): |
827 | 834 |
def __getitem__(self, key): |
828 |
- |