Skip to content

Commit

Permalink
Merge pull request #187 from ukanga/relative-paths-issue-4
Browse files Browse the repository at this point in the history
Use relative references for repeats only.
  • Loading branch information
ukanga authored Dec 9, 2018
2 parents 9249534 + 3c31570 commit 405b5fa
Show file tree
Hide file tree
Showing 8 changed files with 424 additions and 181 deletions.
Empty file modified pyxform/__init__.py
100755 → 100644
Empty file.
145 changes: 68 additions & 77 deletions pyxform/question.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,23 @@


class Question(SurveyElement):

def validate(self):
SurveyElement.validate(self)

# make sure that the type of this question exists in the
# question type dictionary.
if self.type not in QUESTION_TYPE_DICT:
raise PyXFormError(
"Unknown question type '%s'." % self.type
)
raise PyXFormError("Unknown question type '%s'." % self.type)

def xml_instance(self):
def xml_instance(self, **kwargs):
survey = self.get_root()
attributes = {}
attributes.update(self.get(u'instance', {}))
attributes.update(self.get(u"instance", {}))
for key, value in attributes.items():
attributes[key] = survey.insert_xpaths(value)
attributes[key] = survey.insert_xpaths(value, self)

if self.get(u"default"):
return node(
self.name, unicode(self.get(u"default")), **attributes
)
return node(self.name, unicode(self.get(u"default")), **attributes)
return node(self.name, **attributes)

def xml_control(self):
Expand All @@ -40,45 +35,41 @@ class InputQuestion(Question):
This control string is the same for: strings, integers, decimals,
dates, geopoints, barcodes ...
"""

def xml_control(self):
control_dict = self.control
label_and_hint = self.xml_label_and_hint()
survey = self.get_root()
# Resolve field references in attributes
for key, value in control_dict.items():
control_dict[key] = survey.insert_xpaths(value)
control_dict['ref'] = self.get_xpath()
control_dict[key] = survey.insert_xpaths(value, self)
control_dict["ref"] = self.get_xpath()

result = node(**control_dict)
if label_and_hint:
for element in self.xml_label_and_hint():
result.appendChild(element)

# Input types are used for selects with external choices sheets.
if self['query']:
choice_filter = self.get('choice_filter')
query = "instance('" + self['query'] + "')/root/item"
choice_filter = survey.insert_xpaths(choice_filter)
if self["query"]:
choice_filter = self.get("choice_filter")
query = "instance('" + self["query"] + "')/root/item"
choice_filter = survey.insert_xpaths(choice_filter, self, True)
if choice_filter:
query += '[' + choice_filter + ']'
result.setAttribute('query', query)
query += "[" + choice_filter + "]"
result.setAttribute("query", query)
return result


class TriggerQuestion(Question):

def xml_control(self):
control_dict = self.control
survey = self.get_root()
# Resolve field references in attributes
for key, value in control_dict.items():
control_dict[key] = survey.insert_xpaths(value)
control_dict['ref'] = self.get_xpath()
return node(
u"trigger",
*self.xml_label_and_hint(),
**control_dict
)
control_dict[key] = survey.insert_xpaths(value, self)
control_dict["ref"] = self.get_xpath()
return node(u"trigger", *self.xml_label_and_hint(), **control_dict)


class UploadQuestion(Question):
Expand All @@ -87,17 +78,12 @@ def _get_media_type(self):

def xml_control(self):
control_dict = self.control
control_dict['ref'] = self.get_xpath()
control_dict['mediatype'] = self._get_media_type()
return node(
u"upload",
*self.xml_label_and_hint(),
**control_dict
)
control_dict["ref"] = self.get_xpath()
control_dict["mediatype"] = self._get_media_type()
return node(u"upload", *self.xml_label_and_hint(), **control_dict)


class Option(SurveyElement):

def xml_value(self):
return node(u"value", self.name)

Expand All @@ -114,15 +100,15 @@ def validate(self):


class MultipleChoiceQuestion(Question):

def __init__(self, **kwargs):
kwargs_copy = kwargs.copy()
# Notice that choices can be specified under choices or children.
# I'm going to try to stick to just choices.
# Aliases in the json format will make it more difficult
# to use going forward.
choices = list(kwargs_copy.pop(u"choices", [])) + \
list(kwargs_copy.pop(u"children", []))
choices = list(kwargs_copy.pop(u"choices", [])) + list(
kwargs_copy.pop(u"children", [])
)
Question.__init__(self, **kwargs_copy)
for choice in choices:
self.add_choice(**choice)
Expand All @@ -145,47 +131,55 @@ def xml_control(self):
control_dict = self.control.copy()
# Resolve field references in attributes
for key, value in control_dict.items():
control_dict[key] = survey.insert_xpaths(value)
control_dict['ref'] = self.get_xpath()
control_dict[key] = survey.insert_xpaths(value, self)
control_dict["ref"] = self.get_xpath()

result = node(**control_dict)
for element in self.xml_label_and_hint():
result.appendChild(element)
# itemset are only supposed to be strings,
# check to prevent the rare dicts that show up
if self['itemset'] and isinstance(self['itemset'], basestring):
choice_filter = self.get('choice_filter')
itemset, file_extension = os.path.splitext(self['itemset'])
if file_extension in ['.csv', '.xml']:
if self["itemset"] and isinstance(self["itemset"], basestring):
choice_filter = self.get("choice_filter")
itemset, file_extension = os.path.splitext(self["itemset"])
if file_extension in [".csv", ".xml"]:
itemset = itemset
itemset_label_ref = "label"
else:
itemset = self['itemset']
itemset = self["itemset"]
itemset_label_ref = "jr:itext(itextId)"
nodeset = "instance('" + itemset + "')/root/item"

choice_filter = survey.insert_xpaths(choice_filter)
choice_filter = survey.insert_xpaths(choice_filter, self, True)
if choice_filter:
nodeset += '[' + choice_filter + ']'

if self['parameters']:
params = self['parameters']

if 'randomize' in params and params['randomize'] == 'true':
nodeset = 'randomize(' + nodeset

if 'seed' in params:
if params['seed'].startswith('${'):
nodeset = nodeset + ', ' + survey.insert_xpaths(params['seed']).strip()
nodeset += "[" + choice_filter + "]"

if self["parameters"]:
params = self["parameters"]

if "randomize" in params and params["randomize"] == "true":
nodeset = "randomize(" + nodeset

if "seed" in params:
if params["seed"].startswith("${"):
nodeset = (
nodeset
+ ", "
+ survey.insert_xpaths(
params["seed"], self
).strip()
)
else:
nodeset = nodeset + ', ' + params['seed']
nodeset = nodeset + ", " + params["seed"]

nodeset += ')'
nodeset += ")"

itemset_children = [node('value', ref='name'),
node('label', ref=itemset_label_ref)]
result.appendChild(node('itemset', *itemset_children,
nodeset=nodeset))
itemset_children = [
node("value", ref="name"),
node("label", ref=itemset_label_ref),
]
result.appendChild(
node("itemset", *itemset_children, nodeset=nodeset)
)
else:
for n in [o.xml() for o in self.children]:
result.appendChild(n)
Expand All @@ -201,8 +195,9 @@ def __init__(self, **kwargs):
class Tag(SurveyElement):
def __init__(self, **kwargs):
kwargs_copy = kwargs.copy()
choices = kwargs_copy.pop(u"choices", []) + \
kwargs_copy.pop(u"children", [])
choices = kwargs_copy.pop(u"choices", []) + kwargs_copy.pop(
u"children", []
)

super(Tag, self).__init__(**kwargs_copy)

Expand All @@ -229,8 +224,7 @@ def validate(self):
class OsmUploadQuestion(UploadQuestion):
def __init__(self, **kwargs):
kwargs_copy = kwargs.copy()
tags = kwargs_copy.pop(u"tags", []) + \
kwargs_copy.pop(u"children", [])
tags = kwargs_copy.pop(u"tags", []) + kwargs_copy.pop(u"children", [])

super(OsmUploadQuestion, self).__init__(**kwargs_copy)

Expand All @@ -246,13 +240,9 @@ def add_tag(self, **kwargs):

def xml_control(self):
control_dict = self.control
control_dict['ref'] = self.get_xpath()
control_dict['mediatype'] = self._get_media_type()
result = node(
u"upload",
*self.xml_label_and_hint(),
**control_dict
)
control_dict["ref"] = self.get_xpath()
control_dict["mediatype"] = self._get_media_type()
result = node(u"upload", *self.xml_label_and_hint(), **control_dict)

for osm_tag in self.children:
result.appendChild(osm_tag.xml())
Expand All @@ -265,15 +255,16 @@ class RangeQuestion(Question):
This control string is the same for: strings, integers, decimals,
dates, geopoints, barcodes ...
"""

def xml_control(self):
control_dict = self.control
label_and_hint = self.xml_label_and_hint()
survey = self.get_root()
# Resolve field references in attributes
for key, value in control_dict.items():
control_dict[key] = survey.insert_xpaths(value)
control_dict['ref'] = self.get_xpath()
params = self.get('parameters', {})
control_dict[key] = survey.insert_xpaths(value, self)
control_dict["ref"] = self.get_xpath()
params = self.get("parameters", {})
control_dict.update(params)
result = node(**control_dict)
if label_and_hint:
Expand Down
9 changes: 5 additions & 4 deletions pyxform/section.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def xml_instance(self, **kwargs):
survey = self.get_root()
# Resolve field references in attributes
for key, value in attributes.items():
attributes[key] = survey.insert_xpaths(value)
attributes[key] = survey.insert_xpaths(value, self)
result = node(self.name, **attributes)
for child in self.children:
if child.get(u"flat"):
Expand Down Expand Up @@ -87,7 +87,7 @@ def xml_control(self):
survey = self.get_root()
# Resolve field references in attributes
for key, value in control_dict.items():
control_dict[key] = survey.insert_xpaths(value)
control_dict[key] = survey.insert_xpaths(value, self)
repeat_node = node(u"repeat", nodeset=self.get_xpath(), **control_dict)

for n in Section.xml_control(self):
Expand Down Expand Up @@ -138,7 +138,7 @@ def xml_control(self):

# Resolve field references in attributes
for key, value in attributes.items():
attributes[key] = survey.insert_xpaths(value)
attributes[key] = survey.insert_xpaths(value, self)

if not self.get('flat'):
attributes['ref'] = self.get_xpath()
Expand All @@ -153,7 +153,8 @@ def xml_control(self):

if u"intent" in control_dict:
survey = self.get_root()
attributes['intent'] = survey.insert_xpaths(control_dict['intent'])
attributes['intent'] = survey.insert_xpaths(control_dict['intent'],
self)

return node(u"group", *children, **attributes)

Expand Down
Loading

0 comments on commit 405b5fa

Please sign in to comment.