def test_should_convert_multi_select_question(self): xls_parser_response = XlsFormParser(self.MULTI_SELECT, u"My questionnairé").parse() mangroveService = MangroveService(self.mock_request, xls_parser_response=xls_parser_response) questionnaire_id = mangroveService.create_project() self.assertIsNotNone(questionnaire_id)
def test_should_create_project_using_xlsform_file(self): xls_parser_response = XlsFormParser(self.ALL_FIELDS, u"My questionnairé").parse() mangroveService = MangroveService(self.mock_request, xls_parser_response=xls_parser_response) quesionnaire_id = mangroveService.create_project() self.assertIsNotNone(quesionnaire_id)
def test_should_convert_skip_logic_question(self): xls_parser_response = XlsFormParser(self.SKIP, u"My questionnairé").parse() mangroveService = MangroveService(self.mock_request, xls_parser_response=xls_parser_response) questionnaire_id = mangroveService.create_project() self.assertIsNotNone(questionnaire_id)
def post(self, request): project_name = request.GET['pname'].strip() manager = get_database_manager(request.user) try: xls_parser_response = _try_parse_xls(manager, request, project_name) if isinstance(xls_parser_response, HttpResponse): return xls_parser_response send_email_if_unique_id_type_question_has_no_registered_unique_ids( xls_parser_response, request, project_name) questionnaire_code = generate_questionnaire_code(manager) excel_file = _temp_file(request) mangrove_service = MangroveService( request, questionnaire_code=questionnaire_code, project_name=project_name, xls_form=excel_file, xls_parser_response=xls_parser_response) questionnaire_id, form_code = mangrove_service.create_project() if not questionnaire_id: logger.info("User: %s. Upload Error: %s", request.user.username, "Questionnaire must be unique") return HttpResponse( content_type='application/json', content=json.dumps({ 'success': False, 'error_msg': [ _("Duplicate labels. All questions (labels) must be unique." ) ], 'message_prefix': _("Sorry! Current version of DataWinners does not support" ), 'message_suffix': _("Update your XLSForm and upload again.") })) questionnaire = Project.get(manager, questionnaire_id) _save_questionnaire_as_dict_for_builder(questionnaire, excel_file=excel_file) except QuestionAlreadyExistsException as e: return HttpResponse(content_type='application/json', content=json.dumps({ 'success': False, 'error_msg': [_(e.message)] })) return HttpResponse(json.dumps({ "success": True, "project_name": project_name, "project_id": questionnaire_id, "form_code": form_code }), content_type='application/json')
def test_should_verify_repeat_field_added_to_questionnaire(self): xls_parser_response = XlsFormParser(self.REPEAT, u"My questionnairé").parse() mangroveService = MangroveService(self.mock_request, xls_parser_response=xls_parser_response) mangroveService.create_project() questionnaire_code = mangroveService.questionnaire_code mgr = mangroveService.manager from_model = get_form_model_by_code(mgr, questionnaire_code) self.assertNotEqual([], [f for f in from_model.fields if type(f) is FieldSet and f.fields])
def test_xform_is_the_default_namespace(self): # while parsing submission we assume that xform element without namespace since being default. xform_as_string = open(self.NAME_SPACE, 'r').read() default_namespace_definition_format = 'xmlns="http://www.w3.org/2002/xforms"' mangrove_service = MangroveService(self.mock_request, xls_parser_response=XlsParserResponse(xform_as_string=xform_as_string)) mangrove_service.xform = xform_as_string updated_xform = mangrove_service.add_form_code(None) self.assertTrue(updated_xform.find(default_namespace_definition_format) != -1)
def test_should_add_form_code_and_bind_element_to_xform(self): xform_as_string = open(self.NAME_SPACE, 'r').read() expected_form_code = '022-somthing-making-it-unique-in-xml' mangrove_service = MangroveService(self.mock_request, xls_parser_response=XlsParserResponse(xform_as_string=xform_as_string)) mangrove_service.xform = xform_as_string updated_xform = mangrove_service \ .add_form_code('%s' % expected_form_code) form_code = self._find_in_instance(updated_xform, 'form_code') self.assertEqual(form_code, expected_form_code)
def test_should_verify_xform_is_stored_when_project_created(self): manager = get_database_manager(self.user) questionnaire_code = generate_questionnaire_code(manager) project_name = 'xform-' + questionnaire_code xls_parser_response = XlsFormParser(self.REPEAT, u"My questionnairé").parse() mangrove_service = MangroveService(self.mock_request, project_name=project_name, xls_parser_response=xls_parser_response) mangrove_service.create_project() questionnaire_code = mangrove_service.questionnaire_code mgr = mangrove_service.manager from_model = get_form_model_by_code(mgr, questionnaire_code) self.assertIsNotNone(from_model.xform)
def post(self, request): file_content = None tmp_file = None try: file_content = request.raw_post_data file_errors, file_extension = _perform_file_validations(request) tmp_file = NamedTemporaryFile(delete=True, suffix=file_extension) if file_errors: logger.info( "User: %s. Upload File validation failed: %s. File name: %s, size: %d", request.user.username, json.dumps(file_errors), request.GET.get("qqfile"), int(request.META.get('CONTENT_LENGTH'))) return HttpResponse(json.dumps({ 'success': False, 'error_msg': file_errors }), content_type='application/json') tmp_file.write(file_content) tmp_file.seek(0) project_name = request.GET['pname'].strip() manager = get_database_manager(request.user) questionnaire_code = generate_questionnaire_code(manager) xls_parser_response = XlsFormParser(tmp_file, project_name, manager).parse() send_email_if_unique_id_type_question_has_no_registered_unique_ids( xls_parser_response, request, project_name) profile = request.user.get_profile() organization = Organization.objects.get(org_id=profile.org_id) if xls_parser_response.is_multiple_languages: logger.info( "Creating Questionnaire %s with Multi Language support for organization : %s(%s) and email: %s", project_name, organization.name, profile.org_id, profile.user.email) if xls_parser_response.errors: error_list = list(xls_parser_response.errors) logger.info("User: %s. Upload Errors: %s", request.user.username, json.dumps(error_list)) return HttpResponse( content_type='application/json', content=json.dumps({ 'success': False, 'error_msg': error_list, 'message_prefix': _("Sorry! Current version of DataWinners does not support" ), 'message_suffix': _("Update your XLSForm and upload again.") })) tmp_file.seek(0) mangrove_service = MangroveService( request, questionnaire_code=questionnaire_code, project_name=project_name, xls_form=tmp_file, xls_parser_response=xls_parser_response) questionnaire_id, form_code = mangrove_service.create_project() except PyXFormError as e: logger.info("User: %s. Upload Error: %s", request.user.username, e.message) message = transform_error_message(e.message) if 'name_type_error' in message or 'choice_name_type_error' in message: if 'choice_name_type_error' in message: message_prefix = _( "On your \"choices\" sheet the first and second column must be \"list_name\" and \"name\". Possible errors:" ) else: message_prefix = _( "On your \"survey\" sheet the first and second column must be \"type\" and \"name\". Possible errors:" ) return HttpResponse( content_type='application/json', content=json.dumps({ 'success': False, 'error_msg': [ _("Columns are missing"), _("Column name is misspelled"), _("Additional space in column name") ], 'message_prefix': message_prefix, 'message_suffix': _("Update your XLSForm and upload again.") })) else: return HttpResponse( content_type='application/json', content=json.dumps({ 'success': False, 'error_msg': [ message if message else ugettext( "all XLSForm features. Please check the list of unsupported features." ) ] })) except QuestionAlreadyExistsException as e: logger.info("User: %s. Upload Error: %s", request.user.username, e.message) return HttpResponse( content_type='application/json', content=json.dumps({ 'success': False, 'error_msg': [ _("Duplicate labels. All questions (labels) must be unique." ) ], 'message_prefix': _("Sorry! Current version of DataWinners does not support" ), 'message_suffix': _("Update your XLSForm and upload again.") })) except UnicodeDecodeError as e: logger.info("User: %s. Upload Error: %s", request.user.username, e.message) return HttpResponse( content_type='application/json', content=json.dumps({ 'success': False, 'error_msg': [ _("Check your columns for errors.<br>There are missing symbols (like $ for relevant or calculate) or incorrect characters<br>" ) + _("Update your XLSForm and upload again.") ], })) except Exception as e: message = e.message if e.message else _("Errors in excel") logger.info("User: %s. Upload Exception message: %s", request.user.username, e.message) odk_message = '' if not 'ODK Validate Errors:' in e.message: send_email_on_exception( request.user, "Questionnaire Create", traceback.format_exc(), additional_details={'file_contents': file_content}) else: odk_message = translate_odk_message(e.message) message = odk_message if odk_message else message return HttpResponse(content_type='application/json', content=json.dumps({ 'success': False, 'error_msg': [message], })) finally: if tmp_file: tmp_file.close() if not questionnaire_id: org = get_organization(request) if org.is_pro_sms: message = _( "Questionnaire or Poll with same name already exists.Upload was cancelled." ) else: message = _( "Questionnaire with same name already exists.Upload was cancelled." ) return HttpResponse(json.dumps({ 'success': False, 'duplicate_project_name': True, 'error_msg': [message] }), content_type='application/json') return HttpResponse(json.dumps({ "success": True, "project_name": project_name, "project_id": questionnaire_id, "form_code": form_code }), content_type='application/json')
def post(self, request, project_id): manager = get_database_manager(request.user) questionnaire = Project.get(manager, project_id) file_content = None tmp_file = None try: file_content = request.raw_post_data file_errors, file_extension = _perform_file_validations(request) tmp_file = NamedTemporaryFile(delete=True, suffix=file_extension) if file_errors: logger.info( "User: %s. Edit upload File validation failed: %s. File name: %s, size: %d", request.user.username, json.dumps(file_errors), request.GET.get("qqfile"), int(request.META.get('CONTENT_LENGTH'))) return HttpResponse(content_type='application/json', content=json.dumps({ 'success': False, 'error_msg': file_errors })) tmp_file.write(file_content) tmp_file.seek(0) xls_parser_response = XlsFormParser(tmp_file, questionnaire.name, manager).parse() send_email_if_unique_id_type_question_has_no_registered_unique_ids( xls_parser_response, request, questionnaire.name) profile = request.user.get_profile() organization = Organization.objects.get(org_id=profile.org_id) if xls_parser_response.is_multiple_languages: logger.info( "Edit Questionnaire %s with Multi Language support for organization : %s(%s) and email: %s", questionnaire.name, organization.name, profile.org_id, profile.user.email) if xls_parser_response.errors: info_list = list(xls_parser_response.errors) logger.info("User: %s. Edit upload Errors: %s", request.user.username, json.dumps(info_list)) return HttpResponse( content_type='application/json', content=json.dumps({ 'success': False, 'error_msg': info_list, 'message_prefix': _("Sorry! Current version of DataWinners does not support" ), 'message_suffix': _("Update your XLSForm and upload again.") })) mangrove_service = MangroveService( request, questionnaire_code=questionnaire.form_code, project_name=questionnaire.name, xls_parser_response=xls_parser_response) questionnaire.xform = mangrove_service.xform_with_form_code QuestionnaireBuilder(questionnaire, manager).update_questionnaire_with_questions( xls_parser_response.json_xform_data) tmp_file.seek(0) questionnaire.update_media_field_flag() questionnaire.save(process_post_update=False) base_name, extension = os.path.splitext(tmp_file.name) questionnaire.update_attachments(tmp_file, 'questionnaire%s' % extension) self._purge_submissions(manager, questionnaire) self._purge_feed_documents(questionnaire, request) self._purge_media_details_documents(manager, questionnaire) self.recreate_submissions_mapping(manager, questionnaire) if xls_parser_response.info: info_list = list(xls_parser_response.info) logger.info("User: %s. Edit upload Errors: %s", request.user.username, json.dumps(info_list)) return HttpResponse(content_type='application/json', content=json.dumps({ 'success': True, 'information': info_list, })) except PyXFormError as e: logger.info("User: %s. Upload Error: %s", request.user.username, e.message) message = transform_error_message(e.message) if 'name_type_error' in message or 'choice_name_type_error' in message: if 'choice_name_type_error' in message: message_prefix = _( "On your \"choices\" sheet the first and second column must be \"list_name\" and \"name\". Possible errors:" ) else: message_prefix = _( "On your \"survey\" sheet the first and second column must be \"type\" and \"name\". Possible errors:" ) return HttpResponse( content_type='application/json', content=json.dumps({ 'success': False, 'error_msg': [ _("Columns are missing"), _("Column name is misspelled"), _("Additional space in column name") ], 'message_prefix': message_prefix, 'message_suffix': _("Update your XLSForm and upload again.") })) else: return HttpResponse( content_type='application/json', content=json.dumps({ 'success': False, 'error_msg': [ message if message else ugettext( "all XLSForm features. Please check the list of unsupported features." ) ] })) except QuestionAlreadyExistsException as e: logger.info("User: %s. Upload Error: %s", request.user.username, e.message) return HttpResponse( content_type='application/json', content=json.dumps({ 'success': False, 'error_msg': [ _("Duplicate labels. All questions (labels) must be unique." ) ], 'message_prefix': _("Sorry! Current version of DataWinners does not support" ), 'message_suffix': _("Update your XLSForm and upload again.") })) except UnicodeDecodeError as e: logger.info("User: %s. Upload Error: %s", request.user.username, e.message) return HttpResponse( content_type='application/json', content=json.dumps({ 'success': False, 'error_msg': [ _("Check your columns for errors.<br>There are missing symbols (like $ for relevant or calculate) or incorrect characters<br>" ) + _("Update your XLSForm and upload again.") ], })) except Exception as e: logger.info("User: %s. Edit Upload Exception message: %s", request.user.username, e.message) message = e.message if e.message else _("Some error in excel") odk_message = '' if not 'ODK Validate Errors:' in e.message: send_email_on_exception( request.user, "Questionnaire Edit", traceback.format_exc(), additional_details={'file_contents': file_content}) else: odk_message = translate_odk_message(e.message) message = odk_message if odk_message else message return HttpResponse(content_type='application/json', content=json.dumps({ 'error_msg': [message], 'success': False, })) finally: if tmp_file: tmp_file.close() return HttpResponse( json.dumps({ "success": True, "project_name": questionnaire.name, "project_id": questionnaire.id, "file_name": "%s%s" % (slugify(questionnaire.name), extension), # "xls_dict": XlsProjectParser().parse(file_content) }), content_type='application/json')
def _overwrite(self, project_id, request): try: manager = get_database_manager(request.user) questionnaire = Project.get(manager, project_id) xls_parser_response = _try_parse_xls(manager, request, questionnaire.name) if isinstance(xls_parser_response, HttpResponse): return xls_parser_response send_email_if_unique_id_type_question_has_no_registered_unique_ids( xls_parser_response, request, questionnaire.name) mangrove_service = MangroveService( request, questionnaire_code=questionnaire.form_code, project_name=questionnaire.name, xls_parser_response=xls_parser_response) questionnaire.xform = mangrove_service.xform_with_form_code QuestionnaireBuilder(questionnaire, manager).update_questionnaire_with_questions( xls_parser_response.json_xform_data) questionnaire.update_media_field_flag() questionnaire.save(process_post_update=False) UserActivityLog().log(self.request, action=EDITED_QUESTIONNAIRE, project=questionnaire.name, detail=questionnaire.name) tmp_file = _temp_file(request) base_name, extension = os.path.splitext(tmp_file.name) questionnaire.update_attachments(tmp_file, 'questionnaire%s' % extension) questionnaire.update_external_itemset( mangrove_service.itemsets_csv) self._purge_submissions(manager, questionnaire) self._purge_feed_documents(questionnaire, request) self._purge_media_details_documents(manager, questionnaire) self.recreate_submissions_mapping(manager, questionnaire) excel_file = _temp_file(request) excel_file.seek(0) _save_questionnaire_as_dict_for_builder(questionnaire, excel_file=excel_file) if xls_parser_response.info: info_list = list(xls_parser_response.info) logger.info("User: %s. Edit upload Errors: %s", request.user.username, json.dumps(info_list)) return HttpResponse(content_type='application/json', content=json.dumps({ 'success': True, 'information': info_list, })) except QuestionAlreadyExistsException as e: return HttpResponse( content_type='application/json', content=json.dumps({ 'success': False, 'error_msg': [_(e.message)], "status": "error", 'reason': "Save Failed", # TODO: i18n translation 'details': _(e.message) })) return HttpResponse( json.dumps({ "success": True, "project_name": questionnaire.name, "project_id": questionnaire.id, "file_name": "%s%s" % (slugify(questionnaire.name), extension), # "xls_dict": XlsProjectParser().parse(file_content) }), content_type='application/json')
def _edit_questionnaire(request, project_id, excel_file=None, excel_as_dict=None): manager = get_database_manager(request.user) questionnaire = Project.get(manager, project_id) try: xls_parser_response = _try_parse_xls(manager, request, questionnaire.name, excel_file) if isinstance(xls_parser_response, HttpResponse): return xls_parser_response doc = deepcopy(questionnaire._doc) doc.xform = MangroveService( request, questionnaire_code=questionnaire.form_code, xls_parser_response=xls_parser_response).xform_with_form_code new_questionnaire = Project.new_from_doc(manager, doc) QuestionnaireBuilder(new_questionnaire, manager).update_questionnaire_with_questions( xls_parser_response.json_xform_data) xform_rules = get_all_rules() if excel_file is None: excel_file = _temp_file(request) else: excel_file.seek(0) questionnaire_wrapper = Questionnaire(excel_file) activity_log_detail = {} XFormEditor( Submission(manager, get_database_name(request.user), xform_rules), Validator(xform_rules), questionnaire_wrapper).edit(new_questionnaire, questionnaire, activity_log_detail) questionnaire = Project.get(manager, project_id) _save_questionnaire_as_dict_for_builder(questionnaire, excel_as_dict, excel_file) UserActivityLog().log(request, action=EDITED_QUESTIONNAIRE, project=questionnaire.name, detail=json.dumps(activity_log_detail)) except UnsupportedXformEditException as e: return HttpResponse( content_type='application/json', content=json.dumps({ 'success': False, 'unsupported': True, 'error_msg': [_("Unsupported edit operation")], "status": "error", 'reason': "Unsupported edit operation", # TODO: i18n translation 'details': e.message })) except QuestionAlreadyExistsException as e: return HttpResponse( content_type='application/json', content=json.dumps({ 'success': False, 'error_msg': [_(e.message)], "status": "error", 'reason': "Save Failed", # TODO: i18n translation 'details': _(e.message) })) return HttpResponse( json.dumps({ "success": True, "status": "success", 'reason': 'Successfully updated' # TODO: i18n translation }), content_type='application/json')