Source code for aioxmpp.chatstates.utils

########################################################################
# File name: utils.py
# This file is part of: aioxmpp
#
# LICENSE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program.  If not, see
# <http://www.gnu.org/licenses/>.
#
########################################################################
from abc import ABCMeta, abstractproperty

from . import xso as chatstates_xso


class ChatStateStrategy(metaclass=ABCMeta):

    @abstractproperty
    def sending(self):
        """
        Return whether to send chat state notifications.
        """
        raise NotImplementedError  # pragma: no cover

    def reset(self):
        """
        Reset the strategy (called after a reconnect).
        """
        pass

    def no_reply(self):
        """
        Called when the replies did not include a chat state.
        """
        pass


[docs]class DoNotEmit(ChatStateStrategy): """ Chat state strategy: Do not emit chat state notifications. """ @property def sending(self): return False
[docs]class DiscoverSupport(ChatStateStrategy): """ Chat state strategy: Discover support for chat state notifications as per section 5.1 of :xep:`0085`. """ def __init__(self): self.state = True def reset(self): self.state = True def no_reply(self): self.state = False @property def sending(self): return self.state
[docs]class AlwaysEmit(ChatStateStrategy): """ Chat state strategy: Always emit chat state notifications. """ @property def sending(self): return True
[docs]class ChatStateManager: """ Manage the state of our chat state. :param strategy: the strategy used to decide whether to send notifications (defaults to :class:`DiscoverSupport`) :type strategy: a subclass of :class:`ChatStateStrategy` .. automethod:: handle Methods to pass in protocol level information: .. automethod:: no_reply .. automethod:: reset """ def __init__(self, strategy=None): self._state = chatstates_xso.ChatState.ACTIVE if strategy is None: strategy = DiscoverSupport() self._strategy = strategy
[docs] def handle(self, state, message=False): """ Handle a state update. :param state: the new chat state :type state: :class:`~aioxmpp.chatstates.ChatState` :param message: pass true to indicate that we handle the :data:`ACTIVE` state that is implied by sending a content message. :type message: :class:`bool` :returns: whether a standalone notification must be sent for this state update, respective if a chat state notification must be included with the message. :raises ValueError: if `message` is true and a state other than :data:`ACTIVE` is passed. """ if message: if state != chatstates_xso.ChatState.ACTIVE: raise ValueError( "Only the state ACTIVE can be sent with messages." ) elif self._state == state: return False self._state = state return self._strategy.sending
[docs] def no_reply(self): """ Call this method if the peer did not include a chat state notification. """ self._strategy.no_reply()
[docs] def reset(self): """ Call this method on connection reset. """ self._strategy.reset()