def _handle_id_conflict(xform, domain): """ For id conflicts, we check if the files contain exactly the same content, If they do, we just log this as a dupe. If they don't, we deprecate the previous form and overwrite it with the new form's contents. :returns: A two-tuple: `(<new form>, <duplicate form or None>)` The new form may have a different `form_id` than `xform.form_id`. """ assert domain conflict_id = xform.form_id interface = FormProcessorInterface(domain) if interface.is_duplicate(conflict_id, domain): # It looks like a duplicate/edit in the same domain so pursue that workflow. logging.info('Handling duplicate doc id %s for domain %s', conflict_id, domain) return _handle_duplicate(xform) else: # the same form was submitted to two domains, or a form was submitted with # an ID that belonged to a different doc type. these are likely developers # manually testing or broken API users. just resubmit with a generated ID. interface.assign_new_id(xform) logging.info('Reassigned doc id from %s to %s', conflict_id, xform.form_id) return xform, None
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
def _handle_id_conflict(instance, xform, domain): """ For id conflicts, we check if the files contain exactly the same content, If they do, we just log this as a dupe. If they don't, we deprecate the previous form and overwrite it with the new form's contents. """ assert domain conflict_id = xform.form_id interface = FormProcessorInterface(domain) if interface.is_duplicate(conflict_id, domain): # It looks like a duplicate/edit in the same domain so pursue that workflow. return _handle_duplicate(xform, instance) else: # the same form was submitted to two domains, or a form was submitted with # an ID that belonged to a different doc type. these are likely developers # manually testing or broken API users. just resubmit with a generated ID. xform = interface.assign_new_id(xform) return FormProcessingResult(xform)
def _handle_id_conflict(xform, domain): """ For id conflicts, we check if the files contain exactly the same content, If they do, we just log this as a dupe. If they don't, we deprecate the previous form and overwrite it with the new form's contents. """ assert domain conflict_id = xform.form_id interface = FormProcessorInterface(domain) if interface.is_duplicate(conflict_id, domain): # It looks like a duplicate/edit in the same domain so pursue that workflow. return _handle_duplicate(xform) else: # the same form was submitted to two domains, or a form was submitted with # an ID that belonged to a different doc type. these are likely developers # manually testing or broken API users. just resubmit with a generated ID. xform = interface.assign_new_id(xform) return FormProcessingResult(xform)
def _create_new_xform(domain, instance_xml, attachments=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 # 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