示例#1
0
    def __init__(self, name, matcher, pointer, once=False,
                 instream=False, stream=None):
        BaseHandler.__init__(self, name, matcher, stream)
        if not asyncio.iscoroutinefunction(pointer):
            raise ValueError("Given function is not a coroutine")

        async def pointer_wrapper(stanza, *args, **kwargs):
            try:
                await pointer(stanza, *args, **kwargs)
            except Exception as e:
                stanza.exception(e)

        self._pointer = pointer_wrapper
        self._once = once
        self._instream = instream
示例#2
0
    def event(self, name, data={}):
        """Manually trigger a custom event.

        :param name: The name of the event to trigger.
        :param data: Data that will be passed to each event handler.
                     Defaults to an empty dictionary, but is usually
                     a stanza object.
        """
        log.debug("Event triggered: %s", name)

        handlers = self.__event_handlers.get(name, [])
        for handler in handlers:
            handler_callback, disposable = handler
            old_exception = getattr(data, 'exception', None)

            # If the callback is a coroutine, schedule it instead of
            # running it directly
            if asyncio.iscoroutinefunction(handler_callback):

                async def handler_callback_routine(cb):
                    try:
                        await cb(data)
                    except Exception as e:
                        if old_exception:
                            old_exception(e)
                        else:
                            self.exception(e)

                asyncio.ensure_future(
                    handler_callback_routine(handler_callback),
                    loop=self.loop,
                )
            else:
                try:
                    handler_callback(data)
                except Exception as e:
                    if old_exception:
                        old_exception(e)
                    else:
                        self.exception(e)
            if disposable:
                # If the handler is disposable, we will go ahead and
                # remove it now instead of waiting for it to be
                # processed in the queue.
                try:
                    self.__event_handlers[name].remove(handler)
                except ValueError:
                    pass
示例#3
0
    def event(self, name, data={}):
        """Manually trigger a custom event.

        :param name: The name of the event to trigger.
        :param data: Data that will be passed to each event handler.
                     Defaults to an empty dictionary, but is usually
                     a stanza object.
        """
        log.debug("Event triggered: %s", name)

        handlers = self.__event_handlers.get(name, [])
        for handler in handlers:
            handler_callback, disposable = handler
            old_exception = getattr(data, 'exception', None)

            # If the callback is a coroutine, schedule it instead of
            # running it directly
            if asyncio.iscoroutinefunction(handler_callback):
                async def handler_callback_routine(cb):
                    try:
                        await cb(data)
                    except Exception as e:
                        if old_exception:
                            old_exception(e)
                        else:
                            self.exception(e)
                asyncio.ensure_future(
                    handler_callback_routine(handler_callback),
                    loop=self.loop,
                )
            else:
                try:
                    handler_callback(data)
                except Exception as e:
                    if old_exception:
                        old_exception(e)
                    else:
                        self.exception(e)
            if disposable:
                # If the handler is disposable, we will go ahead and
                # remove it now instead of waiting for it to be
                # processed in the queue.
                try:
                    self.__event_handlers[name].remove(handler)
                except ValueError:
                    pass
示例#4
0
    def __init__(self,
                 name,
                 matcher,
                 pointer,
                 once=False,
                 instream=False,
                 stream=None):
        BaseHandler.__init__(self, name, matcher, stream)
        if not asyncio.iscoroutinefunction(pointer):
            raise ValueError("Given function is not a coroutine")

        async def pointer_wrapper(stanza, *args, **kwargs):
            try:
                await pointer(stanza, *args, **kwargs)
            except Exception as e:
                stanza.exception(e)

        self._pointer = pointer_wrapper
        self._once = once
        self._instream = instream
示例#5
0
文件: iq.py 项目: poezio/slixmpp
    def send(self, callback=None, timeout=None, timeout_callback=None):
        """Send an <iq> stanza over the XML stream.

        A callback handler can be provided that will be executed when the Iq
        stanza's result reply is received.

        Returns a future which result will be set to the result Iq if it is of type 'get' or 'set'
        (when it is received), or a future with the result set to None if it has another type.

        Overrides StanzaBase.send

        :param function callback: Optional reference to a stream handler
                                  function. Will be executed when a reply
                                  stanza is received.
        :param int timeout: The length of time (in seconds) to wait for a
                            response before the timeout_callback is called,
                            instead of the regular callback
        :param function timeout_callback: Optional reference to a stream handler
                                          function.  Will be executed when the
                                          timeout expires before a response has
                                          been received for the originally-sent
                                          IQ stanza.
        :rtype: asyncio.Future
        """
        if self.stream.session_bind_event.is_set():
            matcher = MatchIDSender({"id": self["id"], "self": self.stream.boundjid, "peer": self["to"]})
        else:
            matcher = MatcherId(self["id"])

        future = asyncio.Future()

        def callback_success(result):
            if result["type"] == "error":
                future.set_exception(IqError(result))
            else:
                future.set_result(result)

            if timeout is not None:
                self.stream.cancel_schedule("IqTimeout_%s" % self["id"])
            if callback is not None:
                callback(result)

        def callback_timeout():
            future.set_exception(IqTimeout(self))
            self.stream.remove_handler("IqCallback_%s" % self["id"])
            if timeout_callback is not None:
                timeout_callback(self)

        if self["type"] in ("get", "set"):
            handler_name = "IqCallback_%s" % self["id"]
            if asyncio.iscoroutinefunction(callback):
                constr = CoroutineCallback
            else:
                constr = Callback
            if timeout is not None:
                self.stream.schedule("IqTimeout_%s" % self["id"], timeout, callback_timeout, repeat=False)
            handler = constr(handler_name, matcher, callback_success, once=True)
            self.stream.register_handler(handler)
        else:
            future.set_result(None)
        StanzaBase.send(self)
        return future
示例#6
0
    def send(self, callback=None, timeout=None, timeout_callback=None):
        """Send an <iq> stanza over the XML stream.

        A callback handler can be provided that will be executed when the Iq
        stanza's result reply is received.

        Returns a future which result will be set to the result Iq if it is of type 'get' or 'set'
        (when it is received), or a future with the result set to None if it has another type.

        Overrides StanzaBase.send

        :param function callback: Optional reference to a stream handler
                                  function. Will be executed when a reply
                                  stanza is received.
        :param int timeout: The length of time (in seconds) to wait for a
                            response before the timeout_callback is called,
                            instead of the regular callback
        :param function timeout_callback: Optional reference to a stream handler
                                          function.  Will be executed when the
                                          timeout expires before a response has
                                          been received for the originally-sent
                                          IQ stanza.
        :rtype: asyncio.Future
        """
        if self.stream.session_bind_event.is_set():
            matcher = MatchIDSender({
                'id': self['id'],
                'self': self.stream.boundjid,
                'peer': self['to']
            })
        else:
            matcher = MatcherId(self['id'])

        future = asyncio.Future()

        def callback_success(result):
            if result['type'] == 'error':
                future.set_exception(IqError(result))
            else:
                future.set_result(result)

            if timeout is not None:
                self.stream.cancel_schedule('IqTimeout_%s' % self['id'])
            if callback is not None:
                callback(result)

        def callback_timeout():
            future.set_exception(IqTimeout(self))
            self.stream.remove_handler('IqCallback_%s' % self['id'])
            if timeout_callback is not None:
                timeout_callback(self)

        if self['type'] in ('get', 'set'):
            handler_name = 'IqCallback_%s' % self['id']
            if asyncio.iscoroutinefunction(callback):
                constr = CoroutineCallback
            else:
                constr = Callback
            if timeout is not None:
                self.stream.schedule('IqTimeout_%s' % self['id'],
                                     timeout,
                                     callback_timeout,
                                     repeat=False)
            handler = constr(handler_name,
                             matcher,
                             callback_success,
                             once=True)
            self.stream.register_handler(handler)
        else:
            future.set_result(None)
        StanzaBase.send(self)
        return future
示例#7
0
文件: iq.py 项目: mathieui/slixmpp
    def send(self, callback=None, timeout=None, timeout_callback=None):
        """Send an <iq> stanza over the XML stream.

        A callback handler can be provided that will be executed when the Iq
        stanza's result reply is received.

        Returns a future which result will be set to the result Iq if it is of type 'get' or 'set'
        (when it is received), or a future with the result set to None if it has another type.

        Overrides StanzaBase.send

        :param function callback: Optional reference to a stream handler
                                  function. Will be executed when a reply
                                  stanza is received.
        :param int timeout: The length of time (in seconds) to wait for a
                            response before the timeout_callback is called,
                            instead of the regular callback
        :param function timeout_callback: Optional reference to a stream handler
                                          function.  Will be executed when the
                                          timeout expires before a response has
                                          been received for the originally-sent
                                          IQ stanza.
        :rtype: asyncio.Future
        """
        if self.stream.session_bind_event.is_set():
            matcher = MatchIDSender({
                'id': self['id'],
                'self': self.stream.boundjid,
                'peer': self['to']
            })
        else:
            matcher = MatcherId(self['id'])

        future = asyncio.Future()

        # Prevents handlers from existing forever.
        if timeout is None:
            timeout = 120

        def callback_success(result):
            type_ = result['type']
            if type_ == 'result':
                future.set_result(result)
            elif type_ == 'error':
                future.set_exception(IqError(result))
            else:
                # Most likely an iq addressed to ourself, rearm the callback.
                handler = constr(handler_name,
                                 matcher,
                                 callback_success,
                                 once=True)
                self.stream.register_handler(handler)
                return

            if timeout is not None:
                self.stream.cancel_schedule('IqTimeout_%s' % self['id'])
            if callback is not None:
                callback(result)

        def callback_timeout():
            future.set_exception(IqTimeout(self))
            self.stream.remove_handler('IqCallback_%s' % self['id'])
            if timeout_callback is not None:
                timeout_callback(self)

        if self['type'] in ('get', 'set'):
            handler_name = 'IqCallback_%s' % self['id']
            if asyncio.iscoroutinefunction(callback):
                constr = CoroutineCallback
            else:
                constr = Callback
            if timeout is not None:
                self.stream.schedule('IqTimeout_%s' % self['id'],
                                     timeout,
                                     callback_timeout,
                                     repeat=False)
            handler = constr(handler_name,
                             matcher,
                             callback_success,
                             once=True)
            self.stream.register_handler(handler)
        else:
            future.set_result(None)
        StanzaBase.send(self)
        return future