示例#1
0
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
示例#2
0
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
示例#3
0
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
示例#4
0
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)
示例#5
0
    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)
示例#7
0
    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)
示例#8
0
    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)
示例#9
0
文件: parser.py 项目: onaio/onadata
    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)