@@ -71,45 +71,64 @@ def replace_token(text: str, person: Person) -> str:
7171
7272 pattern = r"\[\[.*?\]\]"
7373 all_tokens = re .findall (pattern , text , re .IGNORECASE )
74- present_attributes = [ attribute .get ("ATTRIBUTE_TYPE" ) for attribute in person .data ]
74+ present_attributes = { attribute .get ("ATTRIBUTE_TYPE" ) for attribute in person .data }
7575
7676 for token in all_tokens :
77- parsed_token = TokenParser .parse (token )
78- found_attribute , key_to_replace , replace_with = None , None , None
79-
80- attribute_level_map = {
81- TARGET_ATTRIBUTE_LEVEL : parsed_token .attribute_value ,
82- PERSON_ATTRIBUTE_LEVEL : parsed_token .attribute_name ,
83- }
84-
85- key_to_find = attribute_level_map .get (parsed_token .attribute_level )
86-
87- if (
88- parsed_token .attribute_level == TARGET_ATTRIBUTE_LEVEL
89- and parsed_token .attribute_name in ALLOWED_CONDITIONS .__args__
90- and parsed_token .attribute_value in ALLOWED_TARGET_ATTRIBUTES
91- and parsed_token .attribute_name not in present_attributes
92- ):
93- replace_with = ""
94-
95- if replace_with != "" :
96- for attribute in person .data :
97- is_person_attribute = attribute .get ("ATTRIBUTE_TYPE" ) == PERSON_ATTRIBUTE_LEVEL
98- is_allowed_target = parsed_token .attribute_name .upper () in ALLOWED_CONDITIONS .__args__
99- is_correct_target = parsed_token .attribute_name .upper () == attribute .get ("ATTRIBUTE_TYPE" )
100-
101- if ((is_allowed_target and is_correct_target ) or is_person_attribute ) and key_to_find in attribute :
102- found_attribute = attribute
103- key_to_replace = key_to_find
104- break
105-
106- if not found_attribute or key_to_replace is None :
107- TokenProcessor .handle_token_not_found (parsed_token , token )
108-
109- replace_with = TokenProcessor .apply_formatting (found_attribute , key_to_replace , parsed_token .format )
110- text = text .replace (token , str (replace_with ))
77+ replacement = TokenProcessor .get_token_replacement (token , person .data , present_attributes )
78+ text = text .replace (token , str (replacement ))
11179 return text
11280
81+ @staticmethod
82+ def get_token_replacement (token : str , person_data : list [dict ], present_attributes : set ) -> str :
83+ parsed_token = TokenParser .parse (token )
84+
85+ if TokenProcessor .should_replace_with_empty (parsed_token , present_attributes ):
86+ return ""
87+
88+ found_attribute , key_to_replace = TokenProcessor .find_matching_attribute (parsed_token , person_data )
89+
90+ if not found_attribute or not key_to_replace :
91+ TokenProcessor .handle_token_not_found (parsed_token , token )
92+
93+ return TokenProcessor .apply_formatting (found_attribute , key_to_replace , parsed_token .format )
94+
95+ @staticmethod
96+ def should_replace_with_empty (parsed_token : ParsedToken , present_attributes : set ) -> bool :
97+ is_target_level = parsed_token .attribute_level == TARGET_ATTRIBUTE_LEVEL
98+ is_allowed_condition = parsed_token .attribute_name in ALLOWED_CONDITIONS .__args__
99+ is_allowed_target_attr = parsed_token .attribute_value in ALLOWED_TARGET_ATTRIBUTES
100+ is_attr_not_present = parsed_token .attribute_name not in present_attributes
101+
102+ return all ([is_target_level , is_allowed_condition , is_allowed_target_attr , is_attr_not_present ])
103+
104+ @staticmethod
105+ def find_matching_attribute (parsed_token : ParsedToken , person_data : list [dict ]) -> tuple [dict | None , str | None ]:
106+ attribute_level_map = {
107+ TARGET_ATTRIBUTE_LEVEL : parsed_token .attribute_value ,
108+ PERSON_ATTRIBUTE_LEVEL : parsed_token .attribute_name ,
109+ }
110+ key_to_find = attribute_level_map .get (parsed_token .attribute_level )
111+
112+ for attribute in person_data :
113+ if TokenProcessor .attribute_match (attribute , parsed_token , key_to_find ):
114+ return attribute , key_to_find
115+
116+ return None , None
117+
118+ @staticmethod
119+ def attribute_match (attribute : dict , parsed_token : ParsedToken , key_to_find : str | None ) -> bool :
120+ if not key_to_find or key_to_find not in attribute :
121+ return False
122+
123+ is_person_attribute = attribute .get ("ATTRIBUTE_TYPE" ) == PERSON_ATTRIBUTE_LEVEL
124+ if is_person_attribute :
125+ return True
126+
127+ is_allowed_target = parsed_token .attribute_name .upper () in ALLOWED_CONDITIONS .__args__
128+ is_correct_target = parsed_token .attribute_name .upper () == attribute .get ("ATTRIBUTE_TYPE" )
129+
130+ return is_allowed_target and is_correct_target
131+
113132 @staticmethod
114133 def handle_token_not_found (parsed_token : ParsedToken , token : str ) -> Never :
115134 if parsed_token .attribute_level == TARGET_ATTRIBUTE_LEVEL :
0 commit comments