예제 #1
0
 def get_form_xml_metadata(meta):
     try:
         couch_form._unsafe_get_xml()
         assert meta is not None, couch_form.form_id
         return meta
     except MissingFormXml:
         pass
     log.warning("Rebuilding missing form XML: %s", couch_form.form_id)
     metas = get_blob_metadata(couch_form.form_id)[(CODES.form_xml,
                                                    "form.xml")]
     if len(metas) == 1:
         couch_meta = couch_form.blobs.get("form.xml")
         if couch_meta is None:
             assert not metas[0].blob_exists(), metas
         else:
             assert metas[0].key == couch_meta.key, (metas, couch_meta)
         blobdb.delete(metas[0].key)
         metas.remove(metas[0])
     else:
         assert not metas, metas  # protect against yet another duplicate
     xml = convert_form_to_xml(couch_form.to_json()["form"])
     att = Attachment("form.xml",
                      xml.encode("utf-8"),
                      content_type="text/xml")
     return att.write(blobdb, sql_form)
예제 #2
0
파일: utils.py 프로젝트: caktus/commcare-hq
def create_form_for_test(domain,
                         case_id=None,
                         attachments=None,
                         save=True,
                         state=XFormInstanceSQL.NORMAL,
                         received_on=None,
                         user_id='user1',
                         edited_on=None):
    """
    Create the models directly so that these tests aren't dependent on any
    other apps. Not testing form processing here anyway.
    :param case_id: create case with ID if supplied
    :param attachments: additional attachments dict
    :param save: if False return the unsaved form
    :return: form object
    """
    from corehq.form_processor.utils import get_simple_form_xml

    form_id = uuid4().hex
    utcnow = received_on or datetime.utcnow()

    form_xml = get_simple_form_xml(form_id, case_id)

    form = XFormInstanceSQL(
        form_id=form_id,
        xmlns='http://openrosa.org/formdesigner/form-processor',
        received_on=utcnow,
        user_id=user_id,
        domain=domain,
        state=state,
        edited_on=edited_on,
    )

    attachments = attachments or {}
    attachment_tuples = [
        Attachment(name=a[0], raw_content=a[1], content_type=a[1].content_type)
        for a in attachments.items()
    ]
    attachment_tuples.append(Attachment('form.xml', form_xml, 'text/xml'))

    FormProcessorSQL.store_attachments(form, attachment_tuples)

    cases = []
    if case_id:
        case = CommCareCaseSQL(
            case_id=case_id,
            domain=domain,
            type='',
            owner_id=user_id,
            opened_on=utcnow,
            modified_on=utcnow,
            modified_by=user_id,
            server_modified_on=utcnow,
        )
        case.track_create(CaseTransaction.form_transaction(case, form, utcnow))
        cases = [case]
예제 #3
0
def _create_new_xform(domain,
                      instance_xml,
                      attachments=None,
                      auth_context=None):
    """
    create but do not save an XFormInstance from an xform payload (xml_string)
    optionally set the doc _id to a predefined value (_id)
    return doc _id of the created doc

    `process` is transformation to apply to the form right before saving
    This is to avoid having to save multiple times

    If xml_string is bad xml
      - raise couchforms.XMLSyntaxError
      :param domain:

    """
    from corehq.form_processor.interfaces.processor import FormProcessorInterface
    interface = FormProcessorInterface(domain)

    assert attachments is not None
    form_data = convert_xform_to_json(instance_xml)
    if not form_data.get('@xmlns'):
        raise MissingXMLNSError("Form is missing a required field: XMLNS")

    adjust_datetimes(form_data)

    xform = interface.new_xform(form_data)
    xform.domain = domain
    xform.auth_context = auth_context

    # Maps all attachments to uniform format and adds form.xml to list before storing
    attachments = map(
        lambda a: Attachment(
            name=a[0], raw_content=a[1], content_type=a[1].content_type),
        attachments.items())
    attachments.append(
        Attachment(name='form.xml',
                   raw_content=instance_xml,
                   content_type='text/xml'))
    interface.store_attachments(xform, attachments)

    result = LockedFormProcessingResult(xform)
    with ReleaseOnError(result.lock):
        if interface.is_duplicate(xform.form_id):
            raise DuplicateError(xform)

    return result
예제 #4
0
def get_form_ready_to_save(metadata, is_db_test=False):
    from corehq.form_processor.parsers.form import process_xform_xml
    from corehq.form_processor.utils import get_simple_form_xml, convert_xform_to_json
    from corehq.form_processor.interfaces.processor import FormProcessorInterface
    from corehq.form_processor.models import Attachment

    assert metadata is not None
    metadata.domain = metadata.domain or uuid.uuid4().hex
    form_id = uuid.uuid4().hex
    form_xml = get_simple_form_xml(form_id=form_id, metadata=metadata)

    if is_db_test:
        wrapped_form = process_xform_xml(metadata.domain,
                                         form_xml).submitted_form
    else:
        interface = FormProcessorInterface(domain=metadata.domain)
        form_json = convert_xform_to_json(form_xml)
        wrapped_form = interface.new_xform(form_json)
        wrapped_form.domain = metadata.domain
        interface.store_attachments(wrapped_form, [
            Attachment(
                name='form.xml', raw_content=form_xml, content_type='text/xml')
        ])
    wrapped_form.received_on = metadata.received_on
    wrapped_form.app_id = metadata.app_id
    return wrapped_form
예제 #5
0
    def update_responses(self, xform, value_responses_map, user_id):
        """
        Update a set of question responses. Returns a list of any
        questions that were not found in the xform.
        """
        from corehq.form_processor.interfaces.dbaccessors import FormAccessors
        from corehq.form_processor.utils.xform import update_response

        errors = []
        xml = xform.get_xml_element()
        for question, response in six.iteritems(value_responses_map):
            try:
                update_response(xml, question, response, xmlns=xform.xmlns)
            except XFormQuestionValueNotFound:
                errors.append(question)

        existing_form = FormAccessors(xform.domain).get_with_attachments(
            xform.get_id)
        existing_form, new_form = self.processor.new_form_from_old(
            existing_form, xml, value_responses_map, user_id)
        new_xml = etree.tostring(xml)
        interface = FormProcessorInterface(xform.domain)
        interface.store_attachments(new_form, [
            Attachment(name=ATTACHMENT_NAME,
                       raw_content=new_xml,
                       content_type='text/xml')
        ])
        interface.save_processed_models([new_form, existing_form])

        return errors
예제 #6
0
    def update_responses(self, xform, value_responses_map, user_id):
        from corehq.form_processor.utils.xform import update_response

        xml = xform.get_xml_element()
        dirty = False
        for question, response in six.iteritems(value_responses_map):
            if update_response(xml, question, response, xmlns=xform.xmlns):
                dirty = True

        if dirty:
            from couchforms.const import ATTACHMENT_NAME
            from corehq.form_processor.interfaces.dbaccessors import FormAccessors
            from corehq.form_processor.models import Attachment

            existing_form = FormAccessors(xform.domain).get_with_attachments(xform.get_id)
            existing_form, new_form = self.processor.new_form_from_old(existing_form, xml,
                                                                       value_responses_map, user_id)
            new_xml = etree.tostring(xml)
            interface = FormProcessorInterface(xform.domain)
            interface.store_attachments(new_form, [
                Attachment(name=ATTACHMENT_NAME, raw_content=new_xml, content_type='text/xml')
            ])
            interface.save_processed_models([new_form, existing_form])
            return True

        return False
예제 #7
0
def get_simple_wrapped_form(form_id, case_id=None, metadata=None, save=True):
    from corehq.form_processor.interfaces.processor import FormProcessorInterface

    metadata = metadata or TestFormMetadata()
    xml = get_simple_form_xml(form_id=form_id, metadata=metadata)
    form_json = convert_xform_to_json(xml)
    interface = FormProcessorInterface(domain=metadata.domain)
    wrapped_form = interface.new_xform(form_json)
    wrapped_form.domain = metadata.domain
    interface.store_attachments(wrapped_form, [Attachment('form.xml', xml, 'text/xml')])
    if save:
        interface.save_processed_models([wrapped_form])

    return wrapped_form
예제 #8
0
    def submission_error_form_instance(cls, domain, instance, message):
        xform = XFormInstanceSQL(
            domain=domain,
            form_id=uuid.uuid4().hex,
            received_on=datetime.datetime.utcnow(),
            problem=message,
            state=XFormInstanceSQL.SUBMISSION_ERROR_LOG
        )
        cls.store_attachments(xform, [Attachment(
            name=ATTACHMENT_NAME,
            raw_content=instance,
            content_type='text/xml',
        )])

        return xform
예제 #9
0
def get_simple_wrapped_form(form_id, metadata=None, save=True, simple_form=SIMPLE_FORM):
    from corehq.form_processor.interfaces.processor import FormProcessorInterface
    from corehq.form_processor.interfaces.dbaccessors import FormAccessors

    metadata = metadata or TestFormMetadata()
    xml = get_simple_form_xml(form_id=form_id, metadata=metadata, simple_form=simple_form)
    form_json = convert_xform_to_json(xml)
    interface = FormProcessorInterface(domain=metadata.domain)
    wrapped_form = interface.new_xform(form_json)
    wrapped_form.domain = metadata.domain
    wrapped_form.received_on = metadata.received_on
    interface.store_attachments(wrapped_form, [Attachment('form.xml', xml, 'text/xml')])
    if save:
        interface.save_processed_models([wrapped_form])
        wrapped_form = FormAccessors(metadata.domain).get_form(wrapped_form.form_id)
    return wrapped_form
예제 #10
0
    def new_form_from_old(cls, existing_form, xml, value_responses_map, user_id):
        from corehq.form_processor.parsers.form import apply_deprecation

        new_xml = etree.tostring(xml)
        form_json = convert_xform_to_json(new_xml)
        new_form = cls.new_xform(form_json)
        new_form.user_id = user_id
        new_form.domain = existing_form.domain
        new_form.app_id = existing_form.app_id
        cls.store_attachments(new_form, [Attachment(
            name=ATTACHMENT_NAME,
            raw_content=new_xml,
            content_type='text/xml',
        )])

        existing_form, new_form = apply_deprecation(existing_form, new_form)
        return (existing_form, new_form)
예제 #11
0
def add_form_xml(sql_form, patch_form):
    xml = patch_form.get_xml()
    att = Attachment("form.xml", xml.encode("utf-8"), content_type="text/xml")
    xml_meta = att.write(get_blob_db(), sql_form)
    sql_form.attachments_list = [xml_meta]
예제 #12
0
 def create_attachment_with_content(content):
     return Attachment(name='test_attachment',
                       raw_content=content,
                       content_type='text')