def create_submission(request, username, data_dict, xform_id): """ Returns validated data object instances """ xml_string = dict2xform(data_dict, xform_id) xml_file = StringIO.StringIO(xml_string) error, instance = safe_create_instance(username, xml_file, [], None, request) if error: raise serializers.ValidationError(error.message) return instance
def create_submission(request, username, data_dict, xform_id): """ Returns validated data object instances """ xml_string = dict2xform(data_dict, xform_id) xml_file = BytesIO(xml_string.encode('utf-8')) error, instance = safe_create_instance(username, xml_file, [], None, request) if error: raise serializers.ValidationError(error.message) return instance
def create_submission( request, username, data_dict, xform_id, gen_uuid: bool = False): """ Returns validated data object instances """ xml_string = dict2xform( data_dict, xform_id, username=username, gen_uuid=gen_uuid) xml_file = BytesIO(xml_string.encode('utf-8')) error, instance = safe_create_instance(username, xml_file, [], None, request) if error: raise serializers.ValidationError(error.message) return instance
def create_instance_from_json(username, request): request.accepted_renderer = JSONRenderer() request.accepted_media_type = JSONRenderer.media_type dict_form = request.data submission = dict_form.get('submission') if submission is None: # return an error return [t("No submission key provided."), None] # convert lists in submission dict to joined strings submission_joined = dict_lists2strings(submission) xml_string = dict2xform(submission_joined, dict_form.get('id')) xml_file = io.StringIO(xml_string) return safe_create_instance(username, xml_file, [], None, request)
def create(self, validated_data): request = self.context['request'] responses = validated_data['responses'] xform = get_object_or_404(XForm, uuid=validated_data['id']) processed = [] for submission in parse_responses(responses): xml_file = BytesIO(dict2xform( submission, xform.id_string, 'data').encode('utf-8')) error, instance = safe_create_instance( request.user.username, xml_file, [], None, request) processed.append(instance.pk) if error: raise serializers.ValidationError(error) return FlowResultsResponse(xform.uuid, responses)
def create_instance_from_json(username, request): request.accepted_renderer = JSONRenderer() request.accepted_media_type = JSONRenderer.media_type dict_form = request.data submission = dict_form.get('submission') if submission is None: # return an error return [_(u"No submission key provided."), None] # convert lists in submission dict to joined strings submission_joined = dict_lists2strings(submission) xml_string = dict2xform(submission_joined, dict_form.get('id')) xml_file = StringIO.StringIO(xml_string) return safe_create_instance(username, xml_file, [], None, request)
def create(self, validated_data): duplicates = 0 request = self.context['request'] responses = validated_data['responses'] xform = get_object_or_404(XForm, uuid=validated_data['id'], deleted_at__isnull=True) for submission in parse_responses(responses): xml_file = BytesIO(dict2xform( submission, xform.id_string, 'data').encode('utf-8')) error, _instance = safe_create_instance( request.user.username, xml_file, [], None, request) if error and error.status_code != 202: raise serializers.ValidationError(error) if error and error.status_code == 202: duplicates += 1 return FlowResultsResponse(xform.uuid, responses, duplicates)
def process_incoming(incoming, id_string): # assign variables if len(incoming) >= 2: identity = incoming[0].strip().lower() text = incoming[1].strip().lower() # if the tuple contain an id_string, use it, otherwise default if len(incoming) and id_string is None >= 3: id_string = incoming[2] else: responses.append({ 'code': SMS_API_ERROR, 'text': _(u"Missing 'identity' " u"or 'text' field.") }) return if not len(identity.strip()) or not len(text.strip()): responses.append({ 'code': SMS_API_ERROR, 'text': _(u"'identity' and 'text' fields can " u"not be empty.") }) return # if no id_string has been supplied # we expect the SMS to be prefixed with the form's sms_id_string if id_string is None: keyword, text = [s.strip() for s in text.split(None, 1)] xform = XForm.objects.get(user__username=username, sms_id_string=keyword) else: xform = XForm.objects.get(user__username=username, id_string=id_string) if not xform.allows_sms: responses.append({ 'code': SMS_SUBMISSION_REFUSED, 'text': _(u"The form '%(id_string)s' does not " u"accept SMS submissions.") % { 'id_string': xform.id_string } }) return # parse text into a dict object of groups with values json_submission, medias_submission, notes = parse_sms_text( xform, identity, text) # retrieve sms_response if exist in the form. json_survey = json.loads(xform.json) if json_survey.get('sms_response'): resp_str.update({'success': json_survey.get('sms_response')}) # check that the form contains at least one filled group meta_groups = sum( [1 for k in json_submission.keys() if k.startswith('meta')]) if len(json_submission.keys()) <= meta_groups: responses.append({ 'code': SMS_PARSING_ERROR, 'text': _(u"There must be at least one group of " u"questions filled.") }) return # check that required fields have been filled required_fields = [ f.get('name') for g in json_survey.get('children', {}) for f in g.get('children', {}) if f.get('bind', {}).get('required', 'no') == 'yes' ] submitted_fields = {} for group in json_submission.values(): submitted_fields.update(group) for field in required_fields: if not submitted_fields.get(field): responses.append({ 'code': SMS_SUBMISSION_REFUSED, 'text': _(u"Required field `%(field)s` is " u"missing.") % { 'field': field } }) return # convert dict object into an XForm string xml_submission = dict2xform(jsform=json_submission, form_id=xform.id_string) # compute notes data = {} for g in json_submission.values(): data.update(g) for idx, note in enumerate(notes): try: notes[idx] = note.replace('${', '{').format(**data) except: pass # process_incoming expectes submission to be a file-like object xforms.append(StringIO.StringIO(xml_submission)) medias.append(medias_submission) json_submissions.append(json_submission) xforms_notes.append(notes)
def process_incoming(incoming, id_string): # assign variables if len(incoming) >= 2: identity = incoming[0].strip().lower() text = incoming[1].strip().lower() # if the tuple contains an id_string, use it, otherwise default if id_string is None and len(incoming) >= 3: id_string = incoming[2] else: responses.append({'code': SMS_API_ERROR, 'text': _(u"Missing 'identity' " u"or 'text' field.")}) return if not len(identity.strip()) or not len(text.strip()): responses.append({'code': SMS_API_ERROR, 'text': _(u"'identity' and 'text' fields can " u"not be empty.")}) return # if no id_string has been supplied # we expect the SMS to be prefixed with the form's sms_id_string if id_string is None: keyword, text = [s.strip() for s in text.split(None, 1)] xform = XForm.objects.get(user__username=username, sms_id_string=keyword) else: xform = XForm.objects.get(user__username=username, id_string=id_string) if not xform.allows_sms: responses.append({'code': SMS_SUBMISSION_REFUSED, 'text': _(u"The form '%(id_string)s' does not " u"accept SMS submissions.") % {'id_string': xform.id_string}}) return # parse text into a dict object of groups with values json_submission, medias_submission, notes = parse_sms_text(xform, identity, text) # retrieve sms_response if exist in the form. json_survey = json.loads(xform.json) if json_survey.get('sms_response'): resp_str.update({'success': json_survey.get('sms_response')}) # check that the form contains at least one filled group meta_groups = sum([1 for k in list(json_submission) if k.startswith('meta')]) if len(list(json_submission)) <= meta_groups: responses.append({'code': SMS_PARSING_ERROR, 'text': _(u"There must be at least one group of " u"questions filled.")}) return # check that required fields have been filled required_fields = [f.get('name') for g in json_survey.get('children', {}) for f in g.get('children', {}) if f.get('bind', {}).get('required', 'no') == 'yes'] submitted_fields = {} for group in json_submission.values(): submitted_fields.update(group) for field in required_fields: if not submitted_fields.get(field): responses.append({'code': SMS_SUBMISSION_REFUSED, 'text': _(u"Required field `%(field)s` is " u"missing.") % {'field': field}}) return # convert dict object into an XForm string xml_submission = dict2xform(jsform=json_submission, form_id=xform.id_string) # compute notes data = {} for g in json_submission.values(): data.update(g) for idx, note in enumerate(notes): try: notes[idx] = note.replace('${', '{').format(**data) except Exception as e: logging.exception(_(u'Updating note threw exception: %s' % text(e))) # process_incoming expectes submission to be a file-like object xforms.append(BytesIO(xml_submission.encode('utf-8'))) medias.append(medias_submission) json_submissions.append(json_submission) xforms_notes.append(notes)