callback.py 3.28 KB
Newer Older
1 2 3 4 5
# slixmpp.xmlstream.handler.callback
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Part of Slixmpp: The Slick XMPP Library
# :copyright: (c) 2011 Nathanael C. Fritz
# :license: MIT, see LICENSE for more details
mathieui's avatar
mathieui committed
6 7 8
from __future__ import annotations

from typing import Optional, Callable, Any, TYPE_CHECKING
louiz’'s avatar
louiz’ committed
9
from slixmpp.xmlstream.handler.base import BaseHandler
mathieui's avatar
mathieui committed
10 11 12 13 14
from slixmpp.xmlstream.matcher.base import MatcherBase

if TYPE_CHECKING:
    from slixmpp.xmlstream.stanzabase import StanzaBase
    from slixmpp.xmlstream.xmlstream import XMLStream
15 16 17 18 19 20 21 22 23 24 25


class Callback(BaseHandler):

    """
    The Callback handler will execute a callback function with
    matched stanzas.

    The handler may execute the callback either during stream
    processing or during the main event loop.

26 27
    Callback functions are all executed in the same thread, so be aware if
    you are executing functions that will block for extended periods of
louiz’'s avatar
louiz’ committed
28 29
    time. Typically, you should signal your own events using the Slixmpp
    object's :meth:`~slixmpp.xmlstream.xmlstream.XMLStream.event()`
30 31 32 33 34
    method to pass the stanza off to a threaded event handler for further
    processing.


    :param string name: The name of the handler.
louiz’'s avatar
louiz’ committed
35
    :param matcher: A :class:`~slixmpp.xmlstream.matcher.base.MatcherBase`
36 37 38 39 40 41 42
                    derived object for matching stanza objects.
    :param pointer: The function to execute during callback.
    :param bool once: Indicates if the handler should be used only
                      once. Defaults to False.
    :param bool instream: Indicates if the callback should be executed
                          during stream processing instead of in the
                          main event loop.
louiz’'s avatar
louiz’ committed
43
    :param stream: The :class:`~slixmpp.xmlstream.xmlstream.XMLStream`
44
                   instance this handler should monitor.
45
    """
mathieui's avatar
mathieui committed
46 47 48
    _once: bool
    _instream: bool
    _pointer: Callable[[StanzaBase], Any]
49

mathieui's avatar
mathieui committed
50 51 52 53
    def __init__(self, name: str, matcher: MatcherBase,
                 pointer: Callable[[StanzaBase], Any],
                 once: bool = False, instream: bool = False,
                 stream: Optional[XMLStream] = None):
54 55 56 57 58
        BaseHandler.__init__(self, name, matcher, stream)
        self._pointer = pointer
        self._once = once
        self._instream = instream

mathieui's avatar
mathieui committed
59
    def prerun(self, payload: StanzaBase) -> None:
60 61
        """Execute the callback during stream processing, if
        the callback was created with ``instream=True``.
62

63
        :param payload: The matched
mathieui's avatar
mathieui committed
64
            :class:`~slixmpp.xmlstream.stanzabase.StanzaBase` object.
65
        """
66 67
        if self._once:
            self._destroy = True
68 69 70
        if self._instream:
            self.run(payload, True)

mathieui's avatar
mathieui committed
71
    def run(self, payload: StanzaBase, instream: bool = False) -> None:
72
        """Execute the callback function with the matched stanza payload.
73

74
        :param payload: The matched
mathieui's avatar
mathieui committed
75
            :class:`~slixmpp.xmlstream.stanzabase.StanzaBase` object.
76 77 78
        :param bool instream: Force the handler to execute during stream
                              processing. This should only be used by
                              :meth:`prerun()`. Defaults to ``False``.
79 80 81 82 83
        """
        if not self._instream or instream:
            self._pointer(payload)
            if self._once:
                self._destroy = True
84
                del self._pointer