def xml_hint(self): if type(self.hint) == dict: path = self._translation_path("hint") return node(u"hint", ref="jr:itext('%s')" % path) else: hint, outputInserted = self.get_root().insert_output_values(self.hint) return node(u"hint", hint, toParseString=outputInserted)
def _generate_static_instances(self): """ Generates <instance> elements for static data (e.g. choices for select type questions) """ for list_name, choice_list in self.choices.items(): instance_element_list = [] for idx, choice in zip(range(len(choice_list)), choice_list): choice_element_list = [] # Add a unique id to the choice element incase there is itext # it refrences itextId = '-'.join(['static_instance', list_name, str(idx)]) choice_element_list.append(node("itextId", itextId)) for choicePropertyName, choicePropertyValue in choice.items(): if isinstance(choicePropertyValue, basestring) \ and choicePropertyName != 'label': choice_element_list.append( node(choicePropertyName, unicode(choicePropertyValue)) ) instance_element_list.append(node("item", *choice_element_list)) yield node("instance", node("root", *instance_element_list), id=list_name)
def xml_control(self): assert self.bind[u"type"] in [u"select", u"select1"] survey = self.get_root() 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() 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') nodeset = "instance('" + self['itemset'] + "')/root/item" choice_filter = survey.insert_xpaths(choice_filter) if choice_filter: nodeset += '[' + choice_filter + ']' itemset_label_ref = "jr:itext(itextId)" 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) return result
def xml_control(self): """ <group> <label>Fav Color</label> <repeat nodeset="fav-color"> <select1 ref="."> <label ref="jr:itext('fav')" /> <item><label ref="jr:itext('red')" /><value>red</value></item> <item><label ref="jr:itext('green')" /><value>green</value></item> <item><label ref="jr:itext('yellow')" /><value>yellow</value></item> </select1> </repeat> </group> """ control_dict = self.control kwargs = {} if u"jr:count" in self and self[u"jr:count"] != "": kwargs = {u"jr:count": self[u"jr:count"]} if u"appearance" in control_dict: repeat_node = node(u"repeat", nodeset=self.get_xpath(), appearance=control_dict[u"appearance"], **kwargs) else: repeat_node = node(u"repeat", nodeset=self.get_xpath(), **kwargs) for n in Section.xml_control(self): repeat_node.appendChild(n) label = self.xml_label() if label: return node(u"group", self.xml_label(), repeat_node, ref=self.get_xpath()) return node(u"group", repeat_node, ref=self.get_xpath())
def xml_model(self): """ Generate the xform <model> element """ self._setup_translations() self._setup_media() model_children = [node("instance", self.xml_instance()) ] + self.xml_bindings() if self._translations: model_children.insert(0, self.itext()) if self.submission_url: #We need to add a unique form instance id if the form is to be submitted. model_children.append( node("bind", nodeset="/" + self.name + "/meta/instanceID", type="string", readonly="true()", calculate="concat('uuid:', uuid())")) if self.public_key: submission_node = node("submission", method="form-data-post", action=self.submission_url, base64RsaPublicKey=self.public_key) else: submission_node = node("submission", method="form-data-post", action=self.submission_url) model_children.insert(0, submission_node) return node("model", *model_children)
def xml_control(self): """ <group> <label>Fav Color</label> <repeat nodeset="fav-color"> <select1 ref="."> <label ref="jr:itext('fav')" /> <item><label ref="jr:itext('red')" /><value>red</value></item> <item><label ref="jr:itext('green')" /><value>green</value></item> <item><label ref="jr:itext('yellow')" /><value>yellow</value></item> </select1> </repeat> </group> """ control_dict = self.control.copy() survey = self.get_root() # Resolve field references in attributes for key, value in control_dict.items(): control_dict[key] = survey.insert_xpaths(value) repeat_node = node(u"repeat", nodeset=self.get_xpath(), **control_dict) for n in Section.xml_control(self): repeat_node.appendChild(n) label = self.xml_label() if label: return node( u"group", self.xml_label(), repeat_node, ref=self.get_xpath() ) return node(u"group", repeat_node, ref=self.get_xpath(), **self.control)
def xml_control(self): """ <group> <label>Fav Color</label> <repeat nodeset="fav-color"> <select1 ref="."> <label ref="jr:itext('fav')" /> <item><label ref="jr:itext('red')" /><value>red</value></item> <item><label ref="jr:itext('green')" /><value>green</value></item> <item><label ref="jr:itext('yellow')" /><value>yellow</value></item> </select1> </repeat> </group> """ control_dict = self.control.copy() jrcount = control_dict.get('jr:count') if jrcount: survey = self.get_root() control_dict['jr:count'] = survey.insert_xpaths(jrcount) repeat_node = node(u"repeat", nodeset=self.get_xpath(), **control_dict) for n in Section.xml_control(self): repeat_node.appendChild(n) label = self.xml_label() if label: return node( u"group", self.xml_label(), repeat_node, ref=self.get_xpath() ) return node(u"group", repeat_node, ref=self.get_xpath())
def xml_control(self): assert self.bind[u"type"] in [u"select", u"select1"] survey = self.get_root() 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() 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') nodeset = "instance('" + self['itemset'] + "')/root/item" choice_filter = survey.insert_xpaths(choice_filter) if choice_filter: nodeset += '[' + choice_filter + ']' itemset_label_ref = "jr:itext(itextId)" 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) return result
def xml_control(self): """ <group> <label>Fav Color</label> <repeat nodeset="fav-color"> <select1 ref="."> <label ref="jr:itext('fav')" /> <item><label ref="jr:itext('red')" /><value>red</value></item> <item><label ref="jr:itext('green')" /><value>green</value></item> <item><label ref="jr:itext('blue')" /><value>blue</value></item> </select1> </repeat> </group> """ control_dict = self.control.copy() survey = self.get_root() # Resolve field references in attributes for key, value in control_dict.items(): control_dict[key] = survey.insert_xpaths(value) repeat_node = node(u"repeat", nodeset=self.get_xpath(), **control_dict) for n in Section.xml_control(self): repeat_node.appendChild(n) label = self.xml_label() if label: return node(u"group", self.xml_label(), repeat_node, ref=self.get_xpath()) return node(u"group", repeat_node, ref=self.get_xpath(), **self.control)
def xml_model(self): """ Generate the xform <model> element """ self._setup_translations() self._setup_media() self._add_empty_translations() model_children = [] if self._translations: model_children.append(self.itext()) model_children += [node("instance", self.xml_instance())] model_children += list(self._generate_static_instances()) model_children += list(self._generate_pulldata_instances()) model_children += self.xml_bindings() if self.submission_url or self.public_key: submission_attrs = dict() if self.submission_url: submission_attrs["action"] = self.submission_url if self.public_key: submission_attrs["base64RsaPublicKey"] = self.public_key submission_node = node("submission", method="form-data-post", **submission_attrs) model_children.insert(0, submission_node) return node("model", *model_children)
def xml_hint(self): if type(self.get_hint()) == dict: d = self.get_translation_keys() return node(u"hint", ref="jr:itext('%s')" % d[u"hint"]) else: hint, outputInserted = self.get_root().insert_output_values(self.get_hint()) return node(u"hint", hint, toParseString=outputInserted)
def xml_model(self): self._setup_translations() if self._translations: return node("model", self.xml_translations(), node("instance", self.xml_instance()), *self.xml_bindings()) return node("model", node("instance", self.xml_instance()), *self.xml_bindings())
def xml_hint(self): if type(self.hint) == dict: path = self._translation_path("hint") return node(u"hint", ref="jr:itext('%s')" % path) else: hint, outputInserted = self.get_root().insert_output_values( self.hint) return node(u"hint", hint, toParseString=outputInserted)
def xml_instance(self): result = Section.xml_instance(self) result.setAttribute(u"id", self.id_string) #We need to add a unique form instance id if the form is to be submitted. if self.submission_url: result.appendChild(node("orx:meta", node("orx:instanceID"))) return result
def xml_instance(self): survey = self.get_root() attributes = {} attributes.update(self.get(u'instance', {})) for key, value in attributes.items(): attributes[key] = survey.insert_xpaths(value) if self.get(u"default"): return node(self.name, unicode(self.get(u"default")), **attributes) return node(self.name, **attributes)
def xml_label(self): if self.needs_itext_ref(): #If there is a dictionary label, or non-empty media dict, then we need to make a label with an itext ref ref = "jr:itext('%s')" % self._translation_path(u"label") return node(u"label", ref=ref) else: survey = self.get_root() label, outputInserted = survey.insert_output_values(self.label) return node(u"label", label, toParseString=outputInserted)
def xml(self): """ calls necessary preparation methods, then returns the xml. """ self.validate() self._setup_xpath_dictionary() return node( u"h:html", node(u"h:head", node(u"h:title", self.title), self.xml_model()), node(u"h:body", *self.xml_control()), **nsmap)
def xml_translations(self): result = [] for lang in self._translations.keys(): result.append(node("translation", lang=lang)) for name in self._translations[lang].keys(): result[-1].appendChild( node("text", node("value", self._translations[lang][name]), id=name)) return node("itext", *result)
def xml_instance(self): survey = self.get_root() attributes = {} attributes.update(self.get(u'instance', {})) for key, value in attributes.items(): attributes[key] = survey.insert_xpaths(value) if self.get(u"default"): return node( self.name, unicode(self.get(u"default")), **attributes ) return node(self.name, **attributes)
def xml_control(self): control_dict = self.control if u"appearance" in control_dict: return node(u"trigger", ref=self.get_xpath(), appearance=control_dict[u"appearance"], *self.xml_label_and_hint()) else: return node(u"trigger", ref=self.get_xpath(), *self.xml_label_and_hint())
def xml_label(self): if not self.get_label() and not self.get(self.TYPE) == "group"and len(self.get('media')) == 0: return None if type(self.get_label()) == dict or not len(self.get('media')) == 0: if len(self.get_label()) == 0 and self.get(self.TYPE) == "group": return None return node(u"label", ref="jr:itext('%s')" % self._translation_path(u"label")) else: label, outputInserted = self.get_root().insert_output_values(self.get_label()) return node(u"label", label, toParseString=outputInserted)
def _generate_from_file_instances(self): for i in self.iter_descendants(): itemset = i.get('itemset') if itemset and \ (itemset.endswith('.csv') or itemset.endswith('.xml')): file_id, file_extension = os.path.splitext(itemset) yield node( "instance", node("root", node("item", node("name"), node("label"))), id=file_id, src="jr://file-%s/%s" % (file_extension[1:], itemset) )
def xml_translations(self): result = [] for lang in self._translations.keys(): result.append( node("translation", lang=lang) ) for name in self._translations[lang].keys(): result[-1].appendChild( node("text", node("value", self._translations[lang][name]), id=name ) ) return node("itext", *result)
def xml_model(self): self._setup_translations() if self._translations: return node("model", self.xml_translations(), node("instance", self.xml_instance()), *self.xml_bindings() ) return node("model", node("instance", self.xml_instance()), *self.xml_bindings() )
def xml(self): """ calls necessary preparation methods, then returns the xml. """ self.validate() self._setup_xpath_dictionary() return node( u"h:html", node(u"h:head", node(u"h:title", self.title), self.xml_model()), node(u"h:body", *self.xml_control()), **nsmap )
def _generate_from_file_instances(self): for i in self.iter_descendants(): itemset = i.get('itemset') if itemset and \ (itemset.endswith('.csv') or itemset.endswith('.xml')): file_id, file_extension = os.path.splitext(itemset) yield node("instance", node("root", node("item", node("name"), node("label"))), id=file_id, src="jr://file-%s/%s" % (file_extension[1:], itemset))
def xml_control(self): control_dict = self.get_control() if self.APPEARANCE in control_dict: return node( u"trigger", ref=self.get_xpath(), appearance=control_dict[self.APPEARANCE], *self.xml_label_and_hint() ) else: return node(u"trigger", ref=self.get_xpath(), *self.xml_label_and_hint() )
def xml(self): """ calls necessary preparation methods, then returns the xml. """ self.validate() self._setup_xpath_dictionary() body_kwargs = {} if hasattr(self, constants.STYLE) and getattr(self, constants.STYLE): body_kwargs['class'] = getattr(self, constants.STYLE) return node( u"h:html", node(u"h:head", node(u"h:title", self.title), self.xml_model()), node(u"h:body", *self.xml_control(), **body_kwargs), **nsmap)
def xml_control(self): control_dict = self.control if u"appearance" in control_dict: return node(u"upload", ref=self.get_xpath(), mediatype=self._get_media_type(), appearance=control_dict[u"appearance"], *self.xml_label_and_hint()) else: return node(u"upload", ref=self.get_xpath(), mediatype=self._get_media_type(), *self.xml_label_and_hint())
def xml_control(self): control_dict = self.control if u"appearance" in control_dict: return node( u"trigger", ref=self.get_xpath(), appearance=control_dict[u"appearance"], *self.xml_label_and_hint() ) else: return node(u"trigger", ref=self.get_xpath(), *self.xml_label_and_hint() )
def itext(self): """ This function creates the survey's itext nodes from _translations @see _setup_media _setup_translations itext nodes are localized images/audio/video/text @see http://code.google.com/p/opendatakit/wiki/XFormDesignGuidelines """ result = [] for lang, translation in self._translations.items(): if lang == self.default_language: result.append( node("translation", lang=lang, default=u"true()")) else: result.append(node("translation", lang=lang)) for label_name, content in translation.items(): itext_nodes = [] label_type = label_name.partition(":")[-1] if type(content) is not dict: raise Exception() for media_type, media_value in content.items(): # There is a odk/jr bug where hints can't have a value # for the "form" attribute. # This is my workaround. if label_type == u"hint": value, outputInserted = \ self.insert_output_values(media_value) itext_nodes.append( node("value", value, toParseString=outputInserted)) continue if media_type == "long": value, outputInserted = \ self.insert_output_values(media_value) # I'm ignoring long types for now because I don't know # how they are supposed to work. itext_nodes.append( node("value", value, toParseString=outputInserted)) elif media_type == "image": value, outputInserted = \ self.insert_output_values(media_value) itext_nodes.append( node("value", "jr://images/" + value, form=media_type, toParseString=outputInserted) ) else: value, outputInserted = \ self.insert_output_values(media_value) itext_nodes.append( node("value", "jr://" + media_type + "/" + value, form=media_type, toParseString=outputInserted)) result[-1].appendChild( node("text", *itext_nodes, id=label_name)) return node("itext", *result)
def xml_control(self): control_dict = self.control xml_label = self.xml_label() if u"appearance" in control_dict and xml_label: group_node = node(u"group", xml_label, ref=self.get_xpath(), appearance=control_dict[u"appearance"]) elif u"appearance" in control_dict and not xml_label: group_node = node(u"group", ref=self.get_xpath(), appearance=control_dict[u"appearance"]) elif not u"appearance" in control_dict and xml_label: group_node = node(u"group", self.xml_label(), ref=self.get_xpath()) else: group_node = node(u"group", ref=self.get_xpath()) for n in Section.xml_control(self): group_node.appendChild(n) return group_node
def xml_control(self): return node( u"upload", ref=self.get_xpath(), mediatype=self._get_media_type(), *self.xml_label_and_hint() )
def xml_control(self): control_dict = self.control label_and_hint = self.xml_label_and_hint() control_dict['ref'] = self.get_xpath() # for SurveyCTO's support for external intents, resolve field references in appearance column: survey = self.get_root() appearance=control_dict.get('appearance') if appearance is not None: control_dict['appearance'] = survey.insert_xpaths(appearance) 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 choice_filter: query += '[' + choice_filter + ']' result.setAttribute('query', query) return result
def xml_control(self): control_dict = self.control if control_dict.get("bodyless"): return None children = [] attributes = {} attributes.update(self.control) survey = self.get_root() # Resolve field references in attributes for key, value in attributes.items(): attributes[key] = survey.insert_xpaths(value) if not self.get('flat'): attributes['ref'] = self.get_xpath() if 'label' in self and len(self['label']) > 0: children.append(self.xml_label()) for n in Section.xml_control(self): children.append(n) if u"appearance" in control_dict: attributes['appearance'] = control_dict['appearance'] if u"intent" in control_dict: survey = self.get_root() attributes['intent'] = survey.insert_xpaths(control_dict['intent']) return node(u"group", *children, **attributes)
def xml_control(self): control_dict = self.control if control_dict.get("bodyless"): return None children = [] attrs = {} if not self.get('flat'): attrs['ref'] = self.get_xpath() if 'label' in self and len(self['label']) > 0: children.append(self.xml_label()) for n in Section.xml_control(self): children.append(n) if u"appearance" in control_dict: attrs['appearance'] = control_dict['appearance'] if u"intent" in control_dict: survey = self.get_root() attrs['intent'] = survey.insert_xpaths(control_dict['intent']) return node(u"group", *children, **attrs)
def xml_control(self): control_dict = self.control label_and_hint = self.xml_label_and_hint() control_dict['ref'] = self.get_xpath() # for SurveyCTO's support for external intents, resolve field references in appearance column: survey = self.get_root() appearance = control_dict.get('appearance') if appearance is not None: control_dict['appearance'] = survey.insert_xpaths(appearance) 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 choice_filter: query += '[' + choice_filter + ']' result.setAttribute('query', query) return result
def xml_binding(self): """ Return the binding for this survey element. """ survey = self.get_root() bind_dict = self.bind.copy() if self.get('flat'): # Don't generate bind element for flat groups. return None if bind_dict: for k, v in bind_dict.items(): # I think all the binding conversions should be happening on # the xls2json side. if hashable(v) and v in self.binding_conversions: v = self.binding_conversions[v] if k == u'jr:constraintMsg' and type(v) is dict: v = "jr:itext('%s')" % self._translation_path( u'jr:constraintMsg') if k == u'jr:requiredMsg' and type(v) is dict: v = "jr:itext('%s')" % self._translation_path( u'jr:requiredMsg') if k == u'jr:noAppErrorString' and type(v) is dict: v = "jr:itext('%s')" % self._translation_path( u'jr:noAppErrorString') bind_dict[k] = survey.insert_xpaths(v) return node(u"bind", nodeset=self.get_xpath(), **bind_dict) return None
def xml_binding(self): """ Return the binding for this survey element. """ survey = self.get_root() bind_dict = self.bind.copy() if self.get('flat'): # Don't generate bind element for flat groups. return None if bind_dict: for k, v in bind_dict.items(): #I think all the binding conversions should be happening on the xls2json side. if hashable(v) and v in self.binding_conversions: v = self.binding_conversions[v] if k == u'jr:constraintMsg' and type(v) is dict: v = "jr:itext('%s')" % self._translation_path(u'jr:constraintMsg') if k == u'jr:requiredMsg' and type(v) is dict: v = "jr:itext('%s')" % self._translation_path(u'jr:requiredMsg') if k == u'jr:noAppErrorString' and type(v) is dict: v = "jr:itext('%s')" % self._translation_path(u'jr:noAppErrorString') try: bind_dict[k] = survey.insert_xpaths(v) except PyXFormError as e: referred_field_name = re.findall(r"\$\{(.*?)\}", v)[0] if 'multiple' in e.message: #Hacky way Need to change custom_message = "There is more than one question with same name %s" % referred_field_name else: custom_message = "There is no question with name %s" % referred_field_name raise BindError(self, k, custom_message) return node(u"bind", nodeset=self.get_xpath(), **bind_dict) return None
def xml_binding(self): """ Return the binding for this survey element. """ survey = self.get_root() bind_dict = self.bind.copy() if self.get('flat'): # Don't generate bind element for flat groups. return None if bind_dict: for k, v in bind_dict.items(): #I think all the binding conversions should be happening on the xls2json side. if hashable(v) and v in self.binding_conversions: v = self.binding_conversions[v] if k == u'jr:constraintMsg' and type(v) is dict: v = "jr:itext('%s')" % self._translation_path( u'jr:constraintMsg') if k == u'jr:requiredMsg' and type(v) is dict: v = "jr:itext('%s')" % self._translation_path( u'jr:requiredMsg') if k == u'jr:noAppErrorString' and type(v) is dict: v = "jr:itext('%s')" % self._translation_path( u'jr:noAppErrorString') bind_dict[k] = survey.insert_xpaths(v) return node(u"bind", nodeset=self.get_xpath(), **bind_dict) return None
def xml(self): item = node(u"item") self.xml_label() item.appendChild(self.xml_label()) item.appendChild(self.xml_value()) return item
def xml_control(self): control_dict = self.control if control_dict.get("bodyless"): return None children = [] attrs = {} if not self.get('flat'): attrs['ref'] = self.get_xpath() if pyxform.constants.LABEL in self and len(self[pyxform.constants.LABEL]) > 0: children.append(self.xml_label()) for n in Section.xml_control(self): children.append(n) if pyxform.constants.APPEARANCE in control_dict: attrs[pyxform.constants.APPEARANCE] = control_dict[pyxform.constants.APPEARANCE] if u"intent" in control_dict: survey = self.get_root() attrs['intent'] = survey.insert_xpaths(control_dict['intent']) return node(pyxform.constants.GROUP, *children, **attrs)
def xml_instance(self, **kwargs): """ Creates an xml representation of the section """ result = node(self.name, **kwargs) for child in self.children: result.appendChild(child.xml_instance()) return result
def xml_control(self): assert self.bind[u"type"] in [ u"select", u"select1" ] #Why select1? -- odk/jr use select1 for single-option-select control_dict = self.control if u"appearance" in control_dict: result = node(self.bind[u"type"], ref=self.get_xpath(), appearance=control_dict[u"appearance"]) else: result = node(self.bind[u"type"], ref=self.get_xpath()) for n in self.xml_label_and_hint(): result.appendChild(n) for n in [o.xml() for o in self.children]: result.appendChild(n) return result
def xml(self): result = node(u"tag", key=self.name) self.xml_label() result.appendChild(self.xml_label()) for choice in self.children: result.appendChild(choice.xml()) return result
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)
def xml_control(self): assert self.get_bind()[u"type"] in [u"select", u"select1"] result = node(self.get_bind()[u"type"], ref=self.get_xpath()) for n in self.xml_label_and_hint(): result.appendChild(n) for n in [o.xml() for o in self._children]: result.appendChild(n) return result
def xml_control(self): control_dict = self.control if u"appearance" in control_dict: return node( u"upload", ref=self.get_xpath(), mediatype=self._get_media_type(), appearance=control_dict[u"appearance"], *self.xml_label_and_hint() ) else: return node( u"upload", ref=self.get_xpath(), mediatype=self._get_media_type(), *self.xml_label_and_hint() )