def check_user_has_case(testcase, user, case_block, should_have=True, line_by_line=True, restore_id="", version=V1): XMLNS = NS_VERSION_MAP.get(version, 'http://openrosa.org/http/response') case_block.set('xmlns', XMLNS) case_block = ElementTree.fromstring(ElementTree.tostring(case_block)) payload_string = generate_restore_payload(user, restore_id, version=version) payload = ElementTree.fromstring(payload_string) blocks = payload.findall('{{{0}}}case'.format(XMLNS)) def get_case_id(block): if version == V1: return block.findtext('{{{0}}}case_id'.format(XMLNS)) else: return block.get('case_id') case_id = get_case_id(case_block) n = 0 def extra_info(): return "\n%s\n%s" % (ElementTree.tostring(case_block), map(ElementTree.tostring, blocks)) match = None for block in blocks: if get_case_id(block) == case_id: if should_have: if line_by_line: check_xml_line_by_line(testcase, ElementTree.tostring(case_block), ElementTree.tostring(block)) match = block n += 1 if n == 2: testcase.fail("Block for case_id '%s' appears twice in ota restore for user '%s':%s" % (case_id, user.username, extra_info())) else: testcase.fail("User '%s' gets case '%s' but shouldn't:%s" % (user.username, case_id, extra_info())) if not n and should_have: testcase.fail("Block for case_id '%s' doesn't appear in ota restore for user '%s':%s" \ % (case_id, user.username, extra_info())) return match
def check_user_has_case(testcase, user, case_blocks, should_have=True, line_by_line=True, restore_id="", version=V2, purge_restore_cache=False, return_single=False): if not isinstance(case_blocks, list): case_blocks = [case_blocks] return_single = True XMLNS = NS_VERSION_MAP.get(version, 'http://openrosa.org/http/response') if restore_id and purge_restore_cache: SyncLog.get(restore_id).invalidate_cached_payloads() restore_config = RestoreConfig( project=user.project, restore_user=user, params=RestoreParams(restore_id, version=version) ) payload_string = restore_config.get_payload().as_string() blocks_from_restore = extract_caseblocks_from_xml(payload_string, version) def check_block(case_block): case_block.set('xmlns', XMLNS) case_block = RestoreCaseBlock(ElementTree.fromstring(ElementTree.tostring(case_block)), version=version) case_id = case_block.get_case_id() n = 0 def extra_info(): return "\n%s\n%s" % (case_block.to_string(), map(lambda b: b.to_string(), blocks_from_restore)) match = None for block in blocks_from_restore: if block.get_case_id() == case_id: if should_have: if line_by_line: check_xml_line_by_line( testcase, case_block.to_string(), block.to_string(), ) match = block n += 1 if n == 2: testcase.fail( "Block for case_id '%s' appears twice" " in ota restore for user '%s':%s" % (case_id, user.username, extra_info()) ) else: testcase.fail( "User '%s' gets case '%s' " "but shouldn't:%s" % (user.username, case_id, extra_info()) ) if not n and should_have: testcase.fail("Block for case_id '%s' doesn't appear in ota restore for user '%s':%s" % (case_id, user.username, extra_info())) return match matches = [check_block(case_block) for case_block in case_blocks] return restore_config, matches[0] if return_single else matches
def _check_payload_has_cases(testcase, payload_string, username, case_blocks, should_have=True, line_by_line=True, version=V2, return_single=False, restore_config=None): """DEPRECATED use <MockDevice>.sync().cases""" if not isinstance(case_blocks, list): case_blocks = [case_blocks] return_single = True XMLNS = NS_VERSION_MAP.get(version, 'http://openrosa.org/http/response') blocks_from_restore = extract_caseblocks_from_xml(payload_string, version) def check_block(case_block): case_block.set('xmlns', XMLNS) case_block = _RestoreCaseBlock(ElementTree.fromstring( ElementTree.tostring(case_block)), version=version) case_id = case_block.get_case_id() n = 0 def extra_info(): return "\n%s\n%s" % (case_block.to_string(), [b.to_string() for b in blocks_from_restore]) match = None for block in blocks_from_restore: if block.get_case_id() == case_id: if should_have: if line_by_line: check_xml_line_by_line( testcase, case_block.to_string(), block.to_string(), ) match = block n += 1 if n == 2: testcase.fail("Block for case_id '%s' appears twice" " in ota restore for user '%s':%s" % (case_id, username, extra_info())) else: testcase.fail("User '%s' gets case '%s' " "but shouldn't:%s" % (username, case_id, extra_info())) if not n and should_have: testcase.fail( "Block for case_id '%s' doesn't appear in ota restore for user '%s':%s" % (case_id, username, extra_info())) return match matches = [check_block(case_block) for case_block in case_blocks] return restore_config, matches[0] if return_single else matches
def check_user_has_case(testcase, user, case_block, should_have=True, line_by_line=True, restore_id="", version=V1, caching_enabled=False): XMLNS = NS_VERSION_MAP.get(version, 'http://openrosa.org/http/response') case_block.set('xmlns', XMLNS) case_block = ElementTree.fromstring(ElementTree.tostring(case_block)) payload_string = RestoreConfig( user, restore_id, version=version, caching_enabled=caching_enabled).get_payload() payload = ElementTree.fromstring(payload_string) blocks = payload.findall('{{{0}}}case'.format(XMLNS)) def get_case_id(block): if version == V1: return block.findtext('{{{0}}}case_id'.format(XMLNS)) else: return block.get('case_id') case_id = get_case_id(case_block) n = 0 def extra_info(): return "\n%s\n%s" % (ElementTree.tostring(case_block), map(ElementTree.tostring, blocks)) match = None for block in blocks: if get_case_id(block) == case_id: if should_have: if line_by_line: check_xml_line_by_line(testcase, ElementTree.tostring(case_block), ElementTree.tostring(block)) match = block n += 1 if n == 2: testcase.fail( "Block for case_id '%s' appears twice in ota restore for user '%s':%s" % (case_id, user.username, extra_info())) else: testcase.fail("User '%s' gets case '%s' but shouldn't:%s" % (user.username, case_id, extra_info())) if not n and should_have: testcase.fail("Block for case_id '%s' doesn't appear in ota restore for user '%s':%s" \ % (case_id, user.username, extra_info())) return match
def _check_payload_has_cases(testcase, payload_string, username, case_blocks, should_have=True, line_by_line=True, version=V2, return_single=False, restore_config=None): """DEPRECATED use <MockDevice>.sync().cases""" if not isinstance(case_blocks, list): case_blocks = [case_blocks] return_single = True XMLNS = NS_VERSION_MAP.get(version, 'http://openrosa.org/http/response') blocks_from_restore = extract_caseblocks_from_xml(payload_string, version) def check_block(case_block): case_block.set('xmlns', XMLNS) case_block = _RestoreCaseBlock(ElementTree.fromstring(ElementTree.tostring(case_block)), version=version) case_id = case_block.get_case_id() n = 0 def extra_info(): return "\n%s\n%s" % (case_block.to_string(), [b.to_string() for b in blocks_from_restore]) match = None for block in blocks_from_restore: if block.get_case_id() == case_id: if should_have: if line_by_line: check_xml_line_by_line( testcase, case_block.to_string(), block.to_string(), ) match = block n += 1 if n == 2: testcase.fail( "Block for case_id '%s' appears twice" " in ota restore for user '%s':%s" % (case_id, username, extra_info()) ) else: testcase.fail( "User '%s' gets case '%s' " "but shouldn't:%s" % (username, case_id, extra_info()) ) if not n and should_have: testcase.fail("Block for case_id '%s' doesn't appear in ota restore for user '%s':%s" % (case_id, username, extra_info())) return match matches = [check_block(case_block) for case_block in case_blocks] return restore_config, matches[0] if return_single else matches
def get_case_xmlns(version): return NS_VERSION_MAP.get(version, 'http://openrosa.org/http/response')
def __init__(self, case_id, date_modified=None, user_id=undefined, owner_id=undefined, external_id=undefined, case_type=undefined, case_name=undefined, create=False, date_opened=undefined, update=None, close=False, # V2 only index=None, version=V1, compatibility_mode=False, ): """ From https://bitbucket.org/javarosa/javarosa/wiki/casexml <case> <case_id/> <-- Exactly One: The id of the abstract case to be modified (even in the case of creation) <date_modified/> <-- Exactly One: The date of this operation <create> <-- At Most One: Create action <case_type_id/> <-- Exactly One: The ID for the type of case represented <user_id/> <-- At Most One: The ID for a user who created the case <case_name/> <-- Exactly One: A semantically meaningless but human readable name associated with the case <external_id/> <-- Exactly One: The soft id associated with this record. Generally based on another system's id for this record. </create> <update/> <-- At Most One: Updates data for the case <case_type_id/> <-- At Most One: Modifies the Case Type for the case <case_name/> <-- At Most One: A semantically meaningless but human readable name associated with the case <date_opened/> <-- At Most One: Modifies the Date the case was opened <*/> <-- An Arbitrary Number: Creates or mutates a value identified by the key provided </update> <close/> <-- At Most One: Closes the case </case> https://github.com/dimagi/commcare/wiki/casexml20 <case xmlns="http://commcarehq.org/case/transaction/v2" case_id="" user_id="" date_modified="" > <!-- user_id - At Most One: the GUID of the user responsible for this transaction --> <!-- case_id - Exactly One: The id of the abstract case to be modified (even in the case of creation) --> <!-- date_modified - Exactly One: The date and time of this operation --> <create> <!-- At Most One: Create action --> <case_type/> <!-- Exactly One: The ID for the type of case represented --> <owner_id/> <!-- At Most One: The GUID of the current owner of this case --> <case_name/> <!-- Exactly One: A semantically meaningless but human readable name associated with the case --> </create> <update> <!-- At Most One: Updates data for the case --> <case_type/> <!-- At Most One: Modifies the Case Type for the case --> <case_name/> <!-- At Most One: A semantically meaningless but human readable name associated with the case --> <date_opened/> <!-- At Most One: Modifies the Date the case was opened --> <owner_id/> <!-- At Most One: Modifies the owner of this case --> <*/> <-- An Arbitrary Number: Creates or mutates a value identified by the key provided --> </update> <index/> <!-- At Most One: Contains a set of referenced GUID's to other cases --> <close/> <!-- At Most One: Closes the case --> </case> """ super(CaseBlock, self).__init__() self._id = case_id date_modified = date_modified or datetime.utcnow() update = copy.copy(update) if update else {} index = copy.copy(index) if index else {} self.XMLNS = NS_VERSION_MAP.get(version) if version == V1: self.VERSION = V1 self.CASE_TYPE = "case_type_id" elif version == V2: self.VERSION = V2 self.CASE_TYPE = "case_type" else: raise CaseBlockError("Case XML version must be %s or %s" % (V1, V2)) if create: self['create'] = {} # make case_type case_type = "" if case_type is CaseBlock.undefined else case_type case_name = "" if case_name is CaseBlock.undefined else case_name if version == V2: owner_id = "" if owner_id is CaseBlock.undefined else owner_id self['update'] = update self['update'].update({ 'date_opened': date_opened }) create_or_update = { self.CASE_TYPE: case_type, 'case_name': case_name, } # what to do with case_id, date_modified, user_id, and owner_id, external_id if version == V1: self.update({ 'case_id': case_id, # V1 'date_modified': date_modified, # V1 }) if create: self['create'].update({ 'user_id': user_id, # V1 }) else: if not compatibility_mode and user_id is not CaseBlock.undefined: CaseBlockError("CaseXML V1: You only set user_id when creating a case") self['update'].update({ 'owner_id': owner_id, # V1 }) create_or_update.update({ 'external_id': external_id # V1 }) else: self.update({ '_attrib': { 'case_id': case_id, # V2 'date_modified': date_modified, # V2 'user_id': user_id, # V2 'xmlns': self.XMLNS, } }) create_or_update.update({ 'owner_id': owner_id, # V2 }) self['update'].update({ 'external_id': external_id, # V2 }) # fail if user specifies both, say, case_name='Johnny' and update={'case_name': 'Johnny'} for key in create_or_update: if create_or_update[key] is not CaseBlock.undefined and self['update'].has_key(key): raise CaseBlockError("Key %r specified twice" % key) if create: self['create'].update(create_or_update) else: self['update'].update(create_or_update) if close: self['close'] = {} if not ['' for val in self['update'].values() if val is not CaseBlock.undefined]: self['update'] = CaseBlock.undefined if index and version == V2: self['index'] = {} for name, (case_type, case_id) in index.items(): self['index'][name] = { '_attrib': { 'case_type': case_type }, '_text': case_id }
def __init__( self, case_id, date_modified=None, user_id=undefined, owner_id=undefined, external_id=undefined, case_type=undefined, case_name=undefined, create=False, date_opened=undefined, update=None, close=False, # referrals currently not supported # V2 only index=None, version=V1, compatibility_mode=False, ): """ From https://bitbucket.org/javarosa/javarosa/wiki/casexml <case> <case_id/> <-- Exactly One: The id of the abstract case to be modified (even in the case of creation) <date_modified/> <-- Exactly One: The date of this operation <create> <-- At Most One: Create action <case_type_id/> <-- Exactly One: The ID for the type of case represented <user_id/> <-- At Most One: The ID for a user who created the case <case_name/> <-- Exactly One: A semantically meaningless but human readable name associated with the case <external_id/> <-- Exactly One: The soft id associated with this record. Generally based on another system's id for this record. </create> <update/> <-- At Most One: Updates data for the case <case_type_id/> <-- At Most One: Modifies the Case Type for the case <case_name/> <-- At Most One: A semantically meaningless but human readable name associated with the case <date_opened/> <-- At Most One: Modifies the Date the case was opened <*/> <-- An Arbitrary Number: Creates or mutates a value identified by the key provided </update> <close/> <-- At Most One: Closes the case # <referral> <-- At Most One: Referral actions # <referral_id/> <-- Exactly One: The unique ID. No two referrals should be open with both the same referral_id and referral_type # <followup_date/> <-- At Most One: The due date for all followups referenced in this action # <open> # <referral_types/> <-- Exactly One: A space separated list of referral types which should be opened. # </open> # <update> # <referral_type/> <-- Exactly One: The referral type to be changed # <date_closed/> <-- At Most One: The date the referral was closed. If this element exists, the abstract referral matching the referral_id and referral_type should be closed. # </update> # </referral> </case> https://bitbucket.org/commcare/commcare/wiki/casexml20 <case xmlns="http://commcarehq.org/case/transaction/v2" case_id="" user_id="" date_modified="" > <!-- user_id - At Most One: the GUID of the user responsible for this transaction --> <!-- case_id - Exactly One: The id of the abstract case to be modified (even in the case of creation) --> <!-- date_modified - Exactly One: The date and time of this operation --> <create> <!-- At Most One: Create action --> <case_type/> <!-- Exactly One: The ID for the type of case represented --> <owner_id/> <!-- At Most One: The GUID of the current owner of this case --> <case_name/> <!-- Exactly One: A semantically meaningless but human readable name associated with the case --> </create> <update> <!-- At Most One: Updates data for the case --> <case_type/> <!-- At Most One: Modifies the Case Type for the case --> <case_name/> <!-- At Most One: A semantically meaningless but human readable name associated with the case --> <date_opened/> <!-- At Most One: Modifies the Date the case was opened --> <owner_id/> <!-- At Most One: Modifies the owner of this case --> <*/> <-- An Arbitrary Number: Creates or mutates a value identified by the key provided --> </update> <index/> <!-- At Most One: Contains a set of referenced GUID's to other cases --> <close/> <!-- At Most One: Closes the case --> </case> """ super(CaseBlock, self).__init__() self._id = case_id date_modified = date_modified or datetime.utcnow() update = copy.copy(update) if update else {} index = copy.copy(index) if index else {} self.XMLNS = NS_VERSION_MAP.get(version) if version == V1: self.VERSION = V1 self.CASE_TYPE = "case_type_id" elif version == V2: self.VERSION = V2 self.CASE_TYPE = "case_type" else: raise CaseBlockError("Case XML version must be %s or %s" % (V1, V2)) if create: self['create'] = {} # make case_type case_type = "" if case_type is CaseBlock.undefined else case_type case_name = "" if case_name is CaseBlock.undefined else case_name if version == V2: owner_id = "" if owner_id is CaseBlock.undefined else owner_id self['update'] = update self['update'].update({'date_opened': date_opened}) create_or_update = { self.CASE_TYPE: case_type, 'case_name': case_name, } # what to do with case_id, date_modified, user_id, and owner_id, external_id if version == V1: self.update({ 'case_id': case_id, # V1 'date_modified': date_modified, # V1 }) if create: self['create'].update({ 'user_id': user_id, # V1 }) else: if not compatibility_mode and user_id is not CaseBlock.undefined: CaseBlockError( "CaseXML V1: You only set user_id when creating a case" ) self['update'].update({ 'owner_id': owner_id, # V1 }) create_or_update.update({ 'external_id': external_id # V1 }) else: self.update({ '_attrib': { 'case_id': case_id, # V2 'date_modified': date_modified, # V2 'user_id': user_id, # V2 'xmlns': self.XMLNS, } }) create_or_update.update({ 'owner_id': owner_id, # V2 }) self['update'].update({ 'external_id': external_id, # V2 }) # fail if user specifies both, say, case_name='Johnny' and update={'case_name': 'Johnny'} for key in create_or_update: if create_or_update[key] is not CaseBlock.undefined and self[ 'update'].has_key(key): raise CaseBlockError("Key %r specified twice" % key) if create: self['create'].update(create_or_update) else: self['update'].update(create_or_update) if close: self['close'] = {} if not [ '' for val in self['update'].values() if val is not CaseBlock.undefined ]: self['update'] = CaseBlock.undefined if index and version == V2: self['index'] = {} for name, (case_type, case_id) in index.items(): self['index'][name] = { '_attrib': { 'case_type': case_type }, '_text': case_id }
def check_user_has_case(testcase, user, case_blocks, should_have=True, line_by_line=True, restore_id="", version=V1, purge_restore_cache=False, return_single=False): if not isinstance(case_blocks, list): case_blocks = [case_blocks] return_single = True XMLNS = NS_VERSION_MAP.get(version, 'http://openrosa.org/http/response') if restore_id and purge_restore_cache: SyncLog.get(restore_id).invalidate_cached_payloads() restore_config = RestoreConfig(user, restore_id, version=version) payload_string = restore_config.get_payload().as_string() payload = ElementTree.fromstring(payload_string) blocks = payload.findall('{{{0}}}case'.format(XMLNS)) def get_case_id(block): if version == V1: return block.findtext('{{{0}}}case_id'.format(XMLNS)) else: return block.get('case_id') def check_block(case_block): case_block.set('xmlns', XMLNS) case_block = ElementTree.fromstring(ElementTree.tostring(case_block)) case_id = get_case_id(case_block) n = 0 def extra_info(): return "\n%s\n%s" % (ElementTree.tostring(case_block), map(ElementTree.tostring, blocks)) match = None for block in blocks: if get_case_id(block) == case_id: if should_have: if line_by_line: check_xml_line_by_line( testcase, ElementTree.tostring(case_block), ElementTree.tostring(block) ) match = block n += 1 if n == 2: testcase.fail( "Block for case_id '%s' appears twice" " in ota restore for user '%s':%s" % (case_id, user.username, extra_info()) ) else: testcase.fail( "User '%s' gets case '%s' " "but shouldn't:%s" % (user.username, case_id, extra_info()) ) if not n and should_have: testcase.fail("Block for case_id '%s' doesn't appear in ota restore for user '%s':%s" % (case_id, user.username, extra_info())) return match matches = [check_block(case_block) for case_block in case_blocks] return restore_config, matches[0] if return_single else matches
def __init__( self, case_id, date_modified=None, user_id=undefined, owner_id=undefined, external_id=undefined, case_type=undefined, case_name=undefined, create=False, date_opened=undefined, update=None, close=False, index=None, strict=True, ): """ https://github.com/dimagi/commcare/wiki/casexml20 <case xmlns="http://commcarehq.org/case/transaction/v2" case_id="" user_id="" date_modified="" > <!-- user_id - At Most One: the GUID of the user responsible for this transaction --> <!-- case_id - Exactly One: The id of the abstract case to be modified (even in the case of creation) --> <!-- date_modified - Exactly One: The date and time of this operation --> <create> <!-- At Most One: Create action --> <case_type/> <!-- Exactly One: The ID for the type of case represented --> <owner_id/> <!-- At Most One: The GUID of the current owner of this case --> <case_name/> <!-- Exactly One: A semantically meaningless but human readable name associated with the case --> </create> <update> <!-- At Most One: Updates data for the case --> <case_type/> <!-- At Most One: Modifies the Case Type for the case --> <case_name/> <!-- At Most One: A semantically meaningless but human readable name associated with the case --> <date_opened/> <!-- At Most One: Modifies the Date the case was opened --> <owner_id/> <!-- At Most One: Modifies the owner of this case --> <*/> <-- An Arbitrary Number: Creates or mutates a value identified by the key provided --> </update> <index/> <!-- At Most One: Contains a set of referenced GUID's to other cases --> <close/> <!-- At Most One: Closes the case --> </case> """ super(CaseBlock, self).__init__() self._id = case_id now = datetime.utcnow() date_modified = date_modified or now if date_opened == CaseBlock.undefined and create: date_opened = now.date() update = copy.copy(update) if update else {} index = copy.copy(index) if index else {} self.XMLNS = NS_VERSION_MAP.get(V2) self.VERSION = V2 self.CASE_TYPE = "case_type" if create: self['create'] = {} # make case_type case_type = "" if case_type is CaseBlock.undefined else case_type case_name = "" if case_name is CaseBlock.undefined else case_name owner_id = "" if owner_id is CaseBlock.undefined else owner_id self['update'] = update create_or_update = { self.CASE_TYPE: case_type, 'case_name': case_name, } self.update({ '_attrib': { 'case_id': case_id, 'date_modified': date_modified, 'user_id': user_id, 'xmlns': self.XMLNS, } }) if owner_id is not None: create_or_update.update({ 'owner_id': owner_id, }) self['update'].update({ 'external_id': external_id, 'date_opened': date_opened, }) # fail if user specifies both, say, case_name='Johnny' and update={'case_name': 'Johnny'} if strict: for key in create_or_update: if create_or_update[ key] is not CaseBlock.undefined and key in self[ 'update']: raise CaseBlockError("Key %r specified twice" % key) create_or_update = { key: val for key, val in create_or_update.items() if val is not CaseBlock.undefined } if create: self['create'].update(create_or_update) else: self['update'].update(create_or_update) if close: self['close'] = {} if not [ '' for val in self['update'].values() if val is not CaseBlock.undefined ]: self['update'] = CaseBlock.undefined if index: self['index'] = {} for name in index.keys(): case_type = index[name][0] case_id = index[name][1] # relationship = "child" for index to a parent case (default) # relationship = "extension" for index to a host case relationship = index[name][2] if len( index[name]) > 2 else 'child' if relationship not in ('child', 'extension'): raise CaseBlockError( 'Valid values for an index relationship are "child" and "extension"' ) _attrib = {'case_type': case_type} if relationship != 'child': _attrib['relationship'] = relationship self['index'][name] = {'_attrib': _attrib, '_text': case_id}
def __init__(self, case_id, date_modified=None, user_id=undefined, owner_id=undefined, external_id=undefined, case_type=undefined, case_name=undefined, create=False, date_opened=undefined, update=None, close=False, index=None, strict=True, ): """ https://github.com/dimagi/commcare/wiki/casexml20 <case xmlns="http://commcarehq.org/case/transaction/v2" case_id="" user_id="" date_modified="" > <!-- user_id - At Most One: the GUID of the user responsible for this transaction --> <!-- case_id - Exactly One: The id of the abstract case to be modified (even in the case of creation) --> <!-- date_modified - Exactly One: The date and time of this operation --> <create> <!-- At Most One: Create action --> <case_type/> <!-- Exactly One: The ID for the type of case represented --> <owner_id/> <!-- At Most One: The GUID of the current owner of this case --> <case_name/> <!-- Exactly One: A semantically meaningless but human readable name associated with the case --> </create> <update> <!-- At Most One: Updates data for the case --> <case_type/> <!-- At Most One: Modifies the Case Type for the case --> <case_name/> <!-- At Most One: A semantically meaningless but human readable name associated with the case --> <date_opened/> <!-- At Most One: Modifies the Date the case was opened --> <owner_id/> <!-- At Most One: Modifies the owner of this case --> <*/> <-- An Arbitrary Number: Creates or mutates a value identified by the key provided --> </update> <index/> <!-- At Most One: Contains a set of referenced GUID's to other cases --> <close/> <!-- At Most One: Closes the case --> </case> """ super(CaseBlock, self).__init__() self._id = case_id date_modified = date_modified or datetime.utcnow() update = copy.copy(update) if update else {} index = copy.copy(index) if index else {} self.XMLNS = NS_VERSION_MAP.get(V2) self.VERSION = V2 self.CASE_TYPE = "case_type" if create: self['create'] = {} # make case_type case_type = "" if case_type is CaseBlock.undefined else case_type case_name = "" if case_name is CaseBlock.undefined else case_name owner_id = "" if owner_id is CaseBlock.undefined else owner_id self['update'] = update self['update'].update({ 'date_opened': date_opened }) create_or_update = { self.CASE_TYPE: case_type, 'case_name': case_name, } self.update({ '_attrib': { 'case_id': case_id, 'date_modified': date_modified, 'user_id': user_id, 'xmlns': self.XMLNS, } }) if owner_id is not None: create_or_update.update({ 'owner_id': owner_id, }) self['update'].update({ 'external_id': external_id, }) # fail if user specifies both, say, case_name='Johnny' and update={'case_name': 'Johnny'} if strict: for key in create_or_update: if create_or_update[key] is not CaseBlock.undefined and key in self['update']: raise CaseBlockError("Key %r specified twice" % key) if create: self['create'].update(create_or_update) else: self['update'].update(create_or_update) if close: self['close'] = {} if not ['' for val in self['update'].values() if val is not CaseBlock.undefined]: self['update'] = CaseBlock.undefined if index: self['index'] = {} for name in index.keys(): case_type = index[name][0] case_id = index[name][1] # relationship = "child" for index to a parent case (default) # relationship = "extension" for index to a host case relationship = index[name][2] if len(index[name]) > 2 else 'child' if relationship not in ('child', 'extension'): raise CaseBlockError('Valid values for an index relationship are "child" and "extension"') _attrib = {'case_type': case_type} if relationship != 'child': _attrib['relationship'] = relationship self['index'][name] = { '_attrib': _attrib, '_text': case_id }