class EventsDispatcher(object): """Abstract object from which all the objects generating events inherit""" def __init__(self): self._events_handlers = WeakSet() ### Callbacks def register_events_handler(self, events_handler): """Registers an event handler with this dispatcher @param events_handler: an instance with methods as code of callbacks @type events_handler: L{papyon.event.BaseEventInterface} """ self._events_handlers.add(events_handler) def _dispatch(self, name, *args): count = 0 for event_handler in list(self._events_handlers): if event_handler._dispatch_event(name, *args): count += 1 return count
class SwitchboardManager(gobject.GObject): """Switchboard management @undocumented: do_get_property, do_set_property @group Handlers: _handle_*, _default_handler, _error_handler""" __gsignals__ = { "handler-created": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (object, object)) } def __init__(self, client): """Initializer @param client: the main Client instance""" gobject.GObject.__init__(self) self._client = weakref.proxy(client) self._reset() self._handlers_class = set() self._client._protocol.connect("switchboard-invitation-received", self._ns_switchboard_invite) def _reset(self): self._switchboards = {} self._orphaned_switchboards = set() self._requested_switchboards = {} self._pending_switchboards = {} self._orphaned_handlers = WeakSet() def close(self): for switchboard in self._orphaned_switchboards: switchboard.leave() for switchboard in self._pending_switchboards: switchboard.leave() for switchboard in self._switchboards: switchboard.leave() self._reset() def register_handler_class(self, handler_class, *extra_arguments): self._handlers_class.add((handler_class, extra_arguments)) def register_handler(self, handler): self._orphaned_handlers.add(handler) def request_switchboard(self, handler, priority=99): handler_participants = handler.total_participants participants = ", ".join(map(lambda c: c.account, handler_participants)) logger.info("Requesting switchboard for participant(s) %s" % participants) # If the Handler was orphan, then it is no more self._orphaned_handlers.discard(handler) # Check already open switchboards for switchboard in self._switchboards.keys(): switchboard_participants = set(switchboard.participants.values()) if handler_participants == switchboard_participants and \ (switchboard.state == msnp.ProtocolState.OPEN or \ switchboard.state == msnp.ProtocolState.OPENING): logger.info("Using already opened switchboard %s" % switchboard.session_id) self._switchboards[switchboard].add(handler) handler._switchboard = switchboard return # Check Orphaned switchboards for switchboard in list(self._orphaned_switchboards): switchboard_participants = set(switchboard.participants.values()) if handler_participants == switchboard_participants and \ (switchboard.state == msnp.ProtocolState.OPEN or \ switchboard.state == msnp.ProtocolState.OPENING): logger.info("Using orphaned switchboard %s" % switchboard.session_id) self._switchboards[switchboard] = set([handler ]) #FIXME: WeakSet ? self._orphaned_switchboards.discard(switchboard) handler._switchboard = switchboard return # Check pending switchboards for switchboard, handlers in self._pending_switchboards.iteritems(): pending_handler = handlers.pop() handlers.add(pending_handler) switchboard_participants = pending_handler.total_participants if handler_participants == switchboard_participants: self._pending_switchboards[switchboard].add(handler) logger.info("Using pending switchboard") return # Check switchboards being requested for same participants if participants in self._requested_switchboards: self._requested_switchboards[participants].add(handler) logger.info( "Using already requested switchboard for same contacts") return logger.info("Requesting new switchboard") self._requested_switchboards[participants] = set([handler]) self._client._protocol.request_switchboard( priority, (self._ns_switchboard_request_response, participants)) def close_handler(self, handler): logger.info("Closing switchboard handler %s" % repr(handler)) self._orphaned_handlers.discard(handler) handler._on_closed() for switchboard in self._switchboards.keys(): handlers = self._switchboards[switchboard] handlers.discard(handler) if len(handlers) == 0: switchboard.leave() del self._switchboards[switchboard] self._orphaned_switchboards.add(switchboard) for switchboard in self._pending_switchboards.keys(): handlers = self._pending_switchboards[switchboard] handlers.discard(handler) if len(handlers) == 0: del self._pending_switchboards[switchboard] self._orphaned_switchboards.add(switchboard) def _ns_switchboard_request_response(self, session, participants): switchboard = self._build_switchboard(session) handlers = self._requested_switchboards.pop(participants, set()) self._pending_switchboards[switchboard] = handlers def _ns_switchboard_invite(self, protocol, session, inviter): switchboard = self._build_switchboard(session) self._orphaned_switchboards.add(switchboard) def _build_switchboard(self, session): server, session_id, key = session client = self._client proxies = client._proxies transport_class = client._transport_class transport = transport_class(server, ServerType.SWITCHBOARD, proxies) switchboard = msnp.SwitchboardProtocol(client, transport, session_id, key, proxies) switchboard.connect("notify::state", self._sb_state_changed) switchboard.connect("message-received", self._sb_message_received) transport.establish_connection() return switchboard def _sb_state_changed(self, switchboard, param_spec): state = switchboard.state if state == msnp.ProtocolState.OPEN: self._switchboards[switchboard] = set() #FIXME: WeakSet ? # Requested switchboards if switchboard in self._pending_switchboards: handlers = self._pending_switchboards[switchboard] while True: try: handler = handlers.pop() self._switchboards[switchboard].add(handler) handler._switchboard = switchboard except KeyError: break del self._pending_switchboards[switchboard] # Orphaned Handlers for handler in list(self._orphaned_handlers): switchboard_participants = set( switchboard.participants.values()) handler_participants = handler.total_participants if handler_participants == switchboard_participants: self._switchboards[switchboard].add(handler) self._orphaned_handlers.discard(handler) self._orphaned_switchboards.discard(switchboard) handler._switchboard = switchboard # no one wants it, it is an orphan if len(self._switchboards[switchboard]) == 0: del self._switchboards[switchboard] self._orphaned_switchboards.add(switchboard) elif state == msnp.ProtocolState.CLOSED: if switchboard in self._switchboards.keys(): for handler in self._switchboards[switchboard]: self._orphaned_handlers.add(handler) handler._on_switchboard_closed() del self._switchboards[switchboard] self._orphaned_switchboards.discard(switchboard) def _sb_message_received(self, switchboard, message): switchboard_participants = set(switchboard.participants.values()) # Get current handlers for this switchboard if switchboard in self._switchboards.keys(): handlers = self._switchboards[switchboard] handlers_class = [type(handler) for handler in handlers] elif switchboard in list(self._orphaned_switchboards): handlers = set() #FIXME: WeakSet ? handlers_class = [] self._switchboards[switchboard] = handlers else: logger.warning("Message received on unknown switchboard") return # Signal message to existing handlers for handler in list(handlers): if not handler._can_handle_message(message, handler): continue handler._on_message_received(message) return # Create first handler that could handle this message for handler_class, extra_args in self._handlers_class: if not handler_class._can_handle_message(message): continue handler = handler_class.handle_message(self._client, message, *extra_args) if handler is None: continue self._orphaned_handlers.discard(handler) self._orphaned_switchboards.discard(switchboard) handlers.add(handler) handler._switchboard = switchboard self.emit("handler-created", handler_class, handler) handler._on_message_received(message) return
class SwitchboardManager(gobject.GObject): """Switchboard management @undocumented: do_get_property, do_set_property @group Handlers: _handle_*, _default_handler, _error_handler""" __gsignals__ = { "handler-created": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (object, object)) } def __init__(self, client): """Initializer @param client: the main Client instance""" gobject.GObject.__init__(self) self._client = weakref.proxy(client) self._reset() self._handlers_class = set() self._client._protocol.connect("switchboard-invitation-received", self._ns_switchboard_invite) def _reset(self): self._switchboards = {} self._orphaned_switchboards = set() self._requested_switchboards = {} self._pending_switchboards = {} self._orphaned_handlers = WeakSet() def close(self): for switchboard in self._orphaned_switchboards: switchboard.leave() for switchboard in self._pending_switchboards: switchboard.leave() for switchboard in self._switchboards: switchboard.leave() self._reset() def register_handler_class(self, handler_class, *extra_arguments): self._handlers_class.add((handler_class, extra_arguments)) def register_handler(self, handler): self._orphaned_handlers.add(handler) def request_switchboard(self, handler, priority=99): handler_participants = handler.total_participants participants = ", ".join(map(lambda c: c.account, handler_participants)) logger.info("Requesting switchboard for participant(s) %s" % participants) # If the Handler was orphan, then it is no more self._orphaned_handlers.discard(handler) # Check already open switchboards for switchboard in self._switchboards.keys(): switchboard_participants = set(switchboard.participants.values()) if handler_participants == switchboard_participants: logger.info("Using already opened switchboard %s" % switchboard.session_id) self._switchboards[switchboard].add(handler) handler._switchboard = switchboard return # Check Orphaned switchboards for switchboard in list(self._orphaned_switchboards): switchboard_participants = set(switchboard.participants.values()) if handler_participants == switchboard_participants: logger.info("Using orphaned switchboard %s" % switchboard.session_id) self._switchboards[switchboard] = set([handler]) #FIXME: WeakSet ? self._orphaned_switchboards.discard(switchboard) handler._switchboard = switchboard return # Check pending switchboards for switchboard, handlers in self._pending_switchboards.iteritems(): pending_handler = handlers.pop() handlers.add(pending_handler) switchboard_participants = pending_handler.total_participants if handler_participants == switchboard_participants: self._pending_switchboards[switchboard].add(handler) logger.info("Using pending switchboard") return # Check switchboards being requested for same participants if participants in self._requested_switchboards: self._requested_switchboards[participants].add(handler) logger.info("Using already requested switchboard for same contacts") return logger.info("Requesting new switchboard") self._requested_switchboards[participants] = set([handler]) self._client._protocol.request_switchboard(priority, (self._ns_switchboard_request_response, participants)) def close_handler(self, handler): logger.info("Closing switchboard handler %s" % repr(handler)) self._orphaned_handlers.discard(handler) handler._on_closed() for switchboard in self._switchboards.keys(): handlers = self._switchboards[switchboard] handlers.discard(handler) if len(handlers) == 0: switchboard.leave() del self._switchboards[switchboard] self._orphaned_switchboards.add(switchboard) for switchboard in self._pending_switchboards.keys(): handlers = self._pending_switchboards[switchboard] handlers.discard(handler) if len(handlers) == 0: del self._pending_switchboards[switchboard] self._orphaned_switchboards.add(switchboard) def _ns_switchboard_request_response(self, session, participants): switchboard = self._build_switchboard(session) handlers = self._requested_switchboards.pop(participants, set()) self._pending_switchboards[switchboard] = handlers def _ns_switchboard_invite(self, protocol, session, inviter): switchboard = self._build_switchboard(session) self._orphaned_switchboards.add(switchboard) def _build_switchboard(self, session): server, session_id, key = session client = self._client proxies = client._proxies transport_class = client._transport_class transport = transport_class(server, ServerType.SWITCHBOARD, proxies) switchboard = msnp.SwitchboardProtocol(client, transport, session_id, key, proxies) switchboard.connect("notify::state", self._sb_state_changed) switchboard.connect("message-received", self._sb_message_received) transport.establish_connection() return switchboard def _sb_state_changed(self, switchboard, param_spec): state = switchboard.state if state == msnp.ProtocolState.OPEN: self._switchboards[switchboard] = set() #FIXME: WeakSet ? # Requested switchboards if switchboard in self._pending_switchboards: handlers = self._pending_switchboards[switchboard] while True: try: handler = handlers.pop() self._switchboards[switchboard].add(handler) handler._switchboard = switchboard except KeyError: break del self._pending_switchboards[switchboard] # Orphaned Handlers for handler in list(self._orphaned_handlers): switchboard_participants = set(switchboard.participants.values()) handler_participants = handler.total_participants if handler_participants == switchboard_participants: self._switchboards[switchboard].add(handler) self._orphaned_handlers.discard(handler) self._orphaned_switchboards.discard(switchboard) handler._switchboard = switchboard # no one wants it, it is an orphan if len(self._switchboards[switchboard]) == 0: del self._switchboards[switchboard] self._orphaned_switchboards.add(switchboard) elif state == msnp.ProtocolState.CLOSED: if switchboard in self._switchboards.keys(): for handler in self._switchboards[switchboard]: self._orphaned_handlers.add(handler) handler._on_switchboard_closed() del self._switchboards[switchboard] self._orphaned_switchboards.discard(switchboard) def _sb_message_received(self, switchboard, message): switchboard_participants = set(switchboard.participants.values()) # Get current handlers for this switchboard if switchboard in self._switchboards.keys(): handlers = self._switchboards[switchboard] handlers_class = [type(handler) for handler in handlers] elif switchboard in list(self._orphaned_switchboards): handlers = set() #FIXME: WeakSet ? handlers_class = [] self._switchboards[switchboard] = handlers else: logger.warning("Message received on unknown switchboard") return # Signal message to existing handlers for handler in list(handlers): if not handler._can_handle_message(message, handler): continue handler._on_message_received(message) return # Create first handler that could handle this message for handler_class, extra_args in self._handlers_class: if not handler_class._can_handle_message(message): continue handler = handler_class.handle_message(self._client, message, *extra_args) if handler is None: continue self._orphaned_handlers.discard(handler) self._orphaned_switchboards.discard(switchboard) handlers.add(handler) handler._switchboard = switchboard self.emit("handler-created", handler_class, handler) handler._on_message_received(message) return
class SwitchboardManager(gobject.GObject): """Switchboard management @undocumented: do_get_property, do_set_property @group Handlers: _handle_*, _default_handler, _error_handler""" __gsignals__ = { "handler-created": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (object, object)) } def __init__(self, client): """Initializer @param client: the main Client instance""" gobject.GObject.__init__(self) self._client = weakref.proxy(client) self._handlers_class = set() self._orphaned_handlers = WeakSet() self._switchboards = {} self._orphaned_switchboards = set() self._pending_switchboards = {} self._client._protocol.connect("switchboard-invitation-received", self._ns_switchboard_invite) def close(self): for switchboard in self._orphaned_switchboards: switchboard.leave() for switchboard in self._pending_switchboards: switchboard.leave() for switchboard in self._switchboards: switchboard.leave() def register_handler(self, handler_class, *extra_arguments): self._handlers_class.add((handler_class, extra_arguments)) def request_switchboard(self, handler, priority=99): handler_participants = handler.total_participants # If the Handler was orphan, then it is no more self._orphaned_handlers.discard(handler) # Check already open switchboards for switchboard in self._switchboards.keys(): switchboard_participants = set(switchboard.participants.values()) if handler_participants == switchboard_participants: self._switchboards[switchboard].add(handler) handler._switchboard = switchboard return # Check Orphaned switchboards for switchboard in list(self._orphaned_switchboards): switchboard_participants = set(switchboard.participants.values()) if handler_participants == switchboard_participants: self._switchboards[switchboard] = set([handler]) #FIXME: WeakSet ? self._orphaned_switchboards.discard(switchboard) handler._switchboard = switchboard return # Check being requested switchboards for switchboard, handlers in self._pending_switchboards.iteritems(): pending_handler = handlers.pop() handlers.add(pending_handler) switchboard_participants = pending_handler.total_participants if handler_participants == switchboard_participants: self._pending_switchboards[switchboard].add(handler) return self._client._protocol.\ request_switchboard(priority, self._ns_switchboard_request_response, handler) def close_handler(self, handler): self._orphaned_handlers.discard(handler) for switchboard in self._switchboards.keys(): handlers = self._switchboards[switchboard] handlers.discard(handler) if len(handlers) == 0: switchboard.leave() del self._switchboards[switchboard] self._orphaned_switchboards.add(switchboard) for switchboard in self._pending_switchboards.keys(): handlers = self._pending_switchboards[switchboard] handlers.discard(handler) if len(handlers) == 0: del self._pending_switchboards[switchboard] self._orphaned_switchboards.add(switchboard) def _ns_switchboard_request_response(self, session, handler): switchboard = self._build_switchboard(session) self._pending_switchboards[switchboard] = set([handler]) #FIXME: WeakSet ? def _ns_switchboard_invite(self, protocol, session, inviter): switchboard = self._build_switchboard(session) self._orphaned_switchboards.add(switchboard) def _build_switchboard(self, session): server, session_id, key = session client = self._client proxies = client._proxies transport_class = client._transport_class transport = transport_class(server, ServerType.SWITCHBOARD, proxies) switchboard = msnp.SwitchboardProtocol(client, transport, session_id, key, proxies) switchboard.connect("notify::state", self._sb_state_changed) switchboard.connect("message-received", self._sb_message_received) transport.establish_connection() return switchboard def _sb_state_changed(self, switchboard, param_spec): state = switchboard.state if state == msnp.ProtocolState.OPEN: self._switchboards[switchboard] = set() #FIXME: WeakSet ? # Requested switchboards if switchboard in self._pending_switchboards: handlers = self._pending_switchboards[switchboard] while True: try: handler = handlers.pop() self._switchboards[switchboard].add(handler) handler._switchboard = switchboard except KeyError: break del self._pending_switchboards[switchboard] # Orphaned Handlers for handler in list(self._orphaned_handlers): switchboard_participants = set(switchboard.participants.values()) handler_participants = handler.total_participants if handler_participants == switchboard_participants: self._switchboards[switchboard].add(handler) self._orphaned_handlers.discard(handler) self._orphaned_switchboards.discard(switchboard) handler._switchboard = switchboard # no one wants it, it is an orphan if len(self._switchboards[switchboard]) == 0: del self._switchboards[switchboard] self._orphaned_switchboards.add(switchboard) elif state == msnp.ProtocolState.CLOSED: if switchboard in self._switchboards.keys(): for handler in self._switchboards[switchboard]: self._orphaned_handlers.add(handler) del self._switchboards[switchboard] self._orphaned_switchboards.discard(switchboard) def _sb_message_received(self, switchboard, message): switchboard_participants = set(switchboard.participants.values()) if switchboard in self._switchboards.keys(): handlers = self._switchboards[switchboard] handlers_class = [type(handler) for handler in handlers] for handler in list(handlers): if not handler._can_handle_message(message, handler): continue handler._on_message_received(message) for handler_class, extra_args in self._handlers_class: if handler_class in handlers_class: continue if not handler_class._can_handle_message(message): continue handler = handler_class(self._client, (), *extra_args) handlers.add(handler) handler._switchboard = switchboard self.emit("handler-created", handler_class, handler) handler._on_message_received(message) if switchboard in list(self._orphaned_switchboards): for handler_class, extra_args in self._handlers_class: if not handler_class._can_handle_message(message): continue handler = handler_class(self._client, (), *extra_args) self._switchboards[switchboard] = set([handler]) #FIXME: WeakSet ? self._orphaned_switchboards.discard(switchboard) handler._switchboard = switchboard self.emit("handler-created", handler_class, handler) handler._on_message_received(message)