1818import logging
1919import sys
2020
21+ logger = logging .getLogger (__name__ )
22+
2123
2224class MatrixClient (object ):
2325 """
@@ -85,8 +87,6 @@ def __init__(self, base_url, token=None, user_id=None, valid_cert_check=True):
8587 self .sync_token = None
8688 self .sync_filter = None
8789
88- self .logger = logging .getLogger ("matrix_client" )
89-
9090 """ Time to wait before attempting a /sync request after failing."""
9191 self .bad_sync_timeout_limit = 60 * 60
9292 self .rooms = {
@@ -198,14 +198,20 @@ def get_rooms(self):
198198 """
199199 return self .rooms
200200
201- def add_listener (self , callback ):
201+ def add_listener (self , callback , event_type = None ):
202202 """ Add a listener that will send a callback when the client recieves
203203 an event.
204204
205205 Args:
206206 callback (func(roomchunk)): Callback called when an event arrives.
207+ event_type (str): The event_type to filter for.
207208 """
208- self .listeners .append (callback )
209+ self .listeners .append (
210+ {
211+ 'callback' : callback ,
212+ 'event_type' : event_type
213+ }
214+ )
209215
210216 def add_invite_listener (self , callback ):
211217 """ Add a listener that will send a callback when the client receives
@@ -249,17 +255,17 @@ def listen_forever(self, timeout_ms=30000):
249255 self ._sync (timeout_ms )
250256 bad_sync_timeout = 5
251257 except MatrixRequestError as e :
252- self . logger .warning ("A MatrixRequestError occured during sync." )
258+ logger .warning ("A MatrixRequestError occured during sync." )
253259 if e .code >= 500 :
254- self . logger .warning ("Problem occured serverside. Waiting %i seconds" ,
255- bad_sync_timeout )
260+ logger .warning ("Problem occured serverside. Waiting %i seconds" ,
261+ bad_sync_timeout )
256262 sleep (bad_sync_timeout )
257263 bad_sync_timeout = min (bad_sync_timeout * 2 ,
258264 self .bad_sync_timeout_limit )
259265 else :
260266 raise e
261267 except Exception as e :
262- self . logger .error ("Exception thrown during sync\n %s" , str ( e ) )
268+ logger .exception ("Exception thrown during sync" )
263269
264270 def start_listener_thread (self , timeout_ms = 30000 ):
265271 """ Start a listener thread to listen for events in the background.
@@ -274,7 +280,7 @@ def start_listener_thread(self, timeout_ms=30000):
274280 thread .start ()
275281 except :
276282 e = sys .exc_info ()[0 ]
277- self . logger .error ("Error: unable to start thread. %s" , str (e ))
283+ logger .error ("Error: unable to start thread. %s" , str (e ))
278284
279285 def upload (self , content , content_type ):
280286 """ Upload content to the home server and recieve a MXC url.
@@ -317,6 +323,13 @@ def _process_state_event(self, state_event, current_room):
317323 elif etype == "m.room.aliases" :
318324 current_room .aliases = state_event ["content" ].get ("aliases" , None )
319325
326+ for listener in current_room .state_listeners :
327+ if (
328+ listener ['event_type' ] is None or
329+ listener ['event_type' ] == state_event ['type' ]
330+ ):
331+ listener ['callback' ](state_event )
332+
320333 def _sync (self , timeout_ms = 30000 ):
321334 # TODO: Deal with presence
322335 # TODO: Deal with left rooms
@@ -342,6 +355,14 @@ def _sync(self, timeout_ms=30000):
342355 for event in sync_room ["timeline" ]["events" ]:
343356 room ._put_event (event )
344357
358+ # Dispatch for client (global) listeners
359+ for listener in self .listeners :
360+ if (
361+ listener ['event_type' ] is None or
362+ listener ['event_type' ] == event ['type' ]
363+ ):
364+ listener ['callback' ](event )
365+
345366 def get_user (self , user_id ):
346367 """ Return a User by their id.
347368
@@ -375,6 +396,7 @@ def __init__(self, client, room_id):
375396 self .room_id = room_id
376397 self .client = client
377398 self .listeners = []
399+ self .state_listeners = []
378400 self .events = []
379401 self .event_history_limit = 20
380402 self .name = None
@@ -417,13 +439,33 @@ def send_image(self, url, name, **imageinfo):
417439 extra_information = imageinfo
418440 )
419441
420- def add_listener (self , callback ):
442+ def add_listener (self , callback , event_type = None ):
421443 """ Add a callback handler for events going to this room.
422444
423445 Args:
424446 callback (func(roomchunk)): Callback called when an event arrives.
447+ event_type (str): The event_type to filter for.
425448 """
426- self .listeners .append (callback )
449+ self .listeners .append (
450+ {
451+ 'callback' : callback ,
452+ 'event_type' : event_type
453+ }
454+ )
455+
456+ def add_state_listener (self , callback , event_type = None ):
457+ """ Add a callback handler for state events going to this room.
458+
459+ Args:
460+ callback (func(roomchunk)): Callback called when an event arrives.
461+ event_type (str): The event_type to filter for.
462+ """
463+ self .state_listeners .append (
464+ {
465+ 'callback' : callback ,
466+ 'event_type' : event_type
467+ }
468+ )
427469
428470 def _put_event (self , event ):
429471 self .events .append (event )
@@ -432,7 +474,8 @@ def _put_event(self, event):
432474
433475 # Dispatch for room-specific listeners
434476 for listener in self .listeners :
435- listener (self , event )
477+ if listener ['event_type' ] is None or listener ['event_type' ] == event ['type' ]:
478+ listener ['callback' ](self , event )
436479
437480 # Dispatch for client (global) listeners
438481 for listener in self .client .listeners :
0 commit comments