示例#1
0
 def deduplicate_xform(cls, xform):
     # follow standard dupe handling, which simply saves a copy of the form
     # but a new doc_id, and a doc_type of XFormDuplicate
     xform.doc_type = XFormDuplicate.__name__
     dupe = XFormDuplicate.wrap(xform.to_json())
     dupe.problem = "Form is a duplicate of another! (%s)" % xform._id
     return cls.assign_new_id(dupe)
    def swap_doc_types(self, log_file, bad_xform_id, duplicate_xform_id, domain, dry_run):
        bad_xform = XFormInstance.get(bad_xform_id)

        # confirm that the doc hasn't already been fixed:
        bad_xform_problem = None
        try:
            bad_xform_problem = bad_xform.problem or ""
        except AttributeError:
            pass
        if bad_xform_problem:
            if re.match(PROBLEM_TEMPLATE_START, bad_xform_problem):
                self.log_already_fixed(log_file, bad_xform_id, domain)
                return

        duplicate_xform = XFormInstance.get(duplicate_xform_id)
        now = datetime.now().isoformat()

        # Convert the XFormInstance to an XFormDuplicate
        bad_xform.doc_type = XFormDuplicate.__name__
        bad_xform.problem = BAD_FORM_PROBLEM_TEMPLATE.format(duplicate_xform_id, now)
        bad_xform = XFormDuplicate.wrap(bad_xform.to_json())

        # Convert the XFormDuplicate to an XFormInstance
        duplicate_xform.problem = FIXED_FORM_PROBLEM_TEMPLATE.format(
            id_=bad_xform_id, datetime_=now
        )
        duplicate_xform.doc_type = XFormInstance.__name__
        duplicate_xform = XFormInstance.wrap(duplicate_xform.to_json())

        self.log_swap(log_file, bad_xform_id, domain, duplicate_xform_id, dry_run)

        if not dry_run:
            duplicate_xform.save()
            bad_xform.save()
示例#3
0
    def swap_doc_types(self, log_file, bad_xform_id, duplicate_xform_id, domain, dry_run):
        bad_xform = XFormInstance.get(bad_xform_id)

        # confirm that the doc hasn't already been fixed:
        bad_xform_problem = None
        try:
            bad_xform_problem = bad_xform.problem or ""
        except AttributeError:
            pass
        if bad_xform_problem:
            if re.match(PROBLEM_TEMPLATE_START, bad_xform_problem):
                self.log_already_fixed(log_file, bad_xform_id, domain)
                return

        duplicate_xform = XFormInstance.get(duplicate_xform_id)
        now = datetime.now().isoformat()

        # Convert the XFormInstance to an XFormDuplicate
        bad_xform.doc_type = XFormDuplicate.__name__
        bad_xform.problem = BAD_FORM_PROBLEM_TEMPLATE.format(duplicate_xform_id, now)
        bad_xform = XFormDuplicate.wrap(bad_xform.to_json())

        # Convert the XFormDuplicate to an XFormInstance
        duplicate_xform.problem = FIXED_FORM_PROBLEM_TEMPLATE.format(
            id_=bad_xform_id, datetime_=now
        )
        duplicate_xform.doc_type = XFormInstance.__name__
        duplicate_xform = XFormInstance.wrap(duplicate_xform.to_json())

        self.log_swap(log_file, bad_xform_id, domain, duplicate_xform_id, dry_run)

        if not dry_run:
            duplicate_xform.save()
            bad_xform.save()
示例#4
0
 def deduplicate_xform(cls, xform):
     # follow standard dupe handling, which simply saves a copy of the form
     # but a new doc_id, and a doc_type of XFormDuplicate
     xform.doc_type = XFormDuplicate.__name__
     dupe = XFormDuplicate.wrap(xform.to_json())
     assert not xform.persistent_blobs, "some blobs would be lost"
     if xform._deferred_blobs:
         dupe._deferred_blobs = xform._deferred_blobs.copy()
     dupe.problem = "Form is a duplicate of another! (%s)" % xform._id
     return cls.assign_new_id(dupe)
示例#5
0
 def deduplicate_xform(cls, xform):
     # follow standard dupe handling, which simply saves a copy of the form
     # but a new doc_id, and a doc_type of XFormDuplicate
     xform.doc_type = XFormDuplicate.__name__
     dupe = XFormDuplicate.wrap(xform.to_json())
     assert not xform.persistent_blobs, "some blobs would be lost"
     if xform._deferred_blobs:
         dupe._deferred_blobs = xform._deferred_blobs.copy()
     dupe.problem = "Form is a duplicate of another! (%s)" % xform._id
     return cls.assign_new_id(dupe)
示例#6
0
def _handle_id_conflict(instance, attachments):
    """
    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.
    """
    def _extract_id_from_raw_xml(xml):
        
        # this is the standard openrosa way of doing things
        parsed = etree.XML(xml)
        meta_ns = "http://openrosa.org/jr/xforms"
        val = parsed.find("{%(ns)s}meta/{%(ns)s}instanceID" % \
                          {"ns": meta_ns})
        if val is not None and val.text:
            return val.text
        
        # if we get here search more creatively for some of the older
        # formats
        _PATTERNS = (r"<instanceID>([\w-]+)</instanceID>",
                     r"<uid>([\w-]+)</uid>",
                     r"<uuid>([\w-]+)</uuid>")
        for pattern in _PATTERNS:
            if re.search(pattern, xml): 
                return re.search(pattern, xml).groups()[0]
        
        logging.error("Unable to find conflicting matched uid in form: %s" % xml)
        return ""
    
    conflict_id = _extract_id_from_raw_xml(instance)
    
    # get old document
    existing_doc = XFormInstance.get(conflict_id)

    # compare md5s
    existing_md5 = existing_doc.xml_md5()
    new_md5 = hashlib.md5(instance).hexdigest()

    # if not same:
    # Deprecate old form (including changing ID)
    # to deprecate, copy new instance into a XFormDeprecated
    if existing_md5 != new_md5:
        doc_copy = XFormInstance.get_db().copy_doc(conflict_id)
        # get the doc back to avoid any potential bigcouch race conditions.
        # r=3 implied by class
        xfd = XFormDeprecated.get(doc_copy['id'])
        xfd.orig_id = conflict_id
        xfd.doc_type=XFormDeprecated.__name__
        xfd.save()

        # after that delete the original document and resubmit.
        XFormInstance.get_db().delete_doc(conflict_id)
        return post_xform_to_couch(instance, attachments=attachments)
    else:
        # follow standard dupe handling
        new_doc_id = uid.new()
        response, errors = post_from_settings(instance, {"uid": new_doc_id})
        if not _has_errors(response, errors):
            # create duplicate doc
            # get and save the duplicate to ensure the doc types are set correctly
            # so that it doesn't show up in our reports
            dupe = XFormDuplicate.get(response)
            dupe.problem = "Form is a duplicate of another! (%s)" % conflict_id
            dupe.save()
            return dupe
        else:
            # how badly do we care about this?
            raise CouchFormException("Problem POSTing form to couch! errors/response: %s/%s" % (errors, response))
示例#7
0
                xfd.doc_type = XFormDeprecated.__name__
                xfd.save()

                # after that delete the original document and resubmit.
                XFormInstance.get_db().delete_doc(conflict_id)
                return post_xform_to_couch(instance, attachments=attachments)
            else:
                # follow standard dupe handling
                new_doc_id = uid.new()
                response, errors = post_from_settings(instance,
                                                      {"uid": new_doc_id})
                if not _has_errors(response, errors):
                    # create duplicate doc
                    # get and save the duplicate to ensure the doc types are set correctly
                    # so that it doesn't show up in our reports
                    dupe = XFormDuplicate.get(response)
                    dupe.problem = "Form is a duplicate of another! (%s)" % conflict_id
                    dupe.save()
                    return dupe
                else:
                    # how badly do we care about this?
                    raise CouchFormException(
                        "Problem POSTing form to couch! errors/response: %s/%s"
                        % (errors, response))

        else:
            raise


def value_for_display(value, replacement_chars="_-"):
    """
示例#8
0
                xfd.orig_id = conflict_id
                xfd.doc_type=XFormDeprecated.__name__
                xfd.save()

                # after that delete the original document and resubmit.
                XFormInstance.get_db().delete_doc(conflict_id)
                return post_xform_to_couch(instance, attachments=attachments)
            else:
                # follow standard dupe handling
                new_doc_id = uid.new()
                response, errors = post_from_settings(instance, {"uid": new_doc_id})
                if not _has_errors(response, errors):
                    # create duplicate doc
                    # get and save the duplicate to ensure the doc types are set correctly
                    # so that it doesn't show up in our reports
                    dupe = XFormDuplicate.get(response)
                    dupe.problem = "Form is a duplicate of another! (%s)" % conflict_id
                    dupe.save()
                    return dupe
                else:
                    # how badly do we care about this?
                    raise CouchFormException("Problem POSTing form to couch! errors/response: %s/%s" % (errors, response))
            
        else:
            raise

def value_for_display(value, replacement_chars="_-"):
    """
    Formats an xform value for display, replacing the contents of the 
    system characters with spaces
    """