diff --git a/onadata/apps/api/tests/fixtures/Transportation Form.xml b/onadata/apps/api/tests/fixtures/Transportation Form.xml index a4ef8631a0..76ff4058ea 100644 --- a/onadata/apps/api/tests/fixtures/Transportation Form.xml +++ b/onadata/apps/api/tests/fixtures/Transportation Form.xml @@ -2,9 +2,9 @@ transportation_2011_07_25 - + - + @@ -45,28 +45,28 @@ - + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - + - @@ -109,13 +109,13 @@ other - + - - + + - + @@ -135,9 +135,9 @@ - + - + @@ -157,9 +157,9 @@ - + - + @@ -179,9 +179,9 @@ - + - + @@ -201,9 +201,9 @@ - + - + @@ -223,9 +223,9 @@ - + - + @@ -245,9 +245,9 @@ - + - + @@ -267,9 +267,9 @@ - + - + @@ -289,9 +289,9 @@ - + - + @@ -313,7 +313,7 @@ - + diff --git a/onadata/apps/api/tests/viewsets/test_dataview_viewset.py b/onadata/apps/api/tests/viewsets/test_dataview_viewset.py index 8474bf7f69..542c8afe44 100644 --- a/onadata/apps/api/tests/viewsets/test_dataview_viewset.py +++ b/onadata/apps/api/tests/viewsets/test_dataview_viewset.py @@ -105,7 +105,7 @@ def test_get_dataview_form_definition(self): self._create_dataview() data = { - "name": "tutorial", + "name": "data", "title": "tutorial", "default_language": "default", "id_string": "tutorial", diff --git a/onadata/apps/api/tests/viewsets/test_xform_viewset.py b/onadata/apps/api/tests/viewsets/test_xform_viewset.py index bbe71920bc..3b6a2b5cda 100644 --- a/onadata/apps/api/tests/viewsets/test_xform_viewset.py +++ b/onadata/apps/api/tests/viewsets/test_xform_viewset.py @@ -572,7 +572,7 @@ def test_form_format(self): }) formid = self.xform.pk data = { - "name": "transportation", + "name": "data", "title": "transportation_2011_07_25", "default_language": "default", "id_string": "transportation_2011_07_25", @@ -634,7 +634,7 @@ def test_form_format(self): uuid_nodes = [ node for node in model_node.childNodes if node.nodeType == Node.ELEMENT_NODE and - node.getAttribute("nodeset") == "/transportation/formhub/uuid"] + node.getAttribute("nodeset") == "/data/formhub/uuid"] self.assertEqual(len(uuid_nodes), 1) uuid_node = uuid_nodes[0] uuid_node.setAttribute("calculate", "''") @@ -1381,8 +1381,12 @@ def test_publish_invalid_xls_form(self): response = view(request) self.assertEqual(response.status_code, 400) self.assertEqual(response.get('Cache-Control'), None) - error_msg = 'In strict mode, the XForm ID must be a valid slug'\ - ' and contain no spaces.' + error_msg = ('In strict mode, the XForm ID must be ' + 'a valid slug and contain no spaces.' + ' Please ensure that you have set an' + ' id_string in the settings sheet or ' + 'have modified the filename to not ' + 'contain any spaces.') self.assertEqual(response.data.get('text'), error_msg) path = os.path.join( @@ -2196,7 +2200,7 @@ def test_manager_can_update_xform_xls_file(self): fhuuid = xml.find('formhub/uuid') self.assertEqual( xml[xml[:fhuuid].rfind('=') + 2:fhuuid], - '/transportation/' + '/data/' ) view = XFormViewSet.as_view({ @@ -2233,7 +2237,7 @@ def test_manager_can_update_xform_xls_file(self): fhuuid = xml.find('formhub/uuid') self.assertEqual( xml[xml[:fhuuid].rfind('=') + 2:fhuuid], - '/transportation/' + '/data/' ) def test_update_xform_with_different_id_string_form_with_sub(self): @@ -2342,7 +2346,7 @@ def test_update_xform_xls_file_with_different_model_name(self): response = view(request, pk=form_id) self.assertEqual(response.status_code, 200) xform = XForm.objects.get(pk=form_id) - self.assertEqual('transportation', + self.assertEqual('data', xform.survey.xml_instance().tagName) def test_id_strings_should_be_unique_in_each_account(self): diff --git a/onadata/apps/logger/models/xform.py b/onadata/apps/logger/models/xform.py index 1764a5d25a..85e005ae1f 100644 --- a/onadata/apps/logger/models/xform.py +++ b/onadata/apps/logger/models/xform.py @@ -43,7 +43,8 @@ NOTES, SUBMISSION_TIME, SUBMITTED_BY, TAGS, TOTAL_MEDIA, UUID, VERSION, REVIEW_STATUS, - REVIEW_COMMENT) + REVIEW_COMMENT, + MULTIPLE_SELECT_TYPE) from onadata.libs.utils.model_tools import queryset_iterator from onadata.libs.utils.mongo import _encode_for_mongo @@ -163,7 +164,8 @@ def check_version_set(survey): def _expand_select_all_that_apply(d, key, e): - if e and e.bind.get(u"type") == u"select": + if e and e.bind.get(u"type") == u"string"\ + and e.type == MULTIPLE_SELECT_TYPE: options_selected = d[key].split() for child in e.children: new_key = child.get_abbreviated_xpath() @@ -437,7 +439,8 @@ def xpaths(self, # replace the single question column with a column for each # item in a select all that apply question. - if survey_element.bind.get(u'type') == u'select': + if survey_element.bind.get(u'type') == u'string' \ + and survey_element.type == MULTIPLE_SELECT_TYPE: result.pop() for child in survey_element.children: result.append('/'.join([path, child.name])) @@ -475,7 +478,6 @@ def get_headers(self, include_additional_headers=False): """ Return a list of headers for a csv file. """ - def shorten(xpath): xpath_list = xpath.split('/') return '/'.join(xpath_list[2:]) @@ -863,7 +865,10 @@ def save(self, *args, **kwargs): not re.search(r"^[\w-]+$", self.id_string): raise XLSFormError( _(u'In strict mode, the XForm ID must be a ' - 'valid slug and contain no spaces.')) + 'valid slug and contain no spaces. Please ensure' + ' that you have set an id_string in the settings sheet ' + 'or have modified the filename to not contain' + ' any spaces.')) if not self.sms_id_string and (update_fields is None or 'id_string' in update_fields): diff --git a/onadata/apps/main/tests/fixtures/group_names_must_be_unique.xls b/onadata/apps/main/tests/fixtures/group_names_must_be_unique.xls deleted file mode 100644 index 5ebf7f588b..0000000000 Binary files a/onadata/apps/main/tests/fixtures/group_names_must_be_unique.xls and /dev/null differ diff --git a/onadata/apps/main/tests/fixtures/group_names_must_be_unique.xlsx b/onadata/apps/main/tests/fixtures/group_names_must_be_unique.xlsx new file mode 100644 index 0000000000..62717f42c2 Binary files /dev/null and b/onadata/apps/main/tests/fixtures/group_names_must_be_unique.xlsx differ diff --git a/onadata/apps/main/tests/fixtures/transportation/Transportation Form.xml b/onadata/apps/main/tests/fixtures/transportation/Transportation Form.xml index 5288295eca..76ff4058ea 100644 --- a/onadata/apps/main/tests/fixtures/transportation/Transportation Form.xml +++ b/onadata/apps/main/tests/fixtures/transportation/Transportation Form.xml @@ -1,10 +1,10 @@ - - + + transportation_2011_07_25 - + - + @@ -41,30 +41,32 @@ + - + - - - - - - - - - - - - - + + + + + + + + + + + + + + - + - @@ -107,13 +109,13 @@ other - + - - + + - + @@ -133,9 +135,9 @@ - + - + @@ -155,9 +157,9 @@ - + - + @@ -177,9 +179,9 @@ - + - + @@ -199,9 +201,9 @@ - + - + @@ -221,9 +223,9 @@ - + - + @@ -243,9 +245,9 @@ - + - + @@ -265,9 +267,9 @@ - + - + @@ -287,9 +289,9 @@ - + - + @@ -311,5 +313,8 @@ + + + diff --git a/onadata/apps/main/tests/fixtures/transportation/transportation.xml b/onadata/apps/main/tests/fixtures/transportation/transportation.xml index 8e29952e8f..bf8d6ca5a0 100644 --- a/onadata/apps/main/tests/fixtures/transportation/transportation.xml +++ b/onadata/apps/main/tests/fixtures/transportation/transportation.xml @@ -2,9 +2,9 @@ transportation_2011_07_25 - + - + @@ -45,28 +45,28 @@ - + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - + - @@ -109,13 +109,13 @@ other - + - - + + - + @@ -135,9 +135,9 @@ - + - + @@ -157,9 +157,9 @@ - + - + @@ -179,9 +179,9 @@ - + - + @@ -201,9 +201,9 @@ - + - + @@ -223,9 +223,9 @@ - + - + @@ -245,9 +245,9 @@ - + - + @@ -267,9 +267,9 @@ - + - + @@ -289,9 +289,9 @@ - + - + @@ -313,7 +313,7 @@ - + diff --git a/onadata/apps/main/tests/test_csv_export.py b/onadata/apps/main/tests/test_csv_export.py index 86ad462165..868265bf82 100644 --- a/onadata/apps/main/tests/test_csv_export.py +++ b/onadata/apps/main/tests/test_csv_export.py @@ -67,11 +67,11 @@ def test_csv_nested_repeat_output(self): self.maxDiff = None data_dictionary = DataDictionary.objects.all()[0] xpaths = [ - u'/double_repeat/bed_net[1]/member[1]/name', - u'/double_repeat/bed_net[1]/member[2]/name', - u'/double_repeat/bed_net[2]/member[1]/name', - u'/double_repeat/bed_net[2]/member[2]/name', - u'/double_repeat/meta/instanceID' + u'/data/bed_net[1]/member[1]/name', + u'/data/bed_net[1]/member[2]/name', + u'/data/bed_net[2]/member[1]/name', + u'/data/bed_net[2]/member[2]/name', + u'/data/meta/instanceID' ] self.assertEquals(data_dictionary.xpaths(repeat_iterations=2), xpaths) # test csv diff --git a/onadata/apps/main/tests/test_form_errors.py b/onadata/apps/main/tests/test_form_errors.py index 346f7117dc..8b0fc360bf 100644 --- a/onadata/apps/main/tests/test_form_errors.py +++ b/onadata/apps/main/tests/test_form_errors.py @@ -93,12 +93,12 @@ def test_spaced_xlsform(self): self.xform.save() xls_path = os.path.join(self.this_directory, "fixtures", "transportation", "tutorial .xls") - msg = ("The name 'tutorial ' is an invalid XML tag, it contains an" - " invalid character ' '. Names must begin with a letter, colon," - " or underscore, subsequent characters can include numbers, " - "dashes, and periods") + msg = ("In strict mode, the XForm ID must be a valid slug" + " and contain no spaces. Please ensure that you " + "have set an id_string in the settings sheet or" + " have modified the filename to not contain any spaces.") self.assertRaisesMessage( - PyXFormError, msg, self._publish_xls_file, xls_path) + XLSFormError, msg, self._publish_xls_file, xls_path) self.assertEquals(XForm.objects.count(), count) def test_choice_duplicate_error(self): @@ -111,13 +111,14 @@ def test_choice_duplicate_error(self): xls_path = os.path.join( self.this_directory, 'fixtures', 'cascading_selects', 'duplicate_choice_form.xls') - msg = ("There does not seem to be" - " a `allow_choice_duplicates`" - " column header defined in your settings sheet." - " You must have set `allow_choice_duplicates`" - " setting in your settings sheet" - " to have duplicate choice list names" - " in your choices sheet") + msg = ("The name column for the 'counties' choice list" + " contains these duplicates: 'king'. Duplicate " + "names will be impossible to identify in " + "analysis unless a previous value in a " + "cascading select differentiates them. If this " + "is intentional, you can set the " + "allow_choice_duplicates setting to 'yes'. " + "Read more: https://xlsform.org/#choice-names.") self.assertRaisesMessage( PyXFormError, msg, self._publish_xls_file, xls_path) self.assertEquals(XForm.objects.count(), count) diff --git a/onadata/apps/main/tests/test_past_bugs.py b/onadata/apps/main/tests/test_past_bugs.py index 573bb31b64..c2b6b7053e 100644 --- a/onadata/apps/main/tests/test_past_bugs.py +++ b/onadata/apps/main/tests/test_past_bugs.py @@ -13,13 +13,20 @@ class TestInputs(TestBase): """ def test_uniqueness_of_group_names_enforced(self): + """ + Test an error is raised when a form containing a group + with the name "data" is present within the form. + + This error is raised due to the fact that the root node + is named "data" + """ pre_count = XForm.objects.count() self._create_user_and_login() self.assertRaisesMessage( PyXFormError, - "There are two sections with the name group_names_must_be_unique.", + "There are two sections with the name data.", self._publish_xls_file, - 'fixtures/group_names_must_be_unique.xls') + 'fixtures/group_names_must_be_unique.xlsx') self.assertEqual(XForm.objects.count(), pre_count) def test_mch(self): diff --git a/onadata/apps/main/tests/test_process.py b/onadata/apps/main/tests/test_process.py index 50e7b104e8..e46df8e9bc 100644 --- a/onadata/apps/main/tests/test_process.py +++ b/onadata/apps/main/tests/test_process.py @@ -246,7 +246,7 @@ def _download_xform(self): uuid_nodes = [node for node in model_node.childNodes if node.nodeType == Node.ELEMENT_NODE and node.getAttribute("nodeset") == - "/transportation/formhub/uuid"] + "/data/formhub/uuid"] self.assertEqual(len(uuid_nodes), 1) uuid_node = uuid_nodes[0] uuid_node.setAttribute("calculate", "''") @@ -560,7 +560,7 @@ def test_uuid_injection_in_cascading_select(self): node.nodeType == Node.ELEMENT_NODE and node.tagName == "bind" and node.getAttribute("nodeset") == - "/%s/formhub/uuid" % file_name] + "/data/formhub/uuid"] self.assertEqual(len(calculate_bind_nodes), 1) calculate_bind_node = calculate_bind_nodes[0] self.assertEqual( diff --git a/onadata/apps/viewer/tests/test_exports.py b/onadata/apps/viewer/tests/test_exports.py index 692a1700be..387c30e708 100644 --- a/onadata/apps/viewer/tests/test_exports.py +++ b/onadata/apps/viewer/tests/test_exports.py @@ -824,7 +824,7 @@ def _get_xls_data(self, filepath): storage = get_storage_class()() with storage.open(filepath) as f: workbook = open_workbook(file_contents=f.read()) - transportation_sheet = workbook.sheet_by_name("transportation") + transportation_sheet = workbook.sheet_by_name("data") self.assertTrue(transportation_sheet.nrows > 1) headers = transportation_sheet.row_values(0) column1 = transportation_sheet.row_values(1) diff --git a/onadata/libs/tests/serializers/test_merged_xform_serializer.py b/onadata/libs/tests/serializers/test_merged_xform_serializer.py index c8f4018df1..77ffe00fc7 100644 --- a/onadata/libs/tests/serializers/test_merged_xform_serializer.py +++ b/onadata/libs/tests/serializers/test_merged_xform_serializer.py @@ -226,6 +226,7 @@ def test_get_merged_xform_survey(self): }], u'name': u'gender', u'label': u'Sex', + u'list_name': u'gender', u'type': u'select one' }, { u'control': { @@ -280,6 +281,7 @@ def test_group_merged_xform_survey(self): }], u'name': u'gender', u'label': u'Sex', + u'list_name': u'gender', u'type': u'select one' }], u'name': u'info', @@ -297,6 +299,7 @@ def test_group_merged_xform_survey(self): }], u'name': u'gender', u'label': u'Sex', + u'list_name': u'gender', u'type': u'select one' }], u'name': u'person', @@ -357,6 +360,7 @@ def test_repeat_merged_xform_survey(self): }], u'name': u'gender', u'label': u'Sex', + u'list_name': u'gender', u'type': u'select one' }], u'name': u'info', @@ -374,6 +378,7 @@ def test_repeat_merged_xform_survey(self): }], u'name': u'gender', u'label': u'Sex', + u'list_name': u'gender', u'type': u'select one' }], u'name': u'person', diff --git a/onadata/libs/tests/utils/fixtures/single.xml b/onadata/libs/tests/utils/fixtures/single.xml index 77d818bd30..37a376be32 100644 --- a/onadata/libs/tests/utils/fixtures/single.xml +++ b/onadata/libs/tests/utils/fixtures/single.xml @@ -1 +1 @@ -102014-09-04T15:07:17+03:00 a55d89f9483a45c8a896d45de94499a9maleenketo.org:2gnoXEilHRGn6V5i83.3595 -32.8601 0 1 uuid:fa7f34af-8e28-4d05-9085-b495f0bd9491Name_1no phonenumber property in enketoNAno2014-09-04T15:06:01+03:0083.3595 -32.8601 0 1083.3595-32.8601121.22474 -10.5601 50000 2005000021.22474-10.56012002014-09-04 +102014-09-04T15:07:17+03:00 a55d89f9483a45c8a896d45de94499a9maleenketo.org:2gnoXEilHRGn6V5i83.3595 -32.8601 0 1 uuid:fa7f34af-8e28-4d05-9085-b495f0bd9491Name_1no phonenumber property in enketoNAno2014-09-04T15:06:01+03:0083.3595 -32.8601 0 1083.3595-32.8601121.22474 -10.5601 50000 2005000021.22474-10.56012002014-09-04 diff --git a/onadata/libs/tests/utils/test_export_builder.py b/onadata/libs/tests/utils/test_export_builder.py index 974be49c0d..fea02c79e1 100644 --- a/onadata/libs/tests/utils/test_export_builder.py +++ b/onadata/libs/tests/utils/test_export_builder.py @@ -31,6 +31,8 @@ from onadata.apps.viewer.tests.export_helpers import viewer_fixture_path from onadata.libs.utils.csv_builder import (CSVDataFrameBuilder, get_labels_from_columns) +from onadata.libs.utils.common_tags import (SELECT_BIND_TYPE, + MULTIPLE_SELECT_TYPE) from onadata.libs.utils.export_builder import ( decode_mongo_encoded_section_names, dict_to_joined_export, @@ -238,7 +240,7 @@ class TestExportBuilder(TestBase): def _create_childrens_survey(self, filename="childrens_survey.xls"): survey = create_survey_from_xls(_logger_fixture_path( filename - )) + ), default_name=filename.split('.')[0]) self.dd = DataDictionary() self.dd._survey = survey return survey @@ -438,7 +440,8 @@ def test_zipped_csv_export_works_with_unicode(self): cvs writer doesnt handle unicode we we have to encode to ascii """ survey = create_survey_from_xls(_logger_fixture_path( - 'childrens_survey_unicode.xls')) + 'childrens_survey_unicode.xls'), + default_name='childrens_survey_unicode') export_builder = ExportBuilder() export_builder.set_survey(survey) temp_zip_file = NamedTemporaryFile(suffix='.zip') @@ -933,7 +936,8 @@ def test_zipped_sav_export_with_duplicate_column_name(self): def test_xls_export_works_with_unicode(self): survey = create_survey_from_xls(_logger_fixture_path( - 'childrens_survey_unicode.xls')) + 'childrens_survey_unicode.xls'), + default_name='childrenss_survey_unicode') export_builder = ExportBuilder() export_builder.set_survey(survey) temp_xls_file = NamedTemporaryFile(suffix='.xlsx') @@ -953,7 +957,9 @@ def test_xls_export_with_hxl_adds_extra_row(self): xlsform_path = os.path.join( settings.PROJECT_ROOT, "apps", "main", "tests", "fixtures", "hxl_test", "hxl_example.xlsx") - survey = create_survey_from_xls(xlsform_path) + survey = create_survey_from_xls( + xlsform_path, + default_name=xlsform_path.split('/')[-1].split('.')[0]) export_builder = ExportBuilder() export_builder.INCLUDE_HXL = True export_builder.set_survey(survey) @@ -1483,7 +1489,8 @@ def test_get_valid_sheet_name_catches_long_duplicate_names(self): def test_to_xls_export_generates_valid_sheet_names(self): survey = create_survey_from_xls(_logger_fixture_path( - 'childrens_survey_with_a_very_long_name.xls')) + 'childrens_survey_with_a_very_long_name.xls'), + default_name='childrens_survey_with_a_very_long_name') export_builder = ExportBuilder() export_builder.set_survey(survey) xls_file = NamedTemporaryFile(suffix='.xls') @@ -1502,7 +1509,8 @@ def test_to_xls_export_generates_valid_sheet_names(self): def test_child_record_parent_table_is_updated_when_sheet_is_renamed(self): survey = create_survey_from_xls(_logger_fixture_path( - 'childrens_survey_with_a_very_long_name.xls')) + 'childrens_survey_with_a_very_long_name.xls'), + default_name='childrens_survey_with_a_very_long_name') export_builder = ExportBuilder() export_builder.set_survey(survey) xls_file = NamedTemporaryFile(suffix='.xlsx') @@ -1564,7 +1572,8 @@ def test_type_conversion(self): } survey = create_survey_from_xls(viewer_fixture_path( - 'test_data_types/test_data_types.xls')) + 'test_data_types/test_data_types.xls'), + default_name='test_data_types') export_builder = ExportBuilder() export_builder.set_survey(survey) # format submission 1 for export @@ -1589,7 +1598,8 @@ def test_type_conversion(self): def test_xls_convert_dates_before_1900(self): survey = create_survey_from_xls(viewer_fixture_path( - 'test_data_types/test_data_types.xls')) + 'test_data_types/test_data_types.xls'), + default_name='test_data_types') export_builder = ExportBuilder() export_builder.set_survey(survey) data = [ @@ -1759,7 +1769,8 @@ def test_generate_field_title_truncated_titles_select_multiple(self): def test_xls_export_remove_group_name(self): survey = create_survey_from_xls(_logger_fixture_path( - 'childrens_survey_unicode.xls')) + 'childrens_survey_unicode.xls'), + default_name='childrens_survey_unicode') export_builder = ExportBuilder() export_builder.TRUNCATE_GROUP_TITLE = True export_builder.set_survey(survey) @@ -1780,7 +1791,8 @@ def test_zipped_csv_export_remove_group_name(self): cvs writer doesnt handle unicode we we have to encode to ascii """ survey = create_survey_from_xls(_logger_fixture_path( - 'childrens_survey_unicode.xls')) + 'childrens_survey_unicode.xls'), + default_name='childrens_survey_unicode') export_builder = ExportBuilder() export_builder.TRUNCATE_GROUP_TITLE = True export_builder.set_survey(survey) @@ -1825,7 +1837,8 @@ def test_zipped_csv_export_remove_group_name(self): def test_xls_export_with_labels(self): survey = create_survey_from_xls(_logger_fixture_path( - 'childrens_survey_unicode.xls')) + 'childrens_survey_unicode.xls'), + default_name='childrens_survey_unicode') export_builder = ExportBuilder() export_builder.TRUNCATE_GROUP_TITLE = True export_builder.INCLUDE_LABELS = True @@ -1854,7 +1867,8 @@ def test_xls_export_with_labels(self): def test_xls_export_with_labels_only(self): survey = create_survey_from_xls(_logger_fixture_path( - 'childrens_survey_unicode.xls')) + 'childrens_survey_unicode.xls'), + default_name='childrens_survey_unicode') export_builder = ExportBuilder() export_builder.TRUNCATE_GROUP_TITLE = True export_builder.INCLUDE_LABELS_ONLY = True @@ -1878,7 +1892,8 @@ def test_zipped_csv_export_with_labels(self): cvs writer doesnt handle unicode we we have to encode to ascii """ survey = create_survey_from_xls(_logger_fixture_path( - 'childrens_survey_unicode.xls')) + 'childrens_survey_unicode.xls'), + default_name='childrens_survey_unicode') export_builder = ExportBuilder() export_builder.TRUNCATE_GROUP_TITLE = True export_builder.INCLUDE_LABELS = True @@ -1944,7 +1959,8 @@ def test_zipped_csv_export_with_labels_only(self): cvs writer doesnt handle unicode we we have to encode to ascii """ survey = create_survey_from_xls(_logger_fixture_path( - 'childrens_survey_unicode.xls')) + 'childrens_survey_unicode.xls'), + default_name='childrens_survey_unicode') export_builder = ExportBuilder() export_builder.TRUNCATE_GROUP_TITLE = True export_builder.INCLUDE_LABELS_ONLY = True @@ -2064,7 +2080,8 @@ def _test_sav_file(section): def test_xls_export_with_english_labels(self): survey = create_survey_from_xls(_logger_fixture_path( - 'childrens_survey_en.xls')) + 'childrens_survey_en.xls'), + default_name='childrens_survey_en') # no default_language is not set self.assertEqual( survey.to_json_dict().get('default_language'), 'default' @@ -2092,7 +2109,8 @@ def test_xls_export_with_english_labels(self): def test_xls_export_with_swahili_labels(self): survey = create_survey_from_xls(_logger_fixture_path( - 'childrens_survey_sw.xls')) + 'childrens_survey_sw.xls'), + default_name='childrens_survey_sw') # default_language is set to swahili self.assertEqual( survey.to_json_dict().get('default_language'), 'swahili' @@ -2120,7 +2138,8 @@ def test_xls_export_with_swahili_labels(self): def test_csv_export_with_swahili_labels(self): survey = create_survey_from_xls(_logger_fixture_path( - 'childrens_survey_sw.xls')) + 'childrens_survey_sw.xls'), + default_name='childrens_survey_sw') # default_language is set to swahili self.assertEqual( survey.to_json_dict().get('default_language'), 'swahili' @@ -2137,7 +2156,8 @@ def test_csv_export_with_swahili_labels(self): def test_select_multiples_choices(self): survey = create_survey_from_xls(_logger_fixture_path( - 'childrens_survey_sw.xls')) + 'childrens_survey_sw.xls'), + default_name='childrens_survey_sw') dd = DataDictionary() dd._survey = survey export_builder = ExportBuilder() @@ -2145,7 +2165,8 @@ def test_select_multiples_choices(self): export_builder.INCLUDE_LABELS = True export_builder.set_survey(survey) child = [e for e in dd.get_survey_elements_with_choices() - if e.bind.get('type') == 'select'][0] + if e.bind.get('type') == SELECT_BIND_TYPE + and e.type == MULTIPLE_SELECT_TYPE][0] self.assertNotEqual(child.children, []) choices = export_builder._get_select_mulitples_choices( child, dd, ExportBuilder.GROUP_DELIMITER, @@ -2191,7 +2212,7 @@ def test_select_multiples_choices(self): def test_select_multiples_choices_with_choice_filter(self): survey = create_survey_from_xls(_logger_fixture_path( 'choice_filter.xlsx' - )) + ), default_name='choice_filter') dd = DataDictionary() dd._survey = survey export_builder = ExportBuilder() @@ -2199,7 +2220,8 @@ def test_select_multiples_choices_with_choice_filter(self): export_builder.INCLUDE_LABELS = True export_builder.set_survey(survey) child = [e for e in dd.get_survey_elements_with_choices() - if e.bind.get('type') == 'select'][0] + if e.bind.get('type') == SELECT_BIND_TYPE + and e.type == MULTIPLE_SELECT_TYPE][0] choices = export_builder._get_select_mulitples_choices( child, dd, ExportBuilder.GROUP_DELIMITER, ExportBuilder.TRUNCATE_GROUP_TITLE @@ -2283,7 +2305,9 @@ def _create_osm_survey(self): for filename in filenames] submission_path = os.path.join(osm_fixtures_dir, 'instance_a.xml') self._make_submission_w_attachment(submission_path, paths) - survey = create_survey_from_xls(xlsform_path) + survey = create_survey_from_xls( + xlsform_path, + default_name=xlsform_path.split('/')[-1].split('.')[0]) return survey def test_zip_csv_export_has_comment_and_status_field(self): diff --git a/onadata/libs/tests/utils/test_viewer_tools.py b/onadata/libs/tests/utils/test_viewer_tools.py index 5f5c7c10e1..28fa00591d 100644 --- a/onadata/libs/tests/utils/test_viewer_tools.py +++ b/onadata/libs/tests/utils/test_viewer_tools.py @@ -63,7 +63,7 @@ def test_get_enketo_defaults_with_right_xform(self): kwargs = {xform_variable_name: xform_variable_value} defaults = generate_enketo_form_defaults(self.xform, **kwargs) - key = "defaults[/transportation/transport/{}]".format( + key = "defaults[/data/transport/{}]".format( xform_variable_name) self.assertEqual(defaults, {key: xform_variable_value}) @@ -87,9 +87,9 @@ def test_get_enketo_defaults_with_multiple_params(self): defaults = generate_enketo_form_defaults(self.xform, **kwargs) transportation_types_key = \ - "defaults[/transportation/transport/{}]".format( + "defaults[/data/transport/{}]".format( transportation_types) - frequency_key = "defaults[/transportation/transport/"\ + frequency_key = "defaults[/data/transport/"\ "loop_over_transport_types_frequency/"\ "{}/{}]".format(transportation_types_value, frequency) self.assertIn(transportation_types_key, defaults) diff --git a/onadata/libs/utils/common_tags.py b/onadata/libs/utils/common_tags.py index b9928b4875..de7bbfa669 100644 --- a/onadata/libs/utils/common_tags.py +++ b/onadata/libs/utils/common_tags.py @@ -83,6 +83,7 @@ TEXTIT = 'textit' OSM = 'osm' +SELECT_BIND_TYPE = 'string' MULTIPLE_SELECT_TYPE = 'select all that apply' GROUPNAME_REMOVED_FLAG = 'group-name-removed' DATAVIEW_EXPORT = U'dataview' diff --git a/onadata/libs/utils/csv_builder.py b/onadata/libs/utils/csv_builder.py index b687fa40b5..0b5d6e7bed 100644 --- a/onadata/libs/utils/csv_builder.py +++ b/onadata/libs/utils/csv_builder.py @@ -24,7 +24,9 @@ SUBMISSION_TIME, SUBMITTED_BY, TAGS, TOTAL_MEDIA, UUID, VERSION, XFORM_ID_STRING, REVIEW_STATUS, - REVIEW_COMMENT) + REVIEW_COMMENT, + MULTIPLE_SELECT_TYPE, + SELECT_BIND_TYPE) from onadata.libs.utils.export_builder import (get_choice_label, get_value_or_attachment_uri, track_task_progress) @@ -222,7 +224,8 @@ def _collect_select_multiples(cls, dd, language=None): select_multiples = [] select_multiple_elements = [ e for e in dd.get_survey_elements_with_choices() - if e.bind.get('type') == 'select' + if e.bind.get('type') == SELECT_BIND_TYPE + and e.type == MULTIPLE_SELECT_TYPE ] for e in select_multiple_elements: xpath = e.get_abbreviated_xpath() diff --git a/onadata/libs/utils/export_builder.py b/onadata/libs/utils/export_builder.py index 360749ce92..665c254860 100644 --- a/onadata/libs/utils/export_builder.py +++ b/onadata/libs/utils/export_builder.py @@ -29,15 +29,12 @@ from onadata.apps.viewer.models.data_dictionary import DataDictionary from onadata.libs.utils.common_tags import ( ATTACHMENTS, BAMBOO_DATASET_ID, DELETEDAT, DURATION, GEOLOCATION, - ID, INDEX, MULTIPLE_SELECT_TYPE, NOTES, PARENT_INDEX, + ID, INDEX, MULTIPLE_SELECT_TYPE, SELECT_ONE, NOTES, PARENT_INDEX, PARENT_TABLE_NAME, REPEAT_INDEX_TAGS, SAV_255_BYTES_TYPE, SAV_NUMERIC_TYPE, STATUS, SUBMISSION_TIME, SUBMITTED_BY, TAGS, UUID, - VERSION, XFORM_ID_STRING, REVIEW_STATUS, REVIEW_COMMENT) + VERSION, XFORM_ID_STRING, REVIEW_STATUS, REVIEW_COMMENT, SELECT_BIND_TYPE) from onadata.libs.utils.mongo import _decode_from_mongo, _is_invalid_for_mongo - # the bind type of select multiples that we use to compare -MULTIPLE_SELECT_BIND_TYPE = 'select' -SELECT_ONE_BIND_TYPE = 'select1' GEOPOINT_BIND_TYPE = 'geopoint' OSM_BIND_TYPE = 'osm' DEFAULT_UPDATE_BATCH = 100 @@ -475,7 +472,8 @@ def build_sections( {child_xpath: _encode_for_mongo(child_xpath)}) # if its a select multiple, make columns out of its choices - if child.bind.get('type') == MULTIPLE_SELECT_BIND_TYPE: + if child.bind.get('type') == SELECT_BIND_TYPE \ + and child.type == MULTIPLE_SELECT_TYPE: choices = [] if self.SPLIT_SELECT_MULTIPLES: choices = self._get_select_mulitples_choices( @@ -527,7 +525,8 @@ def build_sections( _append_xpaths_to_section( current_section_name, osm_fields, child.get_abbreviated_xpath(), xpaths) - if child.bind.get(u"type") == SELECT_ONE_BIND_TYPE: + if child.bind.get(u"type") == SELECT_BIND_TYPE \ + and child.type == SELECT_ONE: _append_xpaths_to_section( current_section_name, select_ones, child.get_abbreviated_xpath(), []) @@ -1057,25 +1056,22 @@ def _is_numeric(xpath, element_type, data_dictionary): # check if it is a choice part of multiple choice # type is likely empty string, split multi select is binary element = data_dictionary.get_element(xpath) + if element.type == SELECT_ONE: + # Determine if all select1 choices are numeric in nature. + # If the choices are numeric in nature have the field type + # in spss be numeric + choices = list(all_value_labels[var_name]) + if len(choices) == 0: + return False + return is_all_numeric(choices) if element and element.type == '' and value_select_multiples: return is_all_numeric([element.name]) parent_xpath = '/'.join(xpath.split('/')[:-1]) parent = data_dictionary.get_element(parent_xpath) return (parent and parent.type == MULTIPLE_SELECT_TYPE) - elif element_type != SELECT_ONE_BIND_TYPE: - return False - - if var_name not in all_value_labels: - return False - - # Determine if all select1 choices are numeric in nature - # and as such have the field type in spss be numeric - choices = list(all_value_labels[var_name]) - if len(choices) == 0: + else: return False - return is_all_numeric(choices) - value_select_multiples = self.VALUE_SELECT_MULTIPLES _var_types = {} value_labels = {} diff --git a/requirements/base.pip b/requirements/base.pip index ce635b375f..c2869de5cb 100644 --- a/requirements/base.pip +++ b/requirements/base.pip @@ -4,12 +4,12 @@ # # pip-compile --output-file=requirements/base.pip requirements/base.in # --e git+https://github.com/onaio/django-digest.git@eb85c7ae19d70d4690eeb20983e94b9fde8ab8c2#egg=django-digest --e git+https://github.com/onaio/django-multidb-router.git@f711368180d58eef87eda54fadfd5f8355623d52#egg=django-multidb-router --e git+https://github.com/onaio/oauth2client.git@75dfdee77fb640ae30469145c66440571dfeae5c#egg=oauth2client --e git+https://github.com/onaio/floip-py.git@3bbf5c76b34ec49c438a3099ab848870514d1e50#egg=pyfloip --e git+https://github.com/onaio/python-digest.git@3af1bd0ef6114e24bf23d0e8fd9d7ebf389845d1#egg=python-digest --e git+https://github.com/onaio/python-json2xlsclient.git@62b4645f7b4f2684421a13ce98da0331a9dd66a0#egg=python-json2xlsclient +-e git+https://github.com/onaio/django-digest.git@eb85c7ae19d70d4690eeb20983e94b9fde8ab8c2#egg=django-digest # via -r requirements/base.in +-e git+https://github.com/onaio/django-multidb-router.git@f711368180d58eef87eda54fadfd5f8355623d52#egg=django-multidb-router # via -r requirements/base.in +-e git+https://github.com/onaio/oauth2client.git@75dfdee77fb640ae30469145c66440571dfeae5c#egg=oauth2client # via -r requirements/base.in +-e git+https://github.com/onaio/floip-py.git@3bbf5c76b34ec49c438a3099ab848870514d1e50#egg=pyfloip # via -r requirements/base.in +-e git+https://github.com/onaio/python-digest.git@3af1bd0ef6114e24bf23d0e8fd9d7ebf389845d1#egg=python-digest # via -r requirements/base.in +-e git+https://github.com/onaio/python-json2xlsclient.git@62b4645f7b4f2684421a13ce98da0331a9dd66a0#egg=python-json2xlsclient # via -r requirements/base.in alabaster==0.7.12 # via sphinx amqp==2.5.2 # via kombu argparse==1.4.0 # via unittest2 @@ -19,50 +19,50 @@ billiard==3.6.2.0 # via celery boto3==1.12.4 # via tabulator botocore==1.15.4 # via boto3, s3transfer cchardet==2.1.5 # via datapackage, tabulator -celery==4.4.0 # via django-celery-results +celery==4.4.0 # via django-celery-results, onadata certifi==2019.11.28 # via requests cffi==1.14.0 # via cryptography chardet==3.0.4 # via requests click==7.0 # via datapackage, tableschema, tabulator -cryptography==2.8 -datapackage==1.11.1 +cryptography==2.8 # via onadata +datapackage==1.11.1 # via pyfloip defusedxml==0.6.0 # via djangorestframework-xml -dict2xml==1.6.1 -django-activity-stream==0.8.0 -django-celery-results==1.2.0 -django-cors-headers==3.2.1 -django-debug-toolbar==2.2 -django-filter==2.2.0 -django-guardian==2.1.0 # via djangorestframework-guardian -django-nose==1.4.6 -django-oauth-toolkit==1.2.0 -django-ordered-model==3.3.0 -django-query-builder==1.2.0 -django-registration-redux==2.7 +dict2xml==1.6.1 # via onadata +django-activity-stream==0.8.0 # via onadata +django-celery-results==1.2.0 # via onadata +django-cors-headers==3.2.1 # via onadata +django-debug-toolbar==2.2 # via onadata +django-filter==2.2.0 # via onadata +django-guardian==2.1.0 # via djangorestframework-guardian, onadata +django-nose==1.4.6 # via onadata +django-oauth-toolkit==1.2.0 # via onadata +django-ordered-model==3.3.0 # via onadata +django-query-builder==1.2.0 # via onadata +django-registration-redux==2.7 # via onadata django-render-block==0.6 # via django-templated-email -django-reversion==3.0.7 -django-taggit==1.2.0 -django-templated-email==2.3.0 -django==2.2.10 # via django-cors-headers, django-debug-toolbar, django-filter, django-guardian, django-oauth-toolkit, django-query-builder, django-render-block, django-reversion, django-taggit, djangorestframework, djangorestframework-guardian, djangorestframework-jsonapi, jsonfield -djangorestframework-csv==2.1.0 -djangorestframework-gis==0.15 -djangorestframework-guardian==0.3.0 -djangorestframework-jsonapi==3.1.0 -djangorestframework-jsonp==1.0.2 -djangorestframework-xml==1.4.0 -djangorestframework==3.11.0 # via djangorestframework-csv, djangorestframework-gis, djangorestframework-guardian, djangorestframework-jsonapi +django-reversion==3.0.7 # via onadata +django-taggit==1.2.0 # via onadata +django-templated-email==2.3.0 # via onadata +django==2.2.10 # via django-cors-headers, django-debug-toolbar, django-filter, django-oauth-toolkit, django-query-builder, django-render-block, django-reversion, django-taggit, djangorestframework, djangorestframework-guardian, djangorestframework-jsonapi, jsonfield, onadata +djangorestframework-csv==2.1.0 # via onadata +djangorestframework-gis==0.15 # via onadata +djangorestframework-guardian==0.3.0 # via onadata +djangorestframework-jsonapi==3.1.0 # via onadata +djangorestframework-jsonp==1.0.2 # via onadata +djangorestframework-xml==1.4.0 # via onadata +djangorestframework==3.11.0 # via djangorestframework-csv, djangorestframework-gis, djangorestframework-guardian, djangorestframework-jsonapi, onadata docutils==0.15.2 # via botocore, sphinx -dpath==2.0.1 -elaphe3==0.2.0 +dpath==2.0.1 # via onadata +elaphe3==0.2.0 # via onadata entrypoints==0.3 # via flake8 et-xmlfile==1.0.1 # via openpyxl -flake8==3.7.9 +flake8==3.7.9 # via onadata fleming==0.5.0 # via django-query-builder formencode==1.3.1 # via pyxform -future==0.18.2 -geojson==2.5.0 -httmock==1.3.0 -httplib2==0.17.0 +future==0.18.2 # via python-json2xlsclient +geojson==2.5.0 # via onadata +httmock==1.3.0 # via onadata +httplib2==0.17.0 # via oauth2client, onadata idna==2.9 # via requests ijson==2.6.1 # via tabulator imagesize==1.2.0 # via sphinx @@ -72,55 +72,55 @@ isodate==0.6.0 # via tableschema jdcal==1.4.1 # via openpyxl jinja2==2.11.1 # via sphinx jmespath==0.9.4 # via boto3, botocore -jsonfield==0.9.23 +jsonfield==0.9.23 # via onadata jsonlines==1.2.0 # via tabulator -jsonpickle==1.3 +jsonpickle==1.3 # via onadata jsonpointer==2.0 # via datapackage jsonschema==3.2.0 # via datapackage, tableschema kombu==4.6.7 # via celery linear-tsv==1.1.0 # via tabulator linecache2==1.0.0 # via traceback2 -lxml==4.5.0 -markdown==3.2.1 +lxml==4.5.0 # via onadata +markdown==3.2.1 # via onadata markupsafe==1.1.1 # via jinja2 mccabe==0.6.1 # via flake8 -mock==4.0.1 -modilabs-python-utils==0.1.5 +mock==4.0.1 # via onadata +modilabs-python-utils==0.1.5 # via onadata nose==1.3.7 # via django-nose -numpy==1.18.1 +numpy==1.18.1 # via onadata oauthlib==3.1.0 # via django-oauth-toolkit -openpyxl==3.0.3 # via tabulator +openpyxl==3.0.3 # via onadata, tabulator packaging==20.1 # via sphinx -paho-mqtt==1.5.0 -pillow==7.0.0 # via elaphe3 -psycopg2==2.8.4 -pyasn1-modules==0.2.8 -pyasn1==0.4.8 # via pyasn1-modules, rsa +paho-mqtt==1.5.0 # via onadata +pillow==7.0.0 # via elaphe3, onadata +psycopg2==2.8.4 # via onadata +pyasn1-modules==0.2.8 # via oauth2client +pyasn1==0.4.8 # via oauth2client, pyasn1-modules, rsa pycodestyle==2.5.0 # via flake8 pycparser==2.19 # via cffi pyflakes==2.1.1 # via flake8 pygments==2.5.2 # via sphinx -pyjwt==1.7.1 -pylibmc==1.6.1 -pymongo==3.10.1 +pyjwt==1.7.1 # via onadata +pylibmc==1.6.1 # via onadata +pymongo==3.10.1 # via onadata pyparsing==2.4.6 # via packaging pyrsistent==0.15.7 # via jsonschema -python-dateutil==2.8.1 # via botocore, fleming, tableschema -python-memcached==1.59 -pytz==2019.3 # via babel, celery, django, django-query-builder, fleming -pyxform==0.15.1 -raven==6.10.0 -recaptcha-client==1.0.6 -requests-mock==1.7.0 -requests==2.23.0 # via datapackage, django-oauth-toolkit, httmock, requests-mock, sphinx, tableschema, tabulator +python-dateutil==2.8.1 # via botocore, fleming, onadata, tableschema +python-memcached==1.59 # via onadata +pytz==2019.3 # via babel, celery, django, django-query-builder, fleming, onadata +pyxform==1.1.0 # via onadata, pyfloip +raven==6.10.0 # via onadata +recaptcha-client==1.0.6 # via onadata +requests-mock==1.7.0 # via onadata +requests==2.23.0 # via datapackage, django-oauth-toolkit, httmock, onadata, python-json2xlsclient, requests-mock, sphinx, tableschema, tabulator rfc3986==1.3.2 # via tableschema -rsa==4.0 +rsa==4.0 # via oauth2client s3transfer==0.3.3 # via boto3 -savreaderwriter==3.4.2 -simplejson==3.17.0 -six==1.14.0 # via cryptography, datapackage, dict2xml, django-query-builder, django-templated-email, djangorestframework-csv, isodate, jsonlines, jsonschema, linear-tsv, packaging, pyrsistent, python-dateutil, python-memcached, requests-mock, tableschema, tabulator, unittest2 +savreaderwriter==3.4.2 # via onadata +simplejson==3.17.0 # via onadata +six==1.14.0 # via cryptography, datapackage, dict2xml, django-query-builder, django-templated-email, djangorestframework-csv, isodate, jsonlines, jsonschema, linear-tsv, oauth2client, packaging, pyrsistent, python-dateutil, python-memcached, requests-mock, tableschema, tabulator, unittest2 snowballstemmer==2.0.0 # via sphinx -sphinx==2.4.2 +sphinx==2.4.2 # via onadata sphinxcontrib-applehelp==1.0.1 # via sphinx sphinxcontrib-devhelp==1.0.1 # via sphinx sphinxcontrib-htmlhelp==1.0.2 # via sphinx @@ -132,11 +132,11 @@ sqlparse==0.3.0 # via django, django-debug-toolbar tableschema==1.13.1 # via datapackage tabulator==1.35.0 # via datapackage, tableschema traceback2==1.4.0 # via unittest2 -unicodecsv==0.14.1 # via datapackage, djangorestframework-csv, pyxform, tableschema, tabulator +unicodecsv==0.14.1 # via datapackage, djangorestframework-csv, onadata, pyxform, tableschema, tabulator unittest2==1.1.0 # via pyxform urllib3==1.25.8 # via botocore, requests -uwsgi==2.0.18 +uwsgi==2.0.18 # via onadata vine==1.3.0 # via amqp, celery -xlrd==1.2.0 # via pyxform, tabulator -xlwt==1.3.0 +xlrd==1.2.0 # via onadata, pyxform, tabulator +xlwt==1.3.0 # via onadata zipp==3.0.0 # via importlib-metadata diff --git a/requirements/dev.pip b/requirements/dev.pip index c4a1b3e733..6a47ff83b1 100644 --- a/requirements/dev.pip +++ b/requirements/dev.pip @@ -4,12 +4,12 @@ # # pip-compile --output-file=requirements/dev.pip requirements/dev.in # --e git+https://github.com/onaio/django-digest.git@eb85c7ae19d70d4690eeb20983e94b9fde8ab8c2#egg=django-digest --e git+https://github.com/onaio/django-multidb-router.git@f711368180d58eef87eda54fadfd5f8355623d52#egg=django-multidb-router --e git+https://github.com/onaio/oauth2client.git@75dfdee77fb640ae30469145c66440571dfeae5c#egg=oauth2client --e git+https://github.com/onaio/floip-py.git@3bbf5c76b34ec49c438a3099ab848870514d1e50#egg=pyfloip --e git+https://github.com/onaio/python-digest.git@3af1bd0ef6114e24bf23d0e8fd9d7ebf389845d1#egg=python-digest --e git+https://github.com/onaio/python-json2xlsclient.git@62b4645f7b4f2684421a13ce98da0331a9dd66a0#egg=python-json2xlsclient +-e git+https://github.com/onaio/django-digest.git@eb85c7ae19d70d4690eeb20983e94b9fde8ab8c2#egg=django-digest # via -r requirements/base.in +-e git+https://github.com/onaio/django-multidb-router.git@f711368180d58eef87eda54fadfd5f8355623d52#egg=django-multidb-router # via -r requirements/base.in +-e git+https://github.com/onaio/oauth2client.git@75dfdee77fb640ae30469145c66440571dfeae5c#egg=oauth2client # via -r requirements/base.in +-e git+https://github.com/onaio/floip-py.git@3bbf5c76b34ec49c438a3099ab848870514d1e50#egg=pyfloip # via -r requirements/base.in +-e git+https://github.com/onaio/python-digest.git@3af1bd0ef6114e24bf23d0e8fd9d7ebf389845d1#egg=python-digest # via -r requirements/base.in +-e git+https://github.com/onaio/python-json2xlsclient.git@62b4645f7b4f2684421a13ce98da0331a9dd66a0#egg=python-json2xlsclient # via -r requirements/base.in alabaster==0.7.12 # via sphinx amqp==2.5.2 # via kombu appnope==0.1.0 # via ipython @@ -22,123 +22,124 @@ billiard==3.6.2.0 # via celery boto3==1.12.4 # via tabulator botocore==1.15.4 # via boto3, s3transfer cchardet==2.1.5 # via datapackage, tabulator -celery==4.4.0 # via django-celery-results +celery==4.4.0 # via django-celery-results, onadata certifi==2019.11.28 # via requests cffi==1.14.0 # via cryptography chardet==3.0.4 # via requests click==7.0 # via datapackage, tableschema, tabulator -cryptography==2.8 -datapackage==1.11.1 +cryptography==2.8 # via onadata +datapackage==1.11.1 # via pyfloip decorator==4.4.1 # via ipython, traitlets defusedxml==0.6.0 # via djangorestframework-xml -dict2xml==1.6.1 -django-activity-stream==0.8.0 -django-celery-results==1.2.0 -django-cors-headers==3.2.1 -django-debug-toolbar==2.2 -django-extensions==2.2.8 -django-filter==2.2.0 -django-guardian==2.2.0 -django-nose==1.4.6 -django-oauth-toolkit==1.2.0 -django-ordered-model==3.3.0 -django-query-builder==1.2.0 -django-registration-redux==2.7 +dict2xml==1.6.1 # via onadata +django-activity-stream==0.8.0 # via onadata +django-celery-results==1.2.0 # via onadata +django-cors-headers==3.2.1 # via onadata +django-debug-toolbar==2.2 # via onadata +django-extensions==2.2.8 # via -r requirements/dev.in +django-filter==2.2.0 # via onadata +django-guardian==2.2.0 # via djangorestframework-guardian, onadata +django-nose==1.4.6 # via onadata +django-oauth-toolkit==1.2.0 # via onadata +django-ordered-model==3.3.0 # via onadata +django-query-builder==1.2.0 # via onadata +django-registration-redux==2.7 # via onadata django-render-block==0.6 # via django-templated-email -django-reversion==3.0.7 -django-taggit==1.2.0 -django-templated-email==2.3.0 -django==2.2.10 # via django-cors-headers, django-debug-toolbar, django-filter, django-guardian, django-oauth-toolkit, django-query-builder, django-render-block, django-reversion, django-taggit, djangorestframework, djangorestframework-jsonapi, jsonfield -djangorestframework-csv==2.1.0 -djangorestframework-gis==0.15 -djangorestframework-jsonapi==3.1.0 -djangorestframework-jsonp==1.0.2 -djangorestframework-xml==1.4.0 -djangorestframework==3.11.0 # via djangorestframework-csv, djangorestframework-gis, djangorestframework-jsonapi +django-reversion==3.0.7 # via onadata +django-taggit==1.2.0 # via onadata +django-templated-email==2.3.0 # via onadata +django==2.2.10 # via django-cors-headers, django-debug-toolbar, django-filter, django-guardian, django-oauth-toolkit, django-query-builder, django-render-block, django-reversion, django-taggit, djangorestframework, djangorestframework-guardian, djangorestframework-jsonapi, jsonfield, onadata +djangorestframework-csv==2.1.0 # via onadata +djangorestframework-gis==0.15 # via onadata +djangorestframework-guardian==0.3.0 # via onadata +djangorestframework-jsonapi==3.1.0 # via onadata +djangorestframework-jsonp==1.0.2 # via onadata +djangorestframework-xml==1.4.0 # via onadata +djangorestframework==3.11.0 # via djangorestframework-csv, djangorestframework-gis, djangorestframework-guardian, djangorestframework-jsonapi, onadata docutils==0.15.2 # via botocore, sphinx -dpath==2.0.1 -elaphe3==0.2.0 +dpath==2.0.1 # via onadata +elaphe3==0.2.0 # via onadata entrypoints==0.3 # via flake8 et-xmlfile==1.0.1 # via openpyxl -flake8==3.7.9 +flake8==3.7.9 # via onadata fleming==0.5.0 # via django-query-builder formencode==1.3.1 # via pyxform -future==0.18.2 -geojson==2.5.0 -httmock==1.3.0 -httplib2==0.17.0 +future==0.18.2 # via python-json2xlsclient +geojson==2.5.0 # via onadata +httmock==1.3.0 # via onadata +httplib2==0.17.0 # via oauth2client, onadata idna==2.9 # via requests ijson==2.6.1 # via tabulator imagesize==1.2.0 # via sphinx importlib-metadata==1.5.0 # via jsonschema, kombu inflection==0.3.1 # via djangorestframework-jsonapi -ipdb==0.12.3 +ipdb==0.12.3 # via -r requirements/dev.in ipython-genutils==0.2.0 # via traitlets ipython==7.12.0 # via ipdb isodate==0.6.0 # via tableschema -isort==4.3.21 +isort==4.3.21 # via -r requirements/dev.in, pylint jdcal==1.4.1 # via openpyxl jedi==0.16.0 # via ipython jinja2==2.11.1 # via sphinx jmespath==0.9.4 # via boto3, botocore -jsonfield==0.9.23 +jsonfield==0.9.23 # via onadata jsonlines==1.2.0 # via tabulator -jsonpickle==1.3 +jsonpickle==1.3 # via onadata jsonpointer==2.0 # via datapackage jsonschema==3.2.0 # via datapackage, tableschema kombu==4.6.7 # via celery lazy-object-proxy==1.4.3 # via astroid linear-tsv==1.1.0 # via tabulator linecache2==1.0.0 # via traceback2 -lxml==4.5.0 -markdown==3.2.1 +lxml==4.5.0 # via onadata +markdown==3.2.1 # via onadata markupsafe==1.1.1 # via jinja2 mccabe==0.6.1 # via flake8, pylint -mock==4.0.1 -modilabs-python-utils==0.1.5 +mock==4.0.1 # via onadata +modilabs-python-utils==0.1.5 # via onadata nose==1.3.7 # via django-nose -numpy==1.18.1 +numpy==1.18.1 # via onadata oauthlib==3.1.0 # via django-oauth-toolkit -openpyxl==3.0.3 # via tabulator +openpyxl==3.0.3 # via onadata, tabulator packaging==20.1 # via sphinx -paho-mqtt==1.5.0 +paho-mqtt==1.5.0 # via onadata parso==0.6.1 # via jedi pexpect==4.8.0 # via ipython pickleshare==0.7.5 # via ipython -pillow==7.0.0 # via elaphe3 +pillow==7.0.0 # via elaphe3, onadata prompt-toolkit==3.0.3 # via ipython -psycopg2==2.8.4 +psycopg2==2.8.4 # via onadata ptyprocess==0.6.0 # via pexpect -pyasn1-modules==0.2.8 -pyasn1==0.4.8 # via pyasn1-modules, rsa +pyasn1-modules==0.2.8 # via oauth2client +pyasn1==0.4.8 # via oauth2client, pyasn1-modules, rsa pycodestyle==2.5.0 # via flake8 pycparser==2.19 # via cffi pyflakes==2.1.1 # via flake8 pygments==2.5.2 # via ipython, sphinx -pyjwt==1.7.1 -pylibmc==1.6.1 -pylint-django==0.11.1 +pyjwt==1.7.1 # via onadata +pylibmc==1.6.1 # via onadata +pylint-django==0.11.1 # via -r requirements/dev.in pylint-plugin-utils==0.6 # via pylint-django -pylint==1.9.4 -pymongo==3.10.1 +pylint==1.9.4 # via -r requirements/dev.in, pylint-django, pylint-plugin-utils +pymongo==3.10.1 # via onadata pyparsing==2.4.6 # via packaging pyrsistent==0.15.7 # via jsonschema -python-dateutil==2.8.1 # via botocore, fleming, tableschema -python-memcached==1.59 -pytz==2019.3 # via babel, celery, django, django-query-builder, fleming -pyxform==0.15.1 -raven==6.10.0 -recaptcha-client==1.0.6 -requests-mock==1.7.0 -requests==2.23.0 # via datapackage, django-oauth-toolkit, httmock, requests-mock, sphinx, tableschema, tabulator +python-dateutil==2.8.1 # via botocore, fleming, onadata, tableschema +python-memcached==1.59 # via onadata +pytz==2019.3 # via babel, celery, django, django-query-builder, fleming, onadata +pyxform==1.1.0 # via onadata, pyfloip +raven==6.10.0 # via onadata +recaptcha-client==1.0.6 # via onadata +requests-mock==1.7.0 # via onadata +requests==2.23.0 # via datapackage, django-oauth-toolkit, httmock, onadata, python-json2xlsclient, requests-mock, sphinx, tableschema, tabulator rfc3986==1.3.2 # via tableschema -rsa==4.0 +rsa==4.0 # via oauth2client s3transfer==0.3.3 # via boto3 -savreaderwriter==3.4.2 -simplejson==3.17.0 -six==1.14.0 # via astroid, cryptography, datapackage, dict2xml, django-extensions, django-query-builder, django-templated-email, djangorestframework-csv, isodate, jsonlines, jsonschema, linear-tsv, packaging, pylint, pyrsistent, python-dateutil, python-memcached, requests-mock, tableschema, tabulator, traitlets, unittest2 +savreaderwriter==3.4.2 # via onadata +simplejson==3.17.0 # via onadata +six==1.14.0 # via astroid, cryptography, datapackage, dict2xml, django-extensions, django-query-builder, django-templated-email, djangorestframework-csv, isodate, jsonlines, jsonschema, linear-tsv, oauth2client, packaging, pylint, pyrsistent, python-dateutil, python-memcached, requests-mock, tableschema, tabulator, traitlets, unittest2 snowballstemmer==2.0.0 # via sphinx -sphinx==2.4.2 +sphinx==2.4.2 # via onadata sphinxcontrib-applehelp==1.0.1 # via sphinx sphinxcontrib-devhelp==1.0.1 # via sphinx sphinxcontrib-htmlhelp==1.0.2 # via sphinx @@ -151,14 +152,14 @@ tableschema==1.13.1 # via datapackage tabulator==1.35.0 # via datapackage, tableschema traceback2==1.4.0 # via unittest2 traitlets==4.3.3 # via ipython -unicodecsv==0.14.1 # via datapackage, djangorestframework-csv, pyxform, tableschema, tabulator +unicodecsv==0.14.1 # via datapackage, djangorestframework-csv, onadata, pyxform, tableschema, tabulator unittest2==1.1.0 # via pyxform urllib3==1.25.8 # via botocore, requests -uwsgi==2.0.18 +uwsgi==2.0.18 # via onadata vine==1.3.0 # via amqp, celery wcwidth==0.1.8 # via prompt-toolkit wrapt==1.12.0 # via astroid -xlrd==1.2.0 # via pyxform, tabulator -xlwt==1.3.0 -yapf==0.29.0 +xlrd==1.2.0 # via onadata, pyxform, tabulator +xlwt==1.3.0 # via onadata +yapf==0.29.0 # via -r requirements/dev.in zipp==3.0.0 # via importlib-metadata