<s> """<STR_LIT>""" <EOL> __docformat__ = "<STR_LIT>" <EOL> import queue <EOL> import threading <EOL> import logging <EOL> import inspect <EOL> from collections import defaultdict <EOL> logger = logging . getLogger ( "<STR_LIT>" ) <EOL> from . interfaces import EventHandler , Event , QUIT <EOL> from . . settings import XMPPSettings <EOL> class EventDispatcher ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , settings = None , handlers = None ) : <EOL> """<STR_LIT>""" <EOL> if settings is None : <EOL> settings = XMPPSettings ( ) <EOL> self . queue = settings [ "<STR_LIT>" ] <EOL> self . _handler_map = defaultdict ( list ) <EOL> if handlers : <EOL> self . handlers = list ( handlers ) <EOL> else : <EOL> self . handlers = [ ] <EOL> self . _update_handlers ( ) <EOL> self . lock = threading . RLock ( ) <EOL> def add_handler ( self , handler ) : <EOL> """<STR_LIT>""" <EOL> if not isinstance ( handler , EventHandler ) : <EOL> raise TypeError ( "<STR_LIT>" ) <EOL> with self . lock : <EOL> if handler in self . handlers : <EOL> return <EOL> self . handlers . append ( handler ) <EOL> self . _update_handlers ( ) <EOL> def remove_handler ( self , handler ) : <EOL> """<STR_LIT>""" <EOL> with self . lock : <EOL> if handler in self . handlers : <EOL> self . handlers . remove ( handler ) <EOL> self . _update_handlers ( ) <EOL> def _update_handlers ( self ) : <EOL> """<STR_LIT>""" <EOL> handler_map = defaultdict ( list ) <EOL> for i , obj in enumerate ( self . handlers ) : <EOL> for dummy , handler in inspect . getmembers ( obj , callable ) : <EOL> if not hasattr ( handler , "<STR_LIT>" ) : <EOL> continue <EOL> event_class = handler . _pyxmpp_event_handled <EOL> handler_map [ event_class ] . append ( ( i , handler ) ) <EOL> self . _handler_map = handler_map <EOL> def dispatch ( self , block = False , timeout = None ) : <EOL> """<STR_LIT>""" <EOL> logger . debug ( "<STR_LIT>" ) <EOL> try : <EOL> event = self . queue . get ( block , timeout ) <EOL> except queue . Empty : <EOL> logger . debug ( "<STR_LIT>" ) <EOL> return None <EOL> try : <EOL> logger . debug ( "<STR_LIT>" . format ( event ) ) <EOL> if event is QUIT : <EOL> return QUIT <EOL> handlers = list ( self . _handler_map [ None ] ) <EOL> klass = event . __class__ <EOL> if klass in self . _handler_map : <EOL> handlers += self . _handler_map [ klass ] <EOL> logger . debug ( "<STR_LIT>" . format ( handlers ) ) <EOL> handlers . sort ( key = lambda x : x [ <NUM_LIT:0> ] ) <EOL> for dummy , handler in handlers : <EOL> logger . debug ( "<STR_LIT>" . format ( handler ) ) <EOL> result = handler ( event ) <EOL> if isinstance ( result , Event ) : <EOL> self . queue . put ( result ) <EOL> elif result and event is not QUIT : <EOL> return event <EOL> return event <EOL> finally : <EOL> self . queue . task_done ( ) <EOL> def flush ( self , dispatch = True ) : <EOL> """<STR_LIT>""" <EOL> if dispatch : <EOL> while True : <EOL> event = self . dispatch ( False ) <EOL> if event in ( None , QUIT ) : <EOL> return event <EOL> else : <EOL> while True : <EOL> try : <EOL> self . queue . get ( False ) <EOL> except queue . Empty : <EOL> return None <EOL> def loop ( self ) : <EOL> """<STR_LIT>""" <EOL> while self . dispatch ( True ) is not QUIT : <EOL> pass <EOL> def _event_queue_factory ( settings ) : <EOL> """<STR_LIT>""" <EOL> return queue . Queue ( settings [ "<STR_LIT>" ] ) <EOL> XMPPSettings . add_setting ( "<STR_LIT>" , type = queue . Queue , <EOL> factory = _event_queue_factory , cache = True , <EOL> default_d = "<STR_LIT>" , <EOL> doc = """<STR_LIT>""" <EOL> ) <EOL> XMPPSettings . add_setting ( "<STR_LIT>" , type = int , <EOL> default = <NUM_LIT:0> , <EOL> doc = """<STR_LIT>""" <EOL> ) </s>
