Example #1
0
def _get_new_form_json(xml, xform_id):
    form_json = convert_xform_to_json(xml)
    with force_phone_timezones_should_be_processed():
        adjust_datetimes(form_json)
    # this is actually in-place because of how jsonobject works
    scrub_meta(XFormInstance.wrap({'form': form_json, '_id': xform_id}))
    return form_json
Example #2
0
 def _migrate_form_and_associated_models(self,
                                         couch_form,
                                         form_is_processed=True):
     """
     Copies `couch_form` into a new sql form
     """
     if form_is_processed:
         form_data = couch_form.form
         with force_phone_timezones_should_be_processed():
             adjust_datetimes(form_data)
         xmlns = form_data.get("@xmlns", "")
         user_id = extract_meta_user_id(form_data)
     else:
         xmlns = couch_form.xmlns
         user_id = couch_form.user_id
     sql_form = XFormInstanceSQL(
         form_id=couch_form.form_id,
         domain=self.domain,
         xmlns=xmlns,
         user_id=user_id,
     )
     _copy_form_properties(sql_form, couch_form)
     _migrate_form_attachments(sql_form, couch_form)
     _migrate_form_operations(sql_form, couch_form)
     if couch_form.doc_type != 'SubmissionErrorLog':
         self._save_diffs(couch_form, sql_form)
     case_stock_result = self._get_case_stock_result(
         sql_form, couch_form) if form_is_processed else None
     _save_migrated_models(sql_form, case_stock_result)
Example #3
0
def _get_all_stock_report_helpers_from_form(xform):
    """
    Given an instance of an AbstractXFormInstance, extract the ledger actions and convert
    them to StockReportHelper objects.
    """
    form_xml = xform.get_xml_element()
    commtrack_node_names = ('{%s}balance' % COMMTRACK_REPORT_XMLNS,
                            '{%s}transfer' % COMMTRACK_REPORT_XMLNS)

    def _extract_ledger_nodes_from_xml(node):
        """
        Goes through a parsed XML document and recursively pulls out any ledger XML blocks.
        """
        for child in node:
            if child.tag in commtrack_node_names:
                yield child
            else:
                for e in _extract_ledger_nodes_from_xml(child):
                    yield e

    for elem in _extract_ledger_nodes_from_xml(form_xml):
        report_type, ledger_json = convert_xml_to_json(elem, last_xmlns=COMMTRACK_REPORT_XMLNS)

        # apply the same datetime & string conversions
        # that would be applied to XFormInstance.form
        adjust_datetimes(ledger_json)
        ledger_json = XFormInstance({'form': ledger_json}).form
        yield _ledger_json_to_stock_report_helper(xform, report_type, ledger_json)
Example #4
0
def _get_new_form_json(xml, xform_id):
    form_json = convert_xform_to_json(xml)
    with force_phone_timezones_should_be_processed():
        adjust_datetimes(form_json)
    # this is actually in-place because of how jsonobject works
    scrub_meta(XFormInstance.wrap({'form': form_json, '_id': xform_id}))
    return form_json
Example #5
0
def get_all_stock_report_helpers_from_form(xform):
    """
    Given an instance of an AbstractXFormInstance, extract the ledger actions and convert
    them to StockReportHelper objects.
    """
    form_xml = xform.get_xml_element()
    commtrack_node_names = ('{%s}balance' % COMMTRACK_REPORT_XMLNS,
                            '{%s}transfer' % COMMTRACK_REPORT_XMLNS)

    def _extract_ledger_nodes_from_xml(node):
        """
        Goes through a parsed XML document and recursively pulls out any ledger XML blocks.
        """
        for child in node:
            if child.tag in commtrack_node_names:
                yield child
            else:
                for e in _extract_ledger_nodes_from_xml(child):
                    yield e

    for elem in _extract_ledger_nodes_from_xml(form_xml):
        report_type, ledger_json = convert_xml_to_json(
            elem, last_xmlns=COMMTRACK_REPORT_XMLNS)

        # apply the same datetime & string conversions
        # that would be applied to XFormInstance.form
        adjust_datetimes(ledger_json)
        ledger_json = XFormInstance({'form': ledger_json}).form
        yield _ledger_json_to_stock_report_helper(xform, report_type,
                                                  ledger_json)
Example #6
0
 def test_strip_tz(self):
     if phone_timezones_should_be_processed():
         self.assertEqual(
             adjust_datetimes({'datetime': '2013-03-09T06:30:09.007+03'}),
             {'datetime': '2013-03-09T03:30:09.007000Z'})
     else:
         self.assertEqual(
             adjust_datetimes({'datetime': '2013-03-09T06:30:09.007+03'}),
             {'datetime': '2013-03-09T06:30:09.007000Z'})
 def _migrate_form_and_associated_models(self,
                                         couch_form,
                                         form_is_processed=True):
     """
     Copies `couch_form` into a new sql form
     """
     sql_form = None
     try:
         if form_is_processed:
             form_data = couch_form.form
             with force_phone_timezones_should_be_processed():
                 adjust_datetimes(form_data)
             xmlns = form_data.get("@xmlns", "")
             user_id = extract_meta_user_id(form_data)
         else:
             xmlns = couch_form.xmlns
             user_id = couch_form.user_id
         if xmlns == SYSTEM_ACTION_XMLNS:
             for form_id, case_ids in do_system_action(couch_form):
                 self.case_diff_queue.update(case_ids, form_id)
         sql_form = XFormInstanceSQL(
             form_id=couch_form.form_id,
             domain=self.domain,
             xmlns=xmlns,
             user_id=user_id,
         )
         _copy_form_properties(sql_form, couch_form)
         _migrate_form_attachments(sql_form, couch_form)
         _migrate_form_operations(sql_form, couch_form)
         case_stock_result = (self._get_case_stock_result(
             sql_form, couch_form) if form_is_processed else None)
         _save_migrated_models(sql_form, case_stock_result)
     except IntegrityError as err:
         exc_info = sys.exc_info()
         try:
             sql_form = FormAccessorSQL.get_form(couch_form.form_id)
         except XFormNotFound:
             proc = "" if form_is_processed else " unprocessed"
             log.error("Error migrating%s form %s",
                       proc,
                       couch_form.form_id,
                       exc_info=exc_info)
         if self.stop_on_error:
             raise err from None
     except Exception as err:
         proc = "" if form_is_processed else " unprocessed"
         log.exception("Error migrating%s form %s", proc,
                       couch_form.form_id)
         try:
             sql_form = FormAccessorSQL.get_form(couch_form.form_id)
         except XFormNotFound:
             pass
         if self.stop_on_error:
             raise err from None
     finally:
         if couch_form.doc_type != 'SubmissionErrorLog':
             self._save_diffs(couch_form, sql_form)
 def test_strip_tz(self):
     if phone_timezones_should_be_processed():
         self.assertEqual(
             adjust_datetimes({'datetime': '2013-03-09T06:30:09.007+03'}),
             {'datetime': '2013-03-09T03:30:09.007000Z'}
         )
     else:
         self.assertEqual(
             adjust_datetimes({'datetime': '2013-03-09T06:30:09.007+03'}),
             {'datetime': '2013-03-09T06:30:09.007000Z'}
         )
Example #9
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
Example #10
0
def _migrate_form(domain, couch_form):
    """
    This copies the couch form into a new sql form but does not save it.

    See form_processor.parsers.form._create_new_xform
    and SubmissionPost._set_submission_properties for what this should do.
    """
    interface = FormProcessorInterface(domain)

    form_data = couch_form.form
    with force_phone_timezones_should_be_processed():
        adjust_datetimes(form_data)
    sql_form = interface.new_xform(form_data)
    sql_form.form_id = couch_form.form_id   # some legacy forms don't have ID's so are assigned random ones
    if sql_form.xmlns is None:
        sql_form.xmlns = ''
    return _copy_form_properties(domain, sql_form, couch_form)
def _migrate_form(domain, couch_form):
    """
    This copies the couch form into a new sql form but does not save it.

    See form_processor.parsers.form._create_new_xform
    and SubmissionPost._set_submission_properties for what this should do.
    """
    interface = FormProcessorInterface(domain)

    form_data = couch_form.form
    with force_phone_timezones_should_be_processed():
        adjust_datetimes(form_data)
    sql_form = interface.new_xform(form_data)
    sql_form.form_id = couch_form.form_id   # some legacy forms don't have ID's so are assigned random ones
    if sql_form.xmlns is None:
        sql_form.xmlns = ''
    return _copy_form_properties(domain, sql_form, couch_form)
Example #12
0
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
Example #13
0
def unpack_commtrack(xform):
    form_xml = xform.get_xml_element()
    commtrack_node_names = ('{%s}balance' % COMMTRACK_REPORT_XMLNS,
                            '{%s}transfer' % COMMTRACK_REPORT_XMLNS)

    def commtrack_nodes(node):
        for child in node:
            if child.tag in commtrack_node_names:
                yield child
            else:
                for e in commtrack_nodes(child):
                    yield e

    for elem in commtrack_nodes(form_xml):
        report_type, ledger_json = convert_xml_to_json(
            elem, last_xmlns=COMMTRACK_REPORT_XMLNS)

        # apply the same datetime & string conversions
        # that would be applied to XFormInstance.form
        adjust_datetimes(ledger_json)
        ledger_json = XFormInstance({'form': ledger_json}).form

        yield ledger_json_to_stock_report_helper(
            xform, report_type, ledger_json)
 def test_date_no_change(self):
     self.assertEqual(adjust_datetimes({'date': '2015-04-03'}),
                      {'date': '2015-04-03'})
Example #15
0
 def test_match_no_parse(self):
     fake_datetime = '2015-07-14 2015-06-07 '
     self.assertEqual(adjust_datetimes({'fake_datetime': fake_datetime}),
                      {'fake_datetime': fake_datetime})
Example #16
0
 def test_no_tz(self):
     self.assertEqual(
         adjust_datetimes({'datetime': '2013-03-09T06:30:09.007'}),
         {'datetime': '2013-03-09T06:30:09.007000Z'})
Example #17
0
 def test_date_no_change(self):
     self.assertEqual(adjust_datetimes({'date': '2015-04-03'}),
                      {'date': '2015-04-03'})
 def test_match_no_parse(self):
     fake_datetime = '2015-07-14 2015-06-07 '
     self.assertEqual(
         adjust_datetimes({'fake_datetime': fake_datetime}),
         {'fake_datetime': fake_datetime}
     )
 def test_no_tz(self):
     self.assertEqual(
         adjust_datetimes({'datetime': '2013-03-09T06:30:09.007'}),
         {'datetime': '2013-03-09T06:30:09.007000Z'}
     )