<s> """<STR_LIT>""" <EOL> import os <EOL> import datetime <EOL> from casexml . apps . case import const <EOL> from casexml . apps . case . models import CommCareCaseAction <EOL> from casexml . apps . case . xml import DEFAULT_VERSION , V1 , V2 , NS_REVERSE_LOOKUP_MAP <EOL> from dimagi . utils . parsing import string_to_utc_datetime <EOL> XMLNS_ATTR = "<STR_LIT>" <EOL> KNOWN_PROPERTIES = { <EOL> '<STR_LIT:name>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT:type>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : None , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } <EOL> def get_version ( case_block ) : <EOL> """<STR_LIT>""" <EOL> xmlns = case_block . get ( XMLNS_ATTR , "<STR_LIT>" ) <EOL> if xmlns : <EOL> if xmlns not in NS_REVERSE_LOOKUP_MAP : <EOL> raise CaseGenerationException ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" % xmlns <EOL> ) <EOL> return NS_REVERSE_LOOKUP_MAP [ xmlns ] <EOL> return DEFAULT_VERSION <EOL> class CaseGenerationException ( Exception ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def case_update_from_block ( case_block ) : <EOL> case_version = get_version ( case_block ) <EOL> return VERSION_FUNCTION_MAP [ case_version ] ( case_block ) <EOL> class CaseActionBase ( object ) : <EOL> action_type_slug = None <EOL> def __init__ ( self , block , type = None , name = None , external_id = None , <EOL> user_id = None , owner_id = None , opened_on = None , <EOL> dynamic_properties = None , indices = None , attachments = None ) : <EOL> self . raw_block = block <EOL> self . type = type <EOL> self . name = name <EOL> self . external_id = external_id <EOL> self . user_id = user_id <EOL> self . owner_id = owner_id <EOL> self . opened_on = opened_on <EOL> self . dynamic_properties = dynamic_properties or { } <EOL> self . indices = indices or [ ] <EOL> self . attachments = attachments or { } <EOL> def get_known_properties ( self ) : <EOL> return dict ( ( p , getattr ( self , p ) ) for p in KNOWN_PROPERTIES . keys ( ) <EOL> if getattr ( self , p ) is not None ) <EOL> @ classmethod <EOL> def _from_block_and_mapping ( cls , block , mapping ) : <EOL> def _normalize ( val ) : <EOL> if isinstance ( val , list ) : <EOL> return val [ - <NUM_LIT:1> ] <EOL> return val <EOL> kwargs = { } <EOL> dynamic_properties = { } <EOL> if isinstance ( block , dict ) : <EOL> for k , v in block . items ( ) : <EOL> if k in mapping : <EOL> kwargs [ mapping [ k ] ] = v <EOL> else : <EOL> dynamic_properties [ k ] = _normalize ( v ) <EOL> return cls ( block , dynamic_properties = dynamic_properties , <EOL> ** kwargs ) <EOL> @ classmethod <EOL> def from_v1 ( cls , block ) : <EOL> mapping = { const . CASE_TAG_TYPE_ID : "<STR_LIT:type>" , <EOL> const . CASE_TAG_NAME : "<STR_LIT:name>" , <EOL> const . CASE_TAG_EXTERNAL_ID : "<STR_LIT>" , <EOL> const . CASE_TAG_USER_ID : "<STR_LIT>" , <EOL> const . CASE_TAG_OWNER_ID : "<STR_LIT>" , <EOL> const . CASE_TAG_DATE_OPENED : "<STR_LIT>" } <EOL> return cls . _from_block_and_mapping ( block , mapping ) <EOL> @ classmethod <EOL> def from_v2 ( cls , block ) : <EOL> mapping = { const . CASE_TAG_TYPE : "<STR_LIT:type>" , <EOL> const . CASE_TAG_NAME : "<STR_LIT:name>" , <EOL> const . CASE_TAG_EXTERNAL_ID : "<STR_LIT>" , <EOL> const . CASE_TAG_USER_ID : "<STR_LIT>" , <EOL> const . CASE_TAG_OWNER_ID : "<STR_LIT>" , <EOL> const . CASE_TAG_DATE_OPENED : "<STR_LIT>" } <EOL> return cls . _from_block_and_mapping ( block , mapping ) <EOL> class CaseNoopAction ( CaseActionBase ) : <EOL> """<STR_LIT>""" <EOL> action_type_slug = const . CASE_ACTION_UPDATE <EOL> def get_known_properties ( self ) : <EOL> return { } <EOL> class CaseCreateAction ( CaseActionBase ) : <EOL> action_type_slug = const . CASE_ACTION_CREATE <EOL> class CaseUpdateAction ( CaseActionBase ) : <EOL> action_type_slug = const . CASE_ACTION_UPDATE <EOL> class CaseCloseAction ( CaseActionBase ) : <EOL> action_type_slug = const . CASE_ACTION_CLOSE <EOL> class AbstractAction ( object ) : <EOL> def __init__ ( self , action_type_slug ) : <EOL> self . action_type_slug = action_type_slug <EOL> self . dynamic_properties = { } <EOL> self . indices = [ ] <EOL> self . attachments = { } <EOL> def get_known_properties ( self ) : <EOL> return { } <EOL> class CaseAttachment ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , identifier , attachment_src , attachment_from , attachment_name ) : <EOL> """<STR_LIT>""" <EOL> self . identifier = identifier <EOL> self . attachment_src = attachment_src <EOL> self . attachment_from = attachment_from <EOL> self . attachment_name = attachment_name <EOL> class CaseAttachmentAction ( CaseActionBase ) : <EOL> action_type_slug = const . CASE_ACTION_ATTACHMENT <EOL> def __init__ ( self , block , attachments ) : <EOL> super ( CaseAttachmentAction , self ) . __init__ ( block , attachments = attachments ) <EOL> @ classmethod <EOL> def from_v1 ( cls , block ) : <EOL> return cls ( block , [ ] ) <EOL> @ classmethod <EOL> def from_v2 ( cls , block ) : <EOL> attachments = { } <EOL> for id , data in block . items ( ) : <EOL> if isinstance ( data , basestring ) : <EOL> attachment_from = None <EOL> attachment_src = None <EOL> attachment_name = None <EOL> else : <EOL> attachment_from = data . get ( '<STR_LIT>' , None ) <EOL> attachment_src = data . get ( '<STR_LIT>' , None ) <EOL> attachment_name = data . get ( '<STR_LIT>' , None ) <EOL> if attachment_from == attachment_src == attachment_name == None : <EOL> pass <EOL> attachments [ id ] = CaseAttachment ( id , attachment_src , attachment_from , attachment_name ) <EOL> return cls ( block , attachments ) <EOL> class CaseIndex ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , identifier , referenced_type , referenced_id , relationship = '<STR_LIT>' ) : <EOL> self . identifier = identifier <EOL> self . referenced_type = referenced_type <EOL> self . referenced_id = referenced_id <EOL> self . relationship = relationship <EOL> class CaseIndexAction ( CaseActionBase ) : <EOL> """<STR_LIT>""" <EOL> action_type_slug = const . CASE_ACTION_INDEX <EOL> def __init__ ( self , block , indices ) : <EOL> super ( CaseIndexAction , self ) . __init__ ( block , indices = indices ) <EOL> def get_known_properties ( self ) : <EOL> return { } <EOL> @ classmethod <EOL> def from_v1 ( cls , block ) : <EOL> return cls ( block , [ ] ) <EOL> @ classmethod <EOL> def from_v2 ( cls , block ) : <EOL> indices = [ ] <EOL> for id , data in block . items ( ) : <EOL> if "<STR_LIT>" not in data : <EOL> raise CaseGenerationException ( "<STR_LIT>" ) <EOL> indices . append ( CaseIndex ( id , data [ "<STR_LIT>" ] , data . get ( "<STR_LIT>" , "<STR_LIT>" ) , <EOL> data . get ( "<STR_LIT>" , '<STR_LIT>' ) ) ) <EOL> return cls ( block , indices ) <EOL> class CaseUpdate ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , id , version , block , user_id = "<STR_LIT>" , modified_on_str = "<STR_LIT>" ) : <EOL> self . id = id <EOL> self . version = version <EOL> self . user_id = user_id <EOL> self . modified_on_str = modified_on_str <EOL> self . raw_block = block <EOL> self . create_block = block . get ( const . CASE_ACTION_CREATE , { } ) <EOL> self . update_block = block . get ( const . CASE_ACTION_UPDATE , { } ) <EOL> self . close_block = block . get ( const . CASE_ACTION_CLOSE , { } ) <EOL> self . _closes_case = const . CASE_ACTION_CLOSE in block <EOL> self . index_block = block . get ( const . CASE_ACTION_INDEX , { } ) <EOL> self . attachment_block = block . get ( const . CASE_ACTION_ATTACHMENT , { } ) <EOL> self . referral_block = block . get ( const . REFERRAL_TAG , { } ) <EOL> self . actions = [ ] <EOL> if self . creates_case ( ) : <EOL> self . actions . append ( CREATE_ACTION_FUNCTION_MAP [ self . version ] ( self . create_block ) ) <EOL> if self . updates_case ( ) : <EOL> self . actions . append ( UPDATE_ACTION_FUNCTION_MAP [ self . version ] ( self . update_block ) ) <EOL> if self . closes_case ( ) : <EOL> self . actions . append ( CLOSE_ACTION_FUNCTION_MAP [ self . version ] ( self . close_block ) ) <EOL> if self . has_indices ( ) : <EOL> self . actions . append ( INDEX_ACTION_FUNCTION_MAP [ self . version ] ( self . index_block ) ) <EOL> if self . has_attachments ( ) : <EOL> self . actions . append ( ATTACHMENT_ACTION_FUNCTION_MAP [ self . version ] ( self . attachment_block ) ) <EOL> if not self . actions : <EOL> self . actions . append ( NOOP_ACTION_FUNCTION_MAP [ self . version ] ( { } ) ) <EOL> def guess_modified_on ( self ) : <EOL> """<STR_LIT>""" <EOL> return string_to_utc_datetime ( self . modified_on_str ) if self . modified_on_str else datetime . datetime . utcnow ( ) <EOL> def creates_case ( self ) : <EOL> return bool ( self . create_block ) <EOL> def updates_case ( self ) : <EOL> return bool ( self . update_block ) <EOL> def closes_case ( self ) : <EOL> return self . _closes_case <EOL> def has_indices ( self ) : <EOL> return bool ( self . index_block ) <EOL> def has_referrals ( self ) : <EOL> return bool ( self . referral_block ) <EOL> def has_attachments ( self ) : <EOL> return bool ( self . attachment_block ) <EOL> def get_case_actions ( self , xformdoc ) : <EOL> """<STR_LIT>""" <EOL> return [ <EOL> CommCareCaseAction . from_parsed_action ( <EOL> self . guess_modified_on ( ) , self . user_id , xformdoc , action <EOL> ) <EOL> for action in self . actions <EOL> ] <EOL> def __str__ ( self ) : <EOL> return "<STR_LIT>" % ( self . version , self . id ) <EOL> def _filtered_action ( self , func ) : <EOL> filtered = filter ( func , self . actions ) <EOL> if filtered : <EOL> assert ( len ( filtered ) == <NUM_LIT:1> ) <EOL> return filtered [ <NUM_LIT:0> ] <EOL> def get_create_action ( self ) : <EOL> return self . _filtered_action ( lambda a : isinstance ( a , CaseCreateAction ) ) <EOL> def get_update_action ( self ) : <EOL> return self . _filtered_action ( lambda a : isinstance ( a , CaseUpdateAction ) ) <EOL> def get_close_action ( self ) : <EOL> return self . _filtered_action ( lambda a : isinstance ( a , CaseCloseAction ) ) <EOL> def get_index_action ( self ) : <EOL> return self . _filtered_action ( lambda a : isinstance ( a , CaseIndexAction ) ) <EOL> def get_attachment_action ( self ) : <EOL> return self . _filtered_action ( lambda a : isinstance ( a , CaseAttachmentAction ) ) <EOL> @ classmethod <EOL> def from_v1 ( cls , case_block ) : <EOL> """<STR_LIT>""" <EOL> if const . CASE_TAG_ID not in case_block : <EOL> raise CaseGenerationException ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> ) <EOL> modified_on = case_block . get ( const . CASE_TAG_MODIFIED , "<STR_LIT>" ) <EOL> return cls ( id = case_block [ const . CASE_TAG_ID ] , <EOL> version = V1 , <EOL> block = case_block , <EOL> modified_on_str = modified_on ) <EOL> @ classmethod <EOL> def from_v2 ( cls , case_block ) : <EOL> """<STR_LIT>""" <EOL> def _to_attr ( val ) : <EOL> return "<STR_LIT>" % val <EOL> case_id_attr = _to_attr ( const . CASE_TAG_ID ) <EOL> if case_id_attr not in case_block : <EOL> raise CaseGenerationException ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> ) <EOL> user_id = case_block . get ( _to_attr ( const . CASE_TAG_USER_ID ) , "<STR_LIT>" ) <EOL> modified_on = case_block . get ( _to_attr ( const . CASE_TAG_MODIFIED ) , "<STR_LIT>" ) <EOL> return cls ( id = case_block [ case_id_attr ] , <EOL> version = V2 , <EOL> block = case_block , <EOL> user_id = user_id , <EOL> modified_on_str = modified_on ) <EOL> VERSION_FUNCTION_MAP = { <EOL> V1 : CaseUpdate . from_v1 , <EOL> V2 : CaseUpdate . from_v2 <EOL> } <EOL> NOOP_ACTION_FUNCTION_MAP = { <EOL> V1 : CaseNoopAction . from_v1 , <EOL> V2 : CaseNoopAction . from_v2 <EOL> } <EOL> CREATE_ACTION_FUNCTION_MAP = { <EOL> V1 : CaseCreateAction . from_v1 , <EOL> V2 : CaseCreateAction . from_v2 <EOL> } <EOL> UPDATE_ACTION_FUNCTION_MAP = { <EOL> V1 : CaseUpdateAction . from_v1 , <EOL> V2 : CaseUpdateAction . from_v2 , <EOL> } <EOL> CLOSE_ACTION_FUNCTION_MAP = { <EOL> V1 : CaseCloseAction . from_v1 , <EOL> V2 : CaseCloseAction . from_v2 , <EOL> } <EOL> INDEX_ACTION_FUNCTION_MAP = { <EOL> V1 : CaseIndexAction . from_v1 , <EOL> V2 : CaseIndexAction . from_v2 <EOL> } <EOL> ATTACHMENT_ACTION_FUNCTION_MAP = { <EOL> V1 : CaseAttachmentAction . from_v1 , <EOL> V2 : CaseAttachmentAction . from_v2 <EOL> } </s>
