Skip to content

Commit 2698832

Browse files
committed
Merge branch 'master' into 236-library-locking
2 parents 751f765 + 972fde2 commit 2698832

File tree

7 files changed

+122
-45
lines changed

7 files changed

+122
-45
lines changed

src/formpack/schema/fields.py

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -160,23 +160,47 @@ def from_json_definition(cls, definition, hierarchy=None,
160160
choice = field_choices[choice_id]
161161

162162
data_type_classes = {
163-
"select_one": FormChoiceField,
164-
"select_multiple": FormChoiceFieldWithMultipleSelect,
165-
"geopoint": FormGPSField,
166-
"date": DateField,
167-
"text": TextField,
168-
"barcode": TextField,
169-
170-
# calculate is usually not text but for our purpose it's good
171-
# enough
172-
"calculate": TextField,
173-
"acknowledge": TextField,
174-
"integer": NumField,
163+
# selects
164+
'select_one': FormChoiceField,
165+
'select_one_from_file': FormChoiceField,
166+
'select_multiple': FormChoiceFieldWithMultipleSelect,
167+
# TODO: Get this to work with FormChoiceFieldWithMultipleSelect
168+
'select_multiple_from_file': TextField,
169+
'rank': TextField,
170+
171+
# date and time
172+
'date': DateField,
173+
'today': DateField,
174+
'datetime': TextField,
175+
'time': TextField,
176+
'start': TextField,
177+
'end': TextField,
178+
179+
# general
180+
'text': TextField,
181+
'barcode': TextField,
182+
'acknowledge': TextField,
183+
184+
# geo
185+
'geopoint': FormGPSField,
186+
'start-geopoint': FormGPSField,
187+
188+
# media
189+
'video': TextField,
190+
'image': TextField,
191+
'audio': TextField,
192+
'file': TextField,
193+
'background-audio': TextField,
194+
195+
# numeric
196+
'calculate': TextField,
197+
'integer': NumField,
175198
'decimal': NumField,
199+
'range': NumField,
176200

177201
# legacy type, treat them as text
178-
"select_one_external": partial(TextField, data_type=data_type),
179-
"cascading_select": partial(TextField, data_type=data_type),
202+
'select_one_external': partial(TextField, data_type=data_type),
203+
'cascading_select': partial(TextField, data_type=data_type),
180204
}
181205

182206
args = {

src/formpack/utils/expand_content.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from .array_to_xpath import EXPANDABLE_FIELD_TYPES
1212
from .future import iteritems, OrderedDict
1313
from .iterator import get_first_occurrence
14-
from .replace_aliases import META_TYPES
14+
from .replace_aliases import META_TYPES, SELECT_TYPES
1515
from .string import str_types
1616
from ..constants import (UNTRANSLATED, OR_OTHER_COLUMN,
1717
TAG_COLUMNS_AND_SEPARATORS)
@@ -231,6 +231,7 @@ def _mark_special(**kwargs):
231231

232232

233233
def _expand_type_to_dict(type_str):
234+
SELECT_PATTERN = r'^({select_type})\s+(\S+)$'
234235
out = {}
235236
match = re.search('( or.other)$', type_str)
236237
if match:
@@ -243,12 +244,10 @@ def _expand_type_to_dict(type_str):
243244
if type_str in ['select_one', 'select_multiple']:
244245
out['type'] = type_str
245246
return out
246-
for _re in [
247-
r'^(select_one)\s+(\S+)$',
248-
r'^(select_multiple)\s+(\S+)$',
249-
r'^(select_one_external)\s+(\S+)$',
250-
]:
251-
match = re.match(_re, type_str)
247+
for select_type in SELECT_TYPES:
248+
match = re.match(
249+
SELECT_PATTERN.format(select_type=select_type), type_str
250+
)
252251
if match:
253252
(type_, list_name) = match.groups()
254253
out['type'] = type_

src/formpack/utils/flatten_content.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from .array_to_xpath import array_to_xpath
1111
from .future import range
1212
from .string import str_types
13+
from .replace_aliases import SELECT_TYPES
1314
from ..constants import (UNTRANSLATED, OR_OTHER_COLUMN,
1415
TAG_COLUMNS_AND_SEPARATORS)
1516

@@ -72,11 +73,10 @@ def _stringify_type__depr(json_qtype):
7273
{'select_one': 'xyz'} -> 'select_one xyz'
7374
{'select_multiple': 'xyz'} -> 'select_mutliple xyz'
7475
"""
75-
_type_keys = ['select_one', 'select_multiple']
7676
if len(json_qtype.keys()) != 1:
7777
raise ValueError('Type object must have exactly one key: %s' %
78-
', '.join(_type_keys))
79-
for try_key in _type_keys:
78+
', '.join(SELECT_TYPES))
79+
for try_key in SELECT_TYPES:
8080
if try_key in json_qtype:
8181
return '{} {}'.format(try_key, json_qtype[try_key])
8282
if 'select_one_or_other' in json_qtype:

src/formpack/utils/replace_aliases.py

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -69,25 +69,35 @@ def aliases_to_ordered_dict(_d):
6969
'geopoint': ['gps'],
7070
})
7171

72-
selects = aliases_to_ordered_dict({
73-
'select_multiple': [
74-
'select all that apply',
75-
'select multiple',
76-
'select many',
77-
'select_many',
78-
'select all that apply from',
79-
'add select multiple prompt using',
80-
],
81-
'select_one_external': [
82-
'select one external',
83-
],
84-
'select_one': [
85-
'select one',
86-
'select one from',
87-
'add select one prompt using',
88-
'select1',
89-
],
90-
})
72+
# keys used in `_expand_type_to_dict()` to handle choices argument
73+
selects = aliases_to_ordered_dict(
74+
{
75+
'select_multiple': [
76+
'select all that apply',
77+
'select multiple',
78+
'select many',
79+
'select_many',
80+
'select all that apply from',
81+
'add select multiple prompt using',
82+
],
83+
'select_multiple_from_file': [
84+
'select multiple from file',
85+
],
86+
'select_one_external': [
87+
'select one external',
88+
],
89+
'select_one': [
90+
'select one',
91+
'select one from',
92+
'add select one prompt using',
93+
'select1',
94+
],
95+
'select_one_from_file': [
96+
'select one from file',
97+
],
98+
'rank': [],
99+
}
100+
)
91101
# Python3: Cast to a list because it's merged into other dicts
92102
# (i.e `SELECT_SCHEMA` in validators.py)
93103
SELECT_TYPES = list(selects.keys())
@@ -99,12 +109,15 @@ def aliases_to_ordered_dict(_d):
99109
'deviceid',
100110
'phone_number',
101111
'simserial',
112+
'audit',
102113
# meta values
103114
'username',
104115
# reconsider:
105116
'phonenumber',
106117
'imei',
107118
'subscriberid',
119+
# geo
120+
'start-geopoint',
108121
]
109122

110123
LABEL_OPTIONAL_TYPES = [
@@ -131,17 +144,23 @@ def aliases_to_ordered_dict(_d):
131144
'video',
132145
'image',
133146
'audio',
147+
'file',
148+
'background-audio',
134149
# enter time values
135150
'date',
136151
'datetime',
137152
'time',
138-
139153
# prompt to collect geo data
140154
'location',
141-
142155
# no response
143156
'acknowledge',
144157
'note',
158+
# external data source
159+
'xml-external',
160+
'csv-external',
161+
# other
162+
'range',
163+
'hidden',
145164
] + GEO_TYPES
146165
formpack_preferred_types = set(MAIN_TYPES + LABEL_OPTIONAL_TYPES + SELECT_TYPES)
147166

src/formpack/utils/xform_tools.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
("select one from", 'select_one'),
1616
("select1", 'select_one'),
1717
("select one", 'select_one'),
18+
('select one from file', 'select_one_from_file'),
1819
("add select multiple prompt using", 'select_multiple'),
1920
("select all that apply from", 'select_multiple'),
2021
("select multiple", 'select_multiple'),
2122
("select all that apply", 'select_multiple'),
23+
('select multiple from file', 'select_multiple_from_file'),
2224
("select_one_external", "select one external"),
2325
('cascading select', 'cascading_select'),
2426
('location', 'geopoint'),

tests/test_replace_aliases.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ def test_select_one_aliases_replaced():
2525
assert dealias_type('select_one dogs') == 'select_one dogs'
2626

2727

28+
def test_replace_select_one_from_file():
29+
s1 = {'survey': [{'type': 'select one from file dogs.csv'}]}
30+
replace_aliases(s1, in_place=True)
31+
assert s1['survey'][0]['type'] == 'select_one_from_file dogs.csv'
32+
33+
2834
def test_true_false_value_replaced():
2935
# only replaced on columns with TF_COLUMNS
3036
s1 = {'survey': [
@@ -47,6 +53,12 @@ def test_select_multiple_aliases_replaced():
4753
assert dealias_type('select_multiple dogs') == 'select_multiple dogs'
4854

4955

56+
def test_replace_select_multiple_from_file():
57+
s1 = {'survey': [{'type': 'select multiple from file dogs.csv'}]}
58+
replace_aliases(s1, in_place=True)
59+
assert s1['survey'][0]['type'] == 'select_multiple_from_file dogs.csv'
60+
61+
5062
def test_misc_types():
5163
assert dealias_type('begin group') == 'begin_group'
5264
assert dealias_type('end group') == 'end_group'

tests/test_utils_flatten_content.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,27 @@ def test_flatten_select_multiple_type():
133133
assert ss_struct[0]['type'] == 'select_multiple yn'
134134

135135

136+
def test_flatten_select_one_from_file_type():
137+
a1 = _wrap_type({'select_one_from_file': 'yn.csv'})
138+
flatten_content(a1, in_place=True)
139+
ss_struct = a1['survey']
140+
assert ss_struct[0]['type'] == 'select_one_from_file yn.csv'
141+
142+
143+
def test_flatten_select_multiple_from_file_type():
144+
a1 = _wrap_type({'select_multiple_from_file': 'yn.csv'})
145+
flatten_content(a1, in_place=True)
146+
ss_struct = a1['survey']
147+
assert ss_struct[0]['type'] == 'select_multiple_from_file yn.csv'
148+
149+
150+
def test_flatten_rank_type():
151+
a1 = _wrap_type({'rank': 'yn'})
152+
flatten_content(a1, in_place=True)
153+
ss_struct = a1['survey']
154+
assert ss_struct[0]['type'] == 'rank yn'
155+
156+
136157
def test_json_hash():
137158
# consistent output
138159
assert json_hash({'a': 'z', 'b': 'y', 'c': 'x'}) == 'f6117d60'

0 commit comments

Comments
 (0)