@@ -129,9 +129,55 @@ def __init__(
129129 # Maps strings of e.g. 'content.body' -> event["content"]["body"]
130130 self ._value_cache = _flatten_dict (event )
131131
132+ # Maps cache keys to final values.
133+ self ._condition_cache : Dict [str , bool ] = {}
134+
135+ def check_conditions (
136+ self , conditions : List [dict ], uid : str , display_name : Optional [str ]
137+ ) -> bool :
138+ """
139+ Returns true if a user's conditions/user ID/display name match the event.
140+
141+ Args:
142+ conditions: The user's conditions to match.
143+ uid: The user's MXID.
144+ display_name: The display name.
145+
146+ Returns:
147+ True if all conditions match the event, False otherwise.
148+ """
149+ for cond in conditions :
150+ _cache_key = cond .get ("_cache_key" , None )
151+ if _cache_key :
152+ res = self ._condition_cache .get (_cache_key , None )
153+ if res is False :
154+ return False
155+ elif res is True :
156+ continue
157+
158+ res = self .matches (cond , uid , display_name )
159+ if _cache_key :
160+ self ._condition_cache [_cache_key ] = bool (res )
161+
162+ if not res :
163+ return False
164+
165+ return True
166+
132167 def matches (
133168 self , condition : Dict [str , Any ], user_id : str , display_name : Optional [str ]
134169 ) -> bool :
170+ """
171+ Returns true if a user's condition/user ID/display name match the event.
172+
173+ Args:
174+ condition: The user's condition to match.
175+ uid: The user's MXID.
176+ display_name: The display name, or None if there is not one.
177+
178+ Returns:
179+ True if the condition matches the event, False otherwise.
180+ """
135181 if condition ["kind" ] == "event_match" :
136182 return self ._event_match (condition , user_id )
137183 elif condition ["kind" ] == "contains_display_name" :
@@ -146,6 +192,16 @@ def matches(
146192 return True
147193
148194 def _event_match (self , condition : dict , user_id : str ) -> bool :
195+ """
196+ Check an "event_match" push rule condition.
197+
198+ Args:
199+ condition: The "event_match" push rule condition to match.
200+ user_id: The user's MXID.
201+
202+ Returns:
203+ True if the condition matches the event, False otherwise.
204+ """
149205 pattern = condition .get ("pattern" , None )
150206
151207 if not pattern :
@@ -167,13 +223,22 @@ def _event_match(self, condition: dict, user_id: str) -> bool:
167223
168224 return _glob_matches (pattern , body , word_boundary = True )
169225 else :
170- haystack = self ._get_value (condition ["key" ])
226+ haystack = self ._value_cache . get (condition ["key" ], None )
171227 if haystack is None :
172228 return False
173229
174230 return _glob_matches (pattern , haystack )
175231
176232 def _contains_display_name (self , display_name : Optional [str ]) -> bool :
233+ """
234+ Check an "event_match" push rule condition.
235+
236+ Args:
237+ display_name: The display name, or None if there is not one.
238+
239+ Returns:
240+ True if the display name is found in the event body, False otherwise.
241+ """
177242 if not display_name :
178243 return False
179244
@@ -191,9 +256,6 @@ def _contains_display_name(self, display_name: Optional[str]) -> bool:
191256
192257 return bool (r .search (body ))
193258
194- def _get_value (self , dotted_key : str ) -> Optional [str ]:
195- return self ._value_cache .get (dotted_key , None )
196-
197259
198260# Caches (string, is_glob, word_boundary) -> regex for push. See _glob_matches
199261regex_cache : LruCache [Tuple [str , bool , bool ], Pattern ] = LruCache (
0 commit comments