def test_answers_can_be_imported_from_xml(self): surv = Survey(name="data") surv.add_child( create_survey_element_from_dict( {"type": "text", "name": "name", "label": "Name"} ) ) surv.add_child( create_survey_element_from_dict( { "type": "integer", "name": "users_per_month", "label": "Users per month", } ) ) surv.add_child( create_survey_element_from_dict( {"type": "gps", "name": "geopoint", "label": "gps"} ) ) surv.add_child( create_survey_element_from_dict({"type": "imei", "name": "device_id"}) ) instance = surv.instantiate() import_xml = self.config.get( self.cls_name, "test_answers_can_be_imported_from_xml" ) instance.import_from_xml(import_xml)
def test_answers_can_be_imported_from_xml(self): surv = Survey(name=u"data") surv.add_child( create_survey_element_from_dict({ u'type': u'text', u'name': u'name', u"label": u"Name" })) surv.add_child( create_survey_element_from_dict({ u'type': u'integer', u'name': u'users_per_month', u"label": u"Users per month" })) surv.add_child( create_survey_element_from_dict({ u'type': u'gps', u'name': u'geopoint', u'label': u'gps' })) surv.add_child( create_survey_element_from_dict({ u'type': u'imei', u'name': u'device_id' })) instance = surv.instantiate() import_xml = self.config.get(self.cls_name, "test_answers_can_be_imported_from_xml") instance.import_from_xml(import_xml)
def test_answers_can_be_imported_from_xml(self): surv = Survey(name="data") surv.add_child( create_survey_element_from_dict({ "type": "text", "name": "name", "label": "Name" })) surv.add_child( create_survey_element_from_dict({ "type": "integer", "name": "users_per_month", "label": "Users per month", })) surv.add_child( create_survey_element_from_dict({ "type": "gps", "name": "geopoint", "label": "gps" })) surv.add_child( create_survey_element_from_dict({ "type": "imei", "name": "device_id" })) instance = surv.instantiate() import_xml = self.config.get(self.cls_name, "test_answers_can_be_imported_from_xml") instance.import_from_xml(import_xml)
def _load_registration_survey_object(): """ Loads a registration survey with all the values necessary to register a surveyor. """ survey = Survey(name="registration", id_string="registration") survey.add_child( create_survey_element_from_dict({ 'type': 'text', 'name': 'name', 'label': 'Name' })) survey.add_child( create_survey_element_from_dict({ 'type': 'start time', 'name': 'start' })) survey.add_child( create_survey_element_from_dict({ 'type': 'end time', 'name': 'end' })) survey.add_child( create_survey_element_from_dict({ 'type': 'imei', 'name': 'device_id' })) return survey
def build(self): """ Creates the survey questions for the XForm a FLOIP descriptor. """ if not self._package.resources: raise ValidationError("At least one data resource is required.") resource = self._package.resources[0] if 'schema' not in resource.descriptor: raise ValidationError("The 'schema' object is missing in resource") if 'questions' not in resource.descriptor['schema']: raise ValidationError( "The 'questions' object is missing from schema") questions = resource.descriptor['schema']['questions'] if isinstance(questions, dict): question_keys = list(questions.keys()) question_keys.sort() for name in question_keys: xform_from_floip_dict(self._survey, name, questions[name]) elif isinstance(questions, list): for question in questions: for name in question: xform_from_floip_dict(self._survey, name, question[name]) else: raise ValidationError( "Expecting 'questions' to be an object or array") meta_dict = { "name": "meta", "type": "group", "control": { "bodyless": True }, "children": [{ "name": "instanceID", "type": "calculate", "bind": { "calculate": "concat('uuid:', uuid())" } }, { "name": "contactID", "type": "string", }, { "name": "sessionID", "type": "string", }] } # yapf: disable self._survey.add_child(create_survey_element_from_dict(meta_dict)) self._survey.validate() # check that we can recreate the survey object from the survey JSON create_survey_element_from_dict(self._survey.to_json_dict())
def test_simple_survey_answering(self): surv = Survey(name=u"Water") q = create_survey_element_from_dict({u"type":u"text", u"name":u"color", u"label": u"Color"}) q2 = create_survey_element_from_dict({u"type":u"text", u"name":u"feeling", u"label": u"Feeling"}) surv.add_child(q) surv.add_child(q2) i = SurveyInstance(surv) i.answer(name=u"color", value=u"blue") self.assertEquals(i.answers()[u'color'], u"blue") i.answer(name=u"feeling", value=u"liquidy") self.assertEquals(i.answers()[u'feeling'], u"liquidy")
def test_include_json(self): excel_reader = SurveyReader("pyxform/tests/include_json.xls") d = excel_reader.to_dict() survey_in = create_survey_element_from_dict(d) for k, v in survey_in.to_dict().items(): if k!="name": self.assertEqual(v, self.survey_out_dict[k])
def test_include(self): excel_reader = SurveyReader("pyxform/tests/include.xls") d = excel_reader.to_dict() survey = create_survey_element_from_dict(d) expected_dict = { u'name': 'include', u'type': u'survey', u'children': [ { u'name': u'name', u'label': {u'English': u"What's your name?"}, u'type': u'text' }, { u'name': u'good_day', u'label': {u'english': u'have you had a good day today?'}, u'type': u'select one', u'children': [ { u'name': u'yes', u'label': {u'english': u'yes'} }, { u'name': u'no', u'label': {u'english': u'no'} } ]}]} self.assertEqual(survey.to_dict(), expected_dict)
def xform_from_floip_dict(survey, name, values): """ Creates an XForm SurveyElement from FLOIP Result questions specification. survey - a pyxform Survey object name - the floip question name or uuid values - the floip question object with the type, label and question options for the question. """ question_type = QUESTION_TYPES[values['type']] question_dict = { 'name': name, 'label': values['label'], 'type': question_type } options = values.get('type_options') if question_type in SELECT_QUESTION: question_dict['choices'] = [{ 'label': x, 'name': x } for x in options['choices']] if options and 'range' in options: assert len(options['range']) > 1, "range requires atleast two values." start, end = options['range'][0], options['range'][1] constraint = '. >= %(start)s and . <= %(end)s' % { 'start': start, 'end': end } if 'bind' not in question_dict: question_dict['bind'] = {} question_dict['bind'].update({'constraint': constraint}) question = create_survey_element_from_dict(question_dict) survey.add_child(question) return question
def test_select_one_question_multilingual(self): """ Test the lowest common denominator of question types. """ simple_select_one_json = { u"label" : {u"f": u"ftext",u"e": u"etext"}, u"type" : u"select one", u"name" : u"qname", u"choices" : [ {u"label": {u"f": u"fa",u"e": u"ea"},u"name": u"a"}, {u"label": {u"f": u"fb",u"e": u"eb"},u"name": u"b"} ] } # I copied the response in, since this is not our method of testing # valid return values. expected_select_one_control_xml = u"""<select1 ref="/test/qname"><label ref="jr:itext('/test/qname:label')"/><item><label ref="jr:itext('/test/qname/a:label')"/><value>a</value></item><item><label ref="jr:itext('/test/qname/b:label')"/><value>b</value></item></select1>""" expected_select_one_binding_xml = u""" <bind nodeset="/test/qname" required="true()" type="select1"/> """.strip() q = create_survey_element_from_dict(simple_select_one_json) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_select_one_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_select_one_binding_xml)
def test_specify_other(self): excel_reader = SurveyReader("pyxform/tests/specify_other.xls") d = excel_reader.to_dict() survey = create_survey_element_from_dict(d) expected_dict = { u'name': 'specify_other', u'type': u'survey', u'children': [ { u'name': u'sex', u'label': {u'English': u'What sex are you?'}, u'type': u'select one', u'children': [ { u'name': u'male', u'label': {u'English': u'Male'} }, { u'name': u'female', u'label': {u'English': u'Female'} }, { u'name': u'other', u'label': u'Other' } ] }, { u'name': u'sex_other', u'bind': {u'relevant': u"selected(../sex, 'other')"}, u'label': u'Specify other.', u'type': u'text'} ] } self.assertEqual(survey.to_dict(), expected_dict)
def test_simple_select_all_question_multilingual(self): """ not sure how select all questions should show up... """ simple_select_all_question = { "label": {"f": "f choisit", "e": "e choose"}, "type": "select all that apply", "name": "select_all_q", "choices": [ {"label": {"f": "ff", "e": "ef"}, "name": "f"}, {"label": {"f": "fg", "e": "eg"}, "name": "g"}, {"label": {"f": "fh", "e": "eh"}, "name": "h"}, ], } expected_select_all_control_xml = self.config.get( self.cls_name, "test_simple_select_all_question_multilingual_control" ) expected_select_all_binding_xml = self.config.get( self.cls_name, "test_simple_select_all_question_multilingual_binding" ) q = create_survey_element_from_dict(simple_select_all_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_select_all_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_select_all_binding_xml)
def xls2xform_convert( xlsform_path, xform_path, validate=True, pretty_print=True, enketo=False ): warnings = [] json_survey = xls2json.parse_file_to_json(xlsform_path, warnings=warnings) survey = builder.create_survey_element_from_dict(json_survey) # Setting validate to false will cause the form not to be processed by # ODK Validate. # This may be desirable since ODK Validate requires launching a subprocess # that runs some java code. survey.print_xform_to_file( xform_path, validate=validate, pretty_print=pretty_print, warnings=warnings, enketo=enketo, ) output_dir = os.path.split(xform_path)[0] if has_external_choices(json_survey): itemsets_csv = os.path.join(output_dir, "itemsets.csv") choices_exported = sheet_to_csv(xlsform_path, itemsets_csv, "external_choices") if not choices_exported: warnings.append( "Could not export itemsets.csv, perhaps the " "external choices sheet is missing." ) else: logger.info("External choices csv is located at: %s", itemsets_csv) return warnings
def sendForm(self): # get the fields model like name , widget type, options etc. version = str(datetime.date.today()) print('version is' + version) layer = self.getLayer() self.dlg.getCurrentService().updateFields(layer) fieldDict = self.getFieldsModel(layer) print('fieldDict', fieldDict) surveyDict = { "name": layer.name(), "title": layer.name(), 'VERSION': version, "instance_name": 'uuid()', "submission_url": '', "default_language": 'default', 'id_string': layer.name(), 'type': 'survey', 'children': fieldDict } survey = create_survey_element_from_dict(surveyDict) xml = survey.to_xml(validate=None, warnings=warnings) os.chdir(os.path.expanduser('~')) with open('Xform.xml', 'w') as xForm: xForm.write(xml) self.dlg.getCurrentService().sendForm(layer.name(), 'Xform.xml')
def test_simple_integer_question_type_multilingual(self): """ not sure how integer questions should show up. """ simple_integer_question = { u"label": {u"f": u"fc", u"e": u"ec"}, u"type": u"integer", u"name": u"integer_q", u"attributes": {} } expected_integer_control_xml = u""" <input ref="/test/integer_q"><label ref="jr:itext('/test/integer_q:label')"/></input> """.strip() expected_integer_binding_xml = u""" <bind nodeset="/test/integer_q" type="int"/> """.strip() q = create_survey_element_from_dict(simple_integer_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_integer_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_integer_binding_xml)
def test_select_one_question_multilingual(self): """ Test the lowest common denominator of question types. """ simple_select_one_json = { "label": {"f": "ftext", "e": "etext"}, "type": "select one", "name": "qname", "choices": [ {"label": {"f": "fa", "e": "ea"}, "name": "a"}, {"label": {"f": "fb", "e": "eb"}, "name": "b"}, ], } # I copied the response in, since this is not our method of testing # valid return values. expected_select_one_control_xml = self.config.get( self.cls_name, "test_select_one_question_multilingual_control" ) expected_select_one_binding_xml = self.config.get( self.cls_name, "test_select_one_question_multilingual_binding" ) q = create_survey_element_from_dict(simple_select_one_json) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_select_one_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_select_one_binding_xml)
def test_simple_select_all_question_multilingual(self): """ not sure how select all questions should show up... """ simple_select_all_question = { u"label": {u"f": u"f choisit", u"e": u"e choose"}, u"type": u"select all that apply", u"name": u"select_all_q", u"choices": [ {u"label": {u"f": u"ff", u"e": u"ef"}, u"name": u"f"}, {u"label": {u"f": u"fg", u"e": u"eg"}, u"name": u"g"}, {u"label": {u"f": u"fh", u"e": u"eh"}, u"name": u"h"} ] } expected_select_all_control_xml = u"""<select ref="/test/select_all_q"><label ref="jr:itext('/test/select_all_q:label')"/><hint>Select all that apply.</hint><item><label ref="jr:itext('/test/select_all_q/f:label')"/><value>f</value></item><item><label ref="jr:itext('/test/select_all_q/g:label')"/><value>g</value></item><item><label ref="jr:itext('/test/select_all_q/h:label')"/><value>h</value></item><item><label>None</label><value>none</value></item></select>""" expected_select_all_binding_xml = u""" <bind constraint="(.='none' or not(selected(., 'none')))" nodeset="/test/select_all_q" required="true()" type="select"/> """.strip() q = create_survey_element_from_dict(simple_select_all_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_select_all_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_select_all_binding_xml)
def exportXForm(self, fileName=None, submission_url=None): workDir = QgsProject.instance().readPath("./") if not fileName: fileName = QFileDialog().getSaveFileName(None, self.tr("Save XForm"), workDir, "*.xml") exportingToGDrive = None elif self.settingsDlg.getCurrentService().hasValue( 'data collection table ID'): exportingToGDrive = True else: exportingToGDrive = None if QFileInfo(fileName).suffix() != "xml": fileName += ".xml" json_out = self.dlg.treeView.renderToDict( service=self.settingsDlg.getServiceName()) xForm_id = json_out["name"] if exportingToGDrive: #if exporting to google drive a submission_url is embedded in XFORM if self.settingsDlg.getCurrentService().getValue( 'data collection table ID') == "": #autocreated submission_url = self.settingsDlg.setDataSubmissionTable( xForm_id) else: #user defined submission_url = 'https://docs.google.com/spreadsheets/d/%s/edit' % self.settingsDlg.getCurrentService( ).getValue('data collection table ID') if submission_url: json_out["submission_url"] = submission_url survey = create_survey_element_from_dict(json_out) warnings = [] xform = survey.to_xml(validate=None, warnings=warnings) with io.open(fileName, "w", encoding="utf8") as xml_file: xml_file.write(xform) #with io.open(fileName+'.json', "wb") as json_file: # json.dump(json_out,json_file) return xForm_id
def xls2xform_convert(xlsform_path, xform_path, validate=True, pretty_print=True, enketo=False): warnings = [] json_survey = xls2json.parse_file_to_json(xlsform_path, warnings=warnings) survey = builder.create_survey_element_from_dict(json_survey) # Setting validate to false will cause the form not to be processed by # ODK Validate. # This may be desirable since ODK Validate requires launching a subprocess # that runs some java code. survey.print_xform_to_file( xform_path, validate=validate, pretty_print=pretty_print, warnings=warnings, enketo=enketo, ) output_dir = os.path.split(xform_path)[0] if has_external_choices(json_survey): itemsets_csv = os.path.join(output_dir, "itemsets.csv") choices_exported = sheet_to_csv(xlsform_path, itemsets_csv, "external_choices") if not choices_exported: warnings.append("Could not export itemsets.csv, perhaps the " "external choices sheet is missing.") else: logger.info("External choices csv is located at: %s", itemsets_csv) return warnings
def render(self, data, *args, **kwargs): charset = 'utf-8' root_node = 'xforms' xmlns = "http://openrosa.org/xforms/xformsList" if 'detail' in data.keys(): stream = StringIO() xml = SimplerXMLGenerator(stream, charset) xml.startDocument() xml.startElement(root_node, {'xmlns': xmlns}) for key, value in six.iteritems(data): xml.startElement(key, {}) xml.characters(smart_text(value)) xml.endElement(key) xml.endElement(root_node) xml.endDocument() return stream.getvalue() else: json = self.transform_to_xform_json(data) survey = create_survey_element_from_dict(json) xml = survey.xml() fix_languages(xml) xml = xml.toxml() xml = self.insert_version_attribute(xml, data.get('id_string'), data.get('version')) xml = self.insert_uuid_bind(xml, data.get('id_string')) return xml
def test_select_one_question_multilingual(self): """ Test the lowest common denominator of question types. """ simple_select_one_json = { u"label" : {u"f": u"ftext",u"e": u"etext"}, u"type" : u"select one", u"name" : u"qname", u"choices" : [ {u"label": {u"f": u"fa",u"e": u"ea"},u"name": u"a"}, {u"label": {u"f": u"fb",u"e": u"eb"},u"name": u"b"} ] } # I copied the response in, since this is not our method of testing # valid return values. expected_select_one_control_xml = u"""<select1 ref="/test/qname"><label ref="jr:itext('/test/qname:label')"/><item><label ref="jr:itext('/test/qname/a:label')"/><value>a</value></item><item><label ref="jr:itext('/test/qname/b:label')"/><value>b</value></item></select1>""" expected_select_one_binding_xml = u""" <bind nodeset="/test/qname" type="select1"/> """.strip() q = create_survey_element_from_dict(simple_select_one_json) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_select_one_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_select_one_binding_xml)
def test_simple_phone_number_question_type_multilingual(self): """ not sure how phone number questions should show up. """ simple_phone_number_question = { "label": { "f": "fe", "e": "ee" }, "type": "phone number", "name": "phone_number_q", } expected_phone_number_control_xml = self.config.get( self.cls_name, "test_simple_phone_number_question_type_multilingual_control") expected_phone_number_binding_xml = self.config.get( self.cls_name, "test_simple_phone_number_question_type_multilingual_binding") q = create_survey_element_from_dict(simple_phone_number_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_phone_number_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_phone_number_binding_xml)
def test_simple_integer_question_type_multilingual(self): """ not sure how integer questions should show up. """ simple_integer_question = { u"label": { u"f": u"fc", u"e": u"ec" }, u"type": u"integer", u"name": u"integer_q", u"attributes": {} } expected_integer_control_xml = u""" <input ref="/test/integer_q"><label ref="jr:itext('/test/integer_q:label')"/></input> """.strip() expected_integer_binding_xml = u""" <bind nodeset="/test/integer_q" type="int"/> """.strip() q = create_survey_element_from_dict(simple_integer_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_integer_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_integer_binding_xml)
def cli(xlsform: BinaryIO) -> None: """xlson - XLSForm to native form JSON.""" survey = create_survey_element_from_dict( parse_file_to_json(xlsform.name, file_object=xlsform) ) form = create_native_form(survey.to_json_dict()) click.echo(json.dumps(form, indent=4))
def prepareSendForm(self, layer): self.updateFields(layer) version = str(datetime.date.today()) fieldDict = self.getFieldsModel(layer) print('fieldDict', fieldDict) surveyDict = { "name": layer.name(), "title": layer.name(), 'VERSION': version, "instance_name": 'uuid()', "submission_url": '', "default_language": 'default', 'id_string': layer.name(), 'type': 'survey', 'children': fieldDict } survey = create_survey_element_from_dict(surveyDict) try: xml = survey.to_xml(validate=None, warnings='warnings') os.chdir(os.path.expanduser('~')) self.sendForm(layer.name(), xml) except Exception as e: print("error in creating xform xml", e) self.iface.messageBar().pushCritical( self.tag, self.tr("Survey form can't be created, check layer name"))
def test_simple_phone_number_question_type_multilingual(self): """ not sure how phone number questions should show up. """ simple_phone_number_question = { u"label": { u"f": u"fe", u"e": u"ee" }, u"type": u"phone number", u"name": u"phone_number_q", } expected_phone_number_control_xml = u"""<input ref="/test/phone_number_q"><label ref="jr:itext('/test/phone_number_q:label')"/><hint>Enter numbers only.</hint></input>""" expected_phone_number_binding_xml = u""" <bind constraint="regex(., '^\d*$')" nodeset="/test/phone_number_q" type="string"/> """.strip() q = create_survey_element_from_dict(simple_phone_number_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_phone_number_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_phone_number_binding_xml)
def get_merged_xform_survey(xforms): """ Genertates a new pyxform survey object from the intersection of fields of the xforms being merged. :param xforms: A list of XForms of at least length 2. """ if len(xforms) < 2: raise serializers.ValidationError(_('Expecting at least 2 xforms')) xform_sets = [_get_fields_set(xform) for xform in xforms] merged_xform_dict = json.loads(xforms[0].json) children = merged_xform_dict.pop('children') merged_xform_dict['children'] = [] intersect = set(xform_sets[0]).intersection(*xform_sets[1:]) intersect = set([__ for (__, ___) in intersect]) merged_xform_dict['children'] = _get_elements(children, intersect) if '_xpath' in merged_xform_dict: del merged_xform_dict['_xpath'] is_empty = True for child in merged_xform_dict['children']: if child['name'] != 'meta' and is_empty: is_empty = False if is_empty: raise serializers.ValidationError(_("No matching fields in xforms.")) return create_survey_element_from_dict(merged_xform_dict)
def test_answers_can_be_imported_from_xml(self): surv = Survey(name=u"data") surv.add_child(create_survey_element_from_dict({ \ u'type':u'text', u'name':u'name', u"label": u"Name"})) surv.add_child(create_survey_element_from_dict({ \ u'type':u'integer', u'name':u'users_per_month', u"label": u"Users per month"})) surv.add_child(create_survey_element_from_dict({ \ u'type':u'gps', u'name':u'geopoint', u'label': u'gps'})) surv.add_child(create_survey_element_from_dict({ \ u'type':u'imei', u'name':u'device_id'})) instance = surv.instantiate() instance.import_from_xml(u""" <?xml version='1.0' ?><data id="build_WaterSimple_1295821382"><name>JK Resevoir</name><users_per_month>300</users_per_month><geopoint>40.783594633609184 -73.96436698913574 300.0 4.0</geopoint></data> """.strip())
def to_xform( self, data, options=None ): options = options or {} data = self.to_simple( data, options ) if 'manifest' in data: # Return the xform manifest return self.to_manifest( data ) elif 'objects' in data: # Return the formList representation of our objects if they are # present. return self.to_formList( data.get( 'objects', [] ) ) elif 'id' in data: # Accessing a single repo object! Convert completely into the # xform format. xform = {} xform[ 'name' ] = data.get( 'name' ) # TODO: Fix pyxform to handle this correctly. # data.get( 'type' ) xform[ 'type' ] = 'survey' xform[ 'default_language' ] = data.get( 'default_language', 'default' ) xform[ 'children' ] = data.get( 'children' ) return create_survey_element_from_dict( xform )._to_pretty_xml() else: raise Exception( data ) return None
def test_simple_integer_question_type_multilingual(self): """ not sure how integer questions should show up. """ simple_integer_question = { "label": {"f": "fc", "e": "ec"}, "type": "integer", "name": "integer_q", "attributes": {}, } expected_integer_control_xml = self.config.get( self.cls_name, "test_simple_integer_question_type_multilingual_control" ) expected_integer_binding_xml = self.config.get( self.cls_name, "test_simple_integer_question_type_multilingual_binding" ) q = create_survey_element_from_dict(simple_integer_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_integer_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_integer_binding_xml)
def test_answers_can_be_imported_from_xml(self): surv = Survey(name=u"data") surv.add_child(create_survey_element_from_dict({ \ u'type':u'text', u'name':u'name', u"label": u"Name"})) surv.add_child(create_survey_element_from_dict({ \ u'type':u'integer', u'name':u'users_per_month', u"label": u"Users per month"})) surv.add_child(create_survey_element_from_dict({ \ u'type':u'gps', u'name':u'geopoint', u'label': u'gps'})) surv.add_child(create_survey_element_from_dict({ \ u'type':u'imei', u'name':u'device_id'})) instance = surv.instantiate() instance.import_from_xml(u""" <?xml version='1.0' ?><data id="build_WaterSimple_1295821382"><name>JK Resevoir</name><users_per_month>300</users_per_month><geopoint>40.783594633609184 -73.96436698913574 300.0 4.0</geopoint></data> """.strip())
def test_simple_select_all_question_multilingual(self): """ not sure how select all questions should show up... """ simple_select_all_question = { u"label": {u"f": u"f choisit", u"e": u"e choose"}, u"type": u"select all that apply", u"name": u"select_all_q", u"choices": [ {u"label": {u"f": u"ff", u"e": u"ef"}, u"name": u"f"}, {u"label": {u"f": u"fg", u"e": u"eg"}, u"name": u"g"}, {u"label": {u"f": u"fh", u"e": u"eh"}, u"name": u"h"} ] } expected_select_all_control_xml = u"""<select ref="/test/select_all_q"><label ref="jr:itext('/test/select_all_q:label')"/><hint>Select all that apply.</hint><item><label ref="jr:itext('/test/select_all_q/f:label')"/><value>f</value></item><item><label ref="jr:itext('/test/select_all_q/g:label')"/><value>g</value></item><item><label ref="jr:itext('/test/select_all_q/h:label')"/><value>h</value></item></select>""" expected_select_all_binding_xml = u""" <bind nodeset="/test/select_all_q" type="select"/> """.strip() q = create_survey_element_from_dict(simple_select_all_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_select_all_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_select_all_binding_xml)
def test_simple_phone_number_question_type_multilingual(self): """ not sure how phone number questions should show up. """ simple_phone_number_question = { u"label": {u"f": u"fe", u"e": u"ee"}, u"type": u"phone number", u"name": u"phone_number_q", } expected_phone_number_control_xml = self.config.get( self.cls_name, "test_simple_phone_number_question_type_multilingual_control") expected_phone_number_binding_xml = self.config.get( self.cls_name, "test_simple_phone_number_question_type_multilingual_binding") q = create_survey_element_from_dict(simple_phone_number_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_phone_number_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_phone_number_binding_xml)
def test_include_json(self): excel_reader = SurveyReader("pyxform/tests/include_json.xls") d = excel_reader.to_dict() survey_in = create_survey_element_from_dict(d) for k, v in survey_in.to_dict().items(): if k != "name": self.assertEqual(v, self.survey_out_dict[k])
def test_simple_integer_question_type_multilingual(self): """ not sure how integer questions should show up. """ simple_integer_question = { u"label": {u"f": u"fc", u"e": u"ec"}, u"type": u"integer", u"name": u"integer_q", u"attributes": {} } expected_integer_control_xml = self.config.get( self.cls_name, "test_simple_integer_question_type_multilingual_control") expected_integer_binding_xml = self.config.get( self.cls_name, "test_simple_integer_question_type_multilingual_binding") q = create_survey_element_from_dict(simple_integer_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_integer_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_integer_binding_xml)
def test_simple_decimal_question_multilingual(self): """ not sure how decimal should show up. """ simple_decimal_question = { "label": { "f": "f text", "e": "e text" }, "type": "decimal", "name": "decimal_q", "attributes": {}, } expected_decimal_control_xml = self.config.get( self.cls_name, "test_simple_decimal_question_multilingual_control") expected_decimal_binding_xml = self.config.get( self.cls_name, "test_simple_decimal_question_multilingual_binding") q = create_survey_element_from_dict(simple_decimal_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_decimal_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_decimal_binding_xml)
def test_convert_toJSON_multi_language(self): """ Test that it's possible to convert XLSForms with multiple languages to JSON and back into XML without losing any of the required information """ md = """ | survey | | | type | name | label:Eng | label:Fr | | | text | name | Name | Prénom | | | select_multiple fruits | fruit | Fruit | Fruit | | | | | | | | choices | list name | name | label:Eng | label:Fr | | | fruits | 1 | Mango | Mangue | | | fruits | 2 | Orange | Orange | | | fruits | 3 | Apple | Pomme | """ survey = self.md_to_pyxform_survey( md_raw=md, kwargs={"id_string": "id", "name": "multi-language", "title": "some-title"}, autoname=False, ) expected_xml = survey.to_xml() generated_json = survey.to_json() survey = create_survey_element_from_dict(json.loads(generated_json)) self.assertEqual(expected_xml, survey.to_xml())
def render(self, data, *args, **kwargs): charset = 'utf-8' root_node = 'xforms' xmlns = "http://openrosa.org/xforms/xformsList" if 'detail' in data.keys(): stream = StringIO() xml = SimplerXMLGenerator(stream, charset) xml.startDocument() xml.startElement(root_node, {'xmlns': xmlns}) for key, value in six.iteritems(data): xml.startElement(key, {}) xml.characters(smart_text(value)) xml.endElement(key) xml.endElement(root_node) xml.endDocument() return stream.getvalue() else: json = self.transform_to_xform_json(data) survey = create_survey_element_from_dict(json) xml = survey.xml() fix_languages(xml) xml = xml.toxml() xml = self.insert_version_attribute(xml, data.get('id_string'), data.get('version')) xml = self.insert_uuid_bind(xml, data.get('id_string')) return xml
def test_question_type_string(self): simple_string_json = { "label": { "French": "Nom du travailleur agricole:", "English": "Name of Community Agricultural Worker", }, "type": "text", "name": "enumerator_name", } q = create_survey_element_from_dict(simple_string_json) expected_string_control_xml = self.config.get( self.cls_name, "test_question_type_string_control" ) expected_string_binding_xml = self.config.get( self.cls_name, "test_question_type_string_binding" ) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_string_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_string_binding_xml)
def test_answers_can_be_imported_from_xml(self): surv = Survey(name=u"data") surv.add_child(create_survey_element_from_dict({ u'type': u'text', u'name': u'name', u"label": u"Name"})) surv.add_child(create_survey_element_from_dict({ u'type': u'integer', u'name': u'users_per_month', u"label": u"Users per month"})) surv.add_child(create_survey_element_from_dict({ u'type': u'gps', u'name': u'geopoint', u'label': u'gps'})) surv.add_child(create_survey_element_from_dict({ u'type': u'imei', u'name': u'device_id'})) instance = surv.instantiate() import_xml = self.config.get( self.cls_name, "test_answers_can_be_imported_from_xml") instance.import_from_xml(import_xml)
def create_from_form(self, xls_form=None, original_file=None, project=None): try: with transaction.atomic(): errors = [] instance = self.model( xls_form=xls_form, original_file=original_file, project=project ) json = parse_file_to_json(instance.xls_form.file.name) has_default_language = ( 'default_language' in json and json['default_language'] != 'default' ) if (has_default_language and not check_for_language(json['default_language'])): raise InvalidXLSForm( ["Default language code '{}' unknown".format( json['default_language'] )] ) is_multilingual = multilingual_label_check(json['children']) if is_multilingual and not has_default_language: raise InvalidXLSForm(["Multilingual XLS forms must have " "a default_language setting"]) instance.default_language = json['default_language'] if instance.default_language == 'default': instance.default_language = '' instance.filename = json.get('name') instance.title = json.get('title') instance.id_string = json.get('id_string') survey = create_survey_element_from_dict(json) xml_form = survey.xml() fix_languages(xml_form) instance.save() project.current_questionnaire = instance.id project.save() create_children( children=json.get('children'), errors=errors, project=project, default_language=instance.default_language, kwargs={'questionnaire': instance} ) # all these errors handled by PyXForm so turning off for now # if errors: # raise InvalidXLSForm(errors) return instance except PyXFormError as e: raise InvalidXLSForm([str(e)])
def test_create_table_from_dict(self): d = { u"type" : u"loop", u"name" : u"my_loop", u"label" : {u"English" : u"My Loop"}, u"columns" : [ { u"name" : u"col1", u"label" : {u"English" : u"column 1"}, }, { u"name" : u"col2", u"label" : {u"English" : u"column 2"}, }, ], u"children" : [ { u"type": u"integer", u"name": u"count", u"label": {u"English": u"How many are there in this group?"} }, ] } g = create_survey_element_from_dict(d) expected_dict = { u'name': u'my_loop', u'label': {u'English': u'My Loop'}, u'type' : u'group', u'children': [ { u'name': u'col1', u'label': {u'English': u'column 1'}, u'type' : u'group', u'children': [ { u'name': u'count', u'label': {u'English': u'How many are there in this group?'}, u'type': u'integer' } ] }, { u'name': u'col2', u'label': {u'English': u'column 2'}, u'type' : u'group', u'children': [ { u'name': u'count', u'label': {u'English': u'How many are there in this group?'}, u'type': u'integer' } ] } ] } self.assertEqual(g.to_dict(), expected_dict)
def test_simple_survey_answering(self): surv = Survey(name="Water") q = create_survey_element_from_dict( {"type": "text", "name": "color", "label": "Color"} ) q2 = create_survey_element_from_dict( {"type": "text", "name": "feeling", "label": "Feeling"} ) surv.add_child(q) surv.add_child(q2) i = SurveyInstance(surv) i.answer(name="color", value="blue") self.assertEquals(i.answers()["color"], "blue") i.answer(name="feeling", value="liquidy") self.assertEquals(i.answers()["feeling"], "liquidy")
def _ss_structure_to_pyxform_survey(self, ss_structure, kwargs): # using existing methods from the builder imported_survey_json = workbook_to_json(ss_structure) # ieadlly, when all these tests are working, this would be # refactored as well survey = create_survey_element_from_dict(imported_survey_json) survey.name = kwargs.get('name') survey.title = kwargs.get('title') survey.id_string = kwargs.get('id_string') return survey
def _ss_structure_to_pyxform_survey(self, ss_structure, kwargs): # using existing methods from the builder imported_survey_json = workbook_to_json(ss_structure) # ieadlly, when all these tests are working, this would be # refactored as well survey = create_survey_element_from_dict(imported_survey_json) survey.name = kwargs.get("name") survey.title = kwargs.get("title") survey.id_string = kwargs.get("id_string") return survey
def create_survey_from_ss_struct( ss_struct, default_name='KoBoFormSurvey', default_language=u'default', warnings=None, ): dict_repr = xls2json.workbook_to_json(ss_struct, default_name, default_language, warnings) dict_repr[u'name'] = dict_repr[u'id_string'] return builder.create_survey_element_from_dict(dict_repr)
def create_from_form(self, xls_form=None, original_file=None, project=None): try: with transaction.atomic(): errors = [] instance = self.model(xls_form=xls_form, original_file=original_file, project=project) json = parse_file_to_json(instance.xls_form.file.name) has_default_language = ('default_language' in json and json['default_language'] != 'default') if (has_default_language and not check_for_language(json['default_language'])): raise InvalidQuestionnaire([ "Default language code '{}' unknown".format( json['default_language']) ]) is_multilingual = multilingual_label_check(json['children']) if is_multilingual and not has_default_language: raise InvalidQuestionnaire([ "Multilingual XLS forms must have a default_language" " setting" ]) instance.default_language = json['default_language'] if instance.default_language == 'default': instance.default_language = '' instance.filename = json.get('name') instance.title = json.get('title') instance.id_string = json.get('id_string') survey = create_survey_element_from_dict(json) xml_form = survey.xml() fix_languages(xml_form) instance.save() project.current_questionnaire = instance.id create_children(children=json.get('children'), errors=errors, project=project, default_language=instance.default_language, kwargs={'questionnaire': instance}) project.save() # all these errors handled by PyXForm so turning off for now # if errors: # raise InvalidQuestionnaire(errors) return instance except PyXFormError as e: raise InvalidQuestionnaire([str(e)])
def test_simple_survey_answering(self): surv = Survey(name=u"Water") q = create_survey_element_from_dict({ u"type": u"text", u"name": u"color" }) q2 = create_survey_element_from_dict({ u"type": u"text", u"name": u"feeling" }) surv.add_child(q) surv.add_child(q2) i = SurveyInstance(surv) i.answer(name=u"color", value=u"blue") self.assertEquals(i.answers()[u'color'], u"blue") i.answer(name=u"feeling", value=u"liquidy") self.assertEquals(i.answers()[u'feeling'], u"liquidy")
def test_simple_questions_can_be_imported_from_json(self): json_text = { "type": "survey", "name": "Exchange rate", "children": [ {"label": {"French": "Combien?", "English": "How many?"}, "type": "decimal", "name": "exchange_rate"} ], } s = create_survey_element_from_dict(json_text) self.assertEqual(s.children[0].type, "decimal")
def test_simple_survey_instantiation(self): surv = Survey(name="Simple") q = create_survey_element_from_dict( {"type": "text", "name": "survey_question", "label": "Question"} ) surv.add_child(q) i = surv.instantiate() self.assertEquals(i.keys(), ["survey_question"]) self.assertEquals(set(i.xpaths()), {"/Simple", "/Simple/survey_question"})
def _ss_structure_to_pyxform_survey(ss_structure, kwargs, warnings=None): # using existing methods from the builder imported_survey_json = workbook_to_json(ss_structure, warnings=warnings) # ideally, when all these tests are working, this would be # refactored as well survey = create_survey_element_from_dict(imported_survey_json) survey.name = kwargs.get("name", "data") survey.title = kwargs.get("title") survey.id_string = kwargs.get("id_string") return survey
def generate_sections(form): xform_survey = create_survey_element_from_dict(form) group_delimiter = '/' split_select_multiples = True binary_select_multiples = False export_builder = ExportBuilder() export_builder.GROUP_DELIMITER = group_delimiter export_builder.SPLIT_SELECT_MULTIPLES = split_select_multiples export_builder.BINARY_SELECT_MULTIPLES = binary_select_multiples export_builder.set_survey(xform_survey) return dict([(s['name'], s['elements']) for s in export_builder.sections])
def test_simple_survey_instantiation(self): surv = Survey(name=u"Simple") q = create_survey_element_from_dict({u"type":u"text", u"name":u"survey_question"}) surv.add_child(q) i = surv.instantiate() self.assertEquals(i.keys(), [u"survey_question"]) self.assertEquals(set(i.xpaths()), set([\ u"/Simple", \ u"/Simple/survey_question", \ ]))
def _load_registration_survey_object(): """ Loads a registration survey with all the values necessary to register a surveyor. """ survey = Survey(name=u"registration", id_string=u"registration") survey.add_child(create_survey_element_from_dict({ u'type': u'text', u'name': u'name', u'label': u'Name' })) survey.add_child(create_survey_element_from_dict({ u'type': u'start time', u'name': u'start' })) survey.add_child(create_survey_element_from_dict({ u'type': u'end time', u'name': u'end' })) survey.add_child(create_survey_element_from_dict({ u'type': u'imei', u'name': u'device_id' })) return survey
def test_equality_of_to_dict(self): x = SurveyReader(utils.path_to_text_fixture("group.xls")) x_results = x.to_json_dict() survey = create_survey_element_from_dict(x_results) survey_dict = survey.to_json_dict() # using the builder sets the title attribute to equal name # this won't happen through reading the excel file as done by # SurveyReader. # Now it happens. #del survey_dict[u'title'] self.maxDiff = None self.assertEqual(x_results, survey_dict)
def save(self, *args, **kwargs): skip_xls_read = kwargs.get('skip_xls_read') if self.xls and not skip_xls_read: default_name = None \ if not self.pk else self.survey.xml_instance().tagName survey_dict = process_xlsform(self.xls, default_name) if has_external_choices(survey_dict): self.has_external_choices = True survey = create_survey_element_from_dict(survey_dict) survey = check_version_set(survey) if get_columns_with_hxl(survey.get('children')): self.has_hxl_support = True # if form is being replaced, don't check for id_string uniqueness if self.pk is None: new_id_string = self.get_unique_id_string( survey.get('id_string')) self._id_string_changed = \ new_id_string != survey.get('id_string') survey['id_string'] = new_id_string # For flow results packages use the user defined id/uuid if self.xls.name.endswith('json'): self.uuid = FloipSurvey(self.xls).descriptor.get('id') if self.uuid: check_xform_uuid(self.uuid) elif self.id_string != survey.get('id_string'): raise XLSFormError(_( (u"Your updated form's id_string '%(new_id)s' must match " "the existing forms' id_string '%(old_id)s'." % { 'new_id': survey.get('id_string'), 'old_id': self.id_string}))) elif default_name and default_name != survey.get('name'): survey['name'] = default_name else: survey['id_string'] = self.id_string self.json = survey.to_json() self.xml = survey.to_xml() self.version = survey.get('version') self.last_updated_at = timezone.now() self.title = survey.get('title') self._mark_start_time_boolean() set_uuid(self) self._set_uuid_in_xml() self._set_hash() if 'skip_xls_read' in kwargs: del kwargs['skip_xls_read'] super(DataDictionary, self).save(*args, **kwargs)
def test_simple_registration_xml(self): reg_xform = Survey(name=u"Registration") name_question = create_survey_element_from_dict({ u'type': u'text', u'name': u'name', u"label": u"Name"}) reg_xform.add_child(name_question) reg_instance = reg_xform.instantiate() reg_instance.answer(name=u"name", value=u"bob") rx = reg_instance.to_xml() expected_xml = self.config.get( self.cls_name, "test_simple_registration_xml" ).format(reg_xform.id_string) self.assertEqual(rx, expected_xml)