Esempio n. 1
0
 def to_xml(self, version):
     from xml.etree import ElementTree
     if self.closed:
         elem = get_case_element(self, ('close'), version)
     else:
         elem = get_case_element(self, ('create', 'update'), version)
     return ElementTree.tostring(elem)
Esempio n. 2
0
 def to_xml(self, version):
     from xml.etree import ElementTree
     if self.closed:
         elem = get_case_element(self, ('close'), version)
     else:
         elem = get_case_element(self, ('create', 'update'), version)
     return ElementTree.tostring(elem)
Esempio n. 3
0
 def to_xml(self, version, include_case_on_closed=False):
     from xml.etree import ElementTree
     from casexml.apps.phone.xml import get_case_element
     if self.closed:
         if include_case_on_closed:
             elem = get_case_element(self, ('create', 'update', 'close'), version)
         else:
             elem = get_case_element(self, ('close'), version)
     else:
         elem = get_case_element(self, ('create', 'update'), version)
     return ElementTree.tostring(elem)
Esempio n. 4
0
 def to_xml(self, version, include_case_on_closed=False):
     from xml.etree import ElementTree
     from casexml.apps.phone.xml import get_case_element
     if self.closed:
         if include_case_on_closed:
             elem = get_case_element(self, ('create', 'update', 'close'), version)
         else:
             elem = get_case_element(self, ('close'), version)
     else:
         elem = get_case_element(self, ('create', 'update'), version)
     return ElementTree.tostring(elem)
Esempio n. 5
0
def create_real_cases_from_dummy_cases(cases):
    """
    Takes as input a list of unsaved CommCareCase objects

    that don't have any case actions, etc.
    and creates them through the official channel of submitting forms, etc.

    returns a tuple of two lists: forms posted and cases created

    """
    posted_cases = []
    posted_forms = []
    case_blocks_by_domain = defaultdict(list)
    for case in cases:
        if not case.modified_on:
            case.modified_on = datetime.datetime.utcnow()
        if not case._id:
            case._id = uuid.uuid4().hex
        case_blocks_by_domain[case.domain].append(get_case_element(
            case, (CASE_ACTION_CREATE, CASE_ACTION_UPDATE), version='2.0'))
    for domain, case_blocks in case_blocks_by_domain.items():
        form, cases = post_case_blocks(case_blocks, domain=domain)
        posted_forms.append(form)
        posted_cases.extend(cases)
    return posted_forms, posted_cases
Esempio n. 6
0
    def _get_case_payload_batched(self, response, user, last_sync, synclog):
        synclog.save(**get_safe_write_kwargs())

        sync_operation = BatchedCaseSyncOperation(user, last_sync)
        for batch in sync_operation.batches():
            logger.debug(batch)

            # case blocks
            case_xml_elements = (
                xml.get_case_element(op.case, op.required_updates, self.version)
                for op in batch.case_updates_to_sync
            )
            for case_elem in case_xml_elements:
                response.append(case_elem)

        sync_state = sync_operation.global_state
        synclog.cases_on_phone = sync_state.actual_owned_cases
        synclog.dependent_cases_on_phone = sync_state.actual_extended_cases
        synclog.save(**get_safe_write_kwargs())

        # commtrack balance sections
        commtrack_elements = self.get_stock_payload(sync_state.all_synced_cases)
        for ct_elem in commtrack_elements:
            response.append(ct_elem)

        return response
Esempio n. 7
0
    def _get_case_payload(self, response, user, last_sync, synclog):
        sync_operation = user.get_case_updates(last_sync)
        synclog.cases_on_phone = [
            CaseState.from_case(c) for c in sync_operation.actual_owned_cases
        ]
        synclog.dependent_cases_on_phone = [
            CaseState.from_case(c) for c in sync_operation.actual_extended_cases
        ]
        synclog.save(**get_safe_write_kwargs())

        # case blocks
        case_xml_elements = (
            xml.get_case_element(op.case, op.required_updates, self.version)
            for op in sync_operation.actual_cases_to_sync
        )
        for case_elem in case_xml_elements:
            response.append(case_elem)

        # commtrack balance sections
        case_state_list = [CaseState.from_case(op.case) for op in sync_operation.actual_cases_to_sync]
        commtrack_elements = self.get_stock_payload(case_state_list)
        for ct_elem in commtrack_elements:
            response.append(ct_elem)

        return response
Esempio n. 8
0
    def get_payload(self):
        user = self.user
        last_sync = self.sync_log

        self.validate()

        cached_payload = self.get_cached_payload()
        if cached_payload:
            return cached_payload

        sync_operation = user.get_case_updates(last_sync)
        case_xml_elements = [
            xml.get_case_element(op.case, op.required_updates, self.version)
            for op in sync_operation.actual_cases_to_sync
        ]
        commtrack_elements = self.get_stock_payload(sync_operation)

        last_seq = str(get_db().info()["update_seq"])

        # create a sync log for this
        previous_log_id = last_sync.get_id if last_sync else None

        synclog = SyncLog(
            user_id=user.user_id,
            last_seq=last_seq,
            owner_ids_on_phone=user.get_owner_ids(),
            date=datetime.utcnow(),
            previous_log_id=previous_log_id,
            cases_on_phone=[CaseState.from_case(c) for c in sync_operation.actual_owned_cases],
            dependent_cases_on_phone=[CaseState.from_case(c) for c in sync_operation.actual_extended_cases],
        )
        synclog.save(**get_safe_write_kwargs())

        # start with standard response
        response = get_response_element(
            "Successfully restored account %s!" % user.username, ResponseNature.OTA_RESTORE_SUCCESS
        )

        # add sync token info
        response.append(xml.get_sync_element(synclog.get_id))
        # registration block
        response.append(xml.get_registration_element(user))
        # fixture block
        for fixture in generator.get_fixtures(user, self.version, last_sync):
            response.append(fixture)
        # case blocks
        for case_elem in case_xml_elements:
            response.append(case_elem)
        for ct_elem in commtrack_elements:
            response.append(ct_elem)

        if self.items:
            response.attrib["items"] = "%d" % len(response.getchildren())

        resp = xml.tostring(response)
        self.set_cached_payload_if_enabled(resp)
        return resp
Esempio n. 9
0
def append_update_to_response(response, update, restore_state):
    """
    Adds the XML from the case_update to the restore response.
    If factor is > 1 it will append that many updates to the response for load testing purposes.
    """
    current_count = 0
    original_update = update
    while current_count < restore_state.loadtest_factor:
        element = get_case_element(update.case, update.required_updates, restore_state.version)
        response.append(element)
        current_count += 1
        if current_count < restore_state.loadtest_factor:
            update = transform_loadtest_update(original_update, current_count)
Esempio n. 10
0
def get_xml_for_response(update, restore_state):
    """
    Adds the XML from the case_update to the restore response.
    If factor is > 1 it will append that many updates to the response for load testing purposes.
    """
    current_count = 0
    original_update = update
    elements = []
    while current_count < restore_state.loadtest_factor:
        element = get_case_element(update.case, update.required_updates, restore_state.version)
        elements.append(tostring(element))
        current_count += 1
        if current_count < restore_state.loadtest_factor:
            update = transform_loadtest_update(original_update, current_count)
        # only add user case on the first iteration
        if original_update.case.type == USERCASE_TYPE:
            break
    return elements
Esempio n. 11
0
def get_case_payload_batched(domain, stock_settings, version, user, last_synclog, new_synclog):
    response = get_restore_class(user)()

    sync_operation = BatchedCaseSyncOperation(user, last_synclog)
    for update in sync_operation.get_all_case_updates():
        element = xml.get_case_element(update.case, update.required_updates, version)
        response.append(element)

    sync_state = sync_operation.global_state
    new_synclog.cases_on_phone = sync_state.actual_owned_cases
    new_synclog.dependent_cases_on_phone = sync_state.actual_extended_cases
    new_synclog.save(**get_safe_write_kwargs())

    # commtrack balance sections
    commtrack_elements = get_stock_payload(domain, stock_settings, sync_state.all_synced_cases)
    response.extend(commtrack_elements)

    return response, sync_operation.batch_count
Esempio n. 12
0
def migration_restore(request, domain, case_id):
    """Restore endpoint used in bulk case migrations

    Accepts the provided case_id and returns a restore for the user containing:
    * Registration block
    * The passed in case and its full network of cases
    """
    try:
        case = CaseAccessors(domain).get_case(case_id)
        if case.domain != domain or case.is_deleted:
            raise Http404
    except CaseNotFound:
        raise Http404

    with RestoreContent('Case[{}]'.format(case_id)) as content:
        content.append(get_registration_element_for_case(case))
        for case in get_case_hierarchy_for_restore(case):
            # Formplayer will be creating these cases for the first time, so
            # include create blocks
            content.append(get_case_element(case, ('create', 'update'), V2))
        payload = content.get_fileobj()

    return RestoreResponse(payload).get_http_response()
Esempio n. 13
0
def generate_restore_payload(user, restore_id="", version="1.0", state_hash=""):
    """
    Gets an XML payload suitable for OTA restore. If you need to do something
    other than find all cases matching user_id = user.user_id then you have
    to pass in a user object that overrides the get_case_updates() method.
    
    It should match the same signature as models.user.get_case_updates():
    
        user:          who the payload is for. must implement get_case_updates
        restore_id:    sync token
        version:       the CommCare version 
        
        returns: the xml payload of the sync operation
    """
    check_version(version)
    
    last_sync = None
    if restore_id:
        try:
            last_sync = SyncLog.get(restore_id)
        except Exception:
            logging.error("Request for bad sync log %s by %s, ignoring..." % (restore_id, user))
    
    if last_sync and state_hash:
        parsed_hash = CaseStateHash.parse(state_hash)
        if last_sync.get_state_hash() != parsed_hash:
            raise BadStateException(expected=last_sync.get_state_hash(), 
                                    actual=parsed_hash,
                                    case_ids=last_sync.get_footprint_of_cases_on_phone())
        
    sync_operation = user.get_case_updates(last_sync)
    case_xml_elements = [xml.get_case_element(op.case, op.required_updates, version) \
                         for op in sync_operation.actual_cases_to_sync]
    
    
    last_seq = get_db().info()["update_seq"]
    
    # create a sync log for this
    previous_log_id = last_sync.get_id if last_sync else None
    
    synclog = SyncLog(user_id=user.user_id, last_seq=last_seq,
                      owner_ids_on_phone=user.get_owner_ids(),
                      date=datetime.utcnow(), previous_log_id=previous_log_id,
                      cases_on_phone=[CaseState.from_case(c) for c in \
                                      sync_operation.actual_owned_cases],
                      dependent_cases_on_phone=[CaseState.from_case(c) for c in \
                                                sync_operation.actual_extended_cases])
    synclog.save()
    
    # start with standard response
    response = get_response_element(
        "Successfully restored account %s!" % user.username, 
        ResponseNature.OTA_RESTORE_SUCCESS)
    
    # add sync token info
    response.append(xml.get_sync_element(synclog.get_id))
    # registration block
    response.append(xml.get_registration_element(user))
    # fixture block
    for fixture in generator.get_fixtures(user, version, last_sync):
        response.append(fixture)
    # case blocks
    for case_elem in case_xml_elements:
        response.append(case_elem)
    
    return xml.tostring(response)