irclib: Document classes better, especially instance attributes.

This commit is contained in:
Valentin Lorentz 2020-09-27 15:24:27 +02:00
parent 38b0541f04
commit 48b24769c2
1 changed files with 224 additions and 0 deletions

View File

@ -301,6 +301,58 @@ class IrcMsgQueue(object):
# status of various modes (especially ops/halfops/voices) in channels, etc. # status of various modes (especially ops/halfops/voices) in channels, etc.
### ###
class ChannelState(utils.python.Object): class ChannelState(utils.python.Object):
"""Represents the known state of an IRC channel.
.. attribute:: topic
The topic of a channel (possibly the empty stringà
:type: str
.. attribute:: created
Timestamp of the channel creation, according to the server.
:type: int
.. attribute:: ops
Set of the nicks of all the operators of the channel.
:type: ircutils.IrcSet[str]
.. attribute:: halfops
Set of the nicks of all the half-operators of the channel.
:type: ircutils.IrcSet[str]
.. attribute:: voices
Set of the nicks of all the voiced users of the channel.
:type: ircutils.IrcSet[str]
.. attribute:: users
Set of the nicks of all the users in the channel.
:type: ircutils.IrcSet[str]
.. attribute:: bans
Set of the all the banmasks set in the channel.
:type: ircutils.IrcSet[str]
.. attribute:: modes
Dict of all the modes set in the channel, with they value, if any.
This excludes the following modes: ovhbeq
:type: Dict[str, Optional[str]]
"""
__slots__ = ('users', 'ops', 'halfops', 'bans', __slots__ = ('users', 'ops', 'halfops', 'bans',
'voices', 'topic', 'modes', 'created') 'voices', 'topic', 'modes', 'created')
def __init__(self): def __init__(self):
@ -314,16 +366,27 @@ class ChannelState(utils.python.Object):
self.modes = {} self.modes = {}
def isOp(self, nick): def isOp(self, nick):
"""Returns whether the given nick is an op."""
return nick in self.ops return nick in self.ops
def isOpPlus(self, nick): def isOpPlus(self, nick):
"""Returns whether the given nick is an op."""
return nick in self.ops return nick in self.ops
def isVoice(self, nick): def isVoice(self, nick):
"""Returns whether the given nick is voiced."""
return nick in self.voices return nick in self.voices
def isVoicePlus(self, nick): def isVoicePlus(self, nick):
"""Returns whether the given nick is voiced, an halfop, or an op."""
return nick in self.voices or nick in self.halfops or nick in self.ops return nick in self.voices or nick in self.halfops or nick in self.ops
def isHalfop(self, nick): def isHalfop(self, nick):
"""Returns whether the given nick is an halfop."""
return nick in self.halfops return nick in self.halfops
def isHalfopPlus(self, nick): def isHalfopPlus(self, nick):
"""Returns whether the given nick is an halfop, or an op."""
return nick in self.halfops or nick in self.ops return nick in self.halfops or nick in self.ops
def addUser(self, user): def addUser(self, user):
@ -412,7 +475,11 @@ class ChannelState(utils.python.Object):
ret = ret and getattr(self, name) == getattr(other, name) ret = ret and getattr(self, name) == getattr(other, name)
return ret return ret
Batch = collections.namedtuple('Batch', 'type arguments messages') Batch = collections.namedtuple('Batch', 'type arguments messages')
"""Represents a batch of messages, see
<https://ircv3.net/specs/extensions/batch-3.2>"""
class IrcStateFsm(object): class IrcStateFsm(object):
'''Finite State Machine keeping track of what part of the connection '''Finite State Machine keeping track of what part of the connection
@ -421,6 +488,8 @@ class IrcStateFsm(object):
@enum.unique @enum.unique
class States(enum.Enum): class States(enum.Enum):
"""Enumeration of all the states of an IRC connection."""
UNINITIALIZED = 10 UNINITIALIZED = 10
'''Nothing received yet (except server notices)''' '''Nothing received yet (except server notices)'''
@ -534,8 +603,84 @@ class IrcStateFsm(object):
class IrcState(IrcCommandDispatcher, log.Firewalled): class IrcState(IrcCommandDispatcher, log.Firewalled):
"""Maintains state of the Irc connection. Should also become smarter. """Maintains state of the Irc connection. Should also become smarter.
.. attribute:: fsm
A finite-state machine representing the current state of the IRC
connection: various steps while connecting, then remains in the
CONNECTED state (or CONNECTED_SASL when doing SASL in the middle of a
connection).
:type: IrcStateFsm
.. attribute:: capabilities_req
Set of all capabilities requested from the server.
See <https://ircv3.net/specs/core/capability-negotiation>
:type: Set[str]
.. attribute:: capabilities_acq
Set of all capabilities requested from and acknowledged by the
server. See <https://ircv3.net/specs/core/capability-negotiation>
:type: Set[str]
.. attribute:: capabilities_nak
Set of all capabilities requested from and refused by the server.
This should always be empty unless the bot, a plugin, or the server is
misbehaving. See <https://ircv3.net/specs/core/capability-negotiation>
:type: Set[str]
.. attribute:: capabilities_ls
Stores all the capabilities advertised by the server, as well as their
value, if any.
:type: Dict[str, Optional[str]]
.. attribute:: ircd
Identification string of the software running the server we are
connected to. See
<https://defs.ircdocs.horse/defs/numerics.html#rpl-myinfo-004>
:type: str
.. attribute:: supported
Stores the value of ISUPPORT sent when connecting.
See <https://defs.ircdocs.horse/defs/isupport.html> for the list of
keys.
:type: utils.InsensitivePreservingDict[str, Any]
.. attribute:: history
History of messages received from the network. Automatically discards
messages so it doesn't exceed
``supybot.protocols.irc.maxHistoryLength``.
:type: RingBuffer[ircmsgs.IrcMsg]
.. attribute:: channels
Store channel states.
:type: ircutils.IrcDict[str, ChannelState]
.. attribute:: nickToHostmask
Stores the last hostmask of a seen nick.
:type: ircutils.IrcDict[str, str]
""" """
__firewalled__ = {'addMsg': None} __firewalled__ = {'addMsg': None}
def __init__(self, history=None, supported=None, def __init__(self, history=None, supported=None,
nicksToHostmasks=None, channels=None, nicksToHostmasks=None, channels=None,
capabilities_req=None, capabilities_req=None,
@ -899,6 +1044,76 @@ class Irc(IrcCommandDispatcher, log.Firewalled):
"""The base class for an IRC connection. """The base class for an IRC connection.
Handles PING commands already. Handles PING commands already.
.. attribute:: zombie
Whether or not this object represents a living IRC connection.
:type: bool
.. attribute:: network
The name of the network this object is connected to.
:type: str
.. attribute:: startedAt
When this connection was (re)started.
:type: float
.. attribute:: callbacks
List of all callbacks (ie. plugins) currently loaded
:type: List[IrcCallback]
.. attribute:: queue
Queue of messages waiting to be sent. Plugins should use the
``queueMsg`` method instead of accessing this directly.
:type: IrcMsgQueue
.. attribute:: fastqueue
Same as ``queue``, but for messages with high priority. Plugins should
use the ``sendMsg`` method instead of accessing this directly (or
`queueMsg` if the message isn't high priority).
:type: smallqueue
.. attribute:: driver
Driver of the IRC connection (normally, a
:py:class:`supybot.drivers.Socket.SocketDriver` object).
Plugins normally do not need to access this.
.. attribute:: startedSync
When joining a channel, a ``'#channel': time.time()`` entry is added
to this dict, which is then removed when the join is completed.
Plugins should not change this value, it is automatically handled when
they send a JOIN.
:type: ircutils.IrcDict[str, float]
.. attribute:: monitoring
A dict with nicks as keys and the number of plugins monitoring this
nick as value.
Plugins should not access this directly, and should use the ``monitor``
and ``unmonitor`` methods instead.
:type: ircutils.IrcDict[str, int]
.. attribute:: state
An :py:class:`supybot.irclib.IrcState` object, which stores all the
known information about the connection with the IRC network.
:type: supybot.irclib.IrcState
""" """
__firewalled__ = {'die': None, __firewalled__ = {'die': None,
'feedMsg': None, 'feedMsg': None,
@ -934,6 +1149,9 @@ class Irc(IrcCommandDispatcher, log.Firewalled):
return ircutils.isChannel(s, **kw) return ircutils.isChannel(s, **kw)
def isNick(self, s): def isNick(self, s):
"""Returns whether the given argument is a valid nick on this
network.
"""
kw = {} kw = {}
if 'nicklen' in self.state.supported: if 'nicklen' in self.state.supported:
kw['nicklen'] = self.state.supported['nicklen'] kw['nicklen'] = self.state.supported['nicklen']
@ -1295,6 +1513,12 @@ class Irc(IrcCommandDispatcher, log.Firewalled):
'userhost-in-names', 'invite-notify', 'server-time', 'userhost-in-names', 'invite-notify', 'server-time',
'chghost', 'batch', 'away-notify', 'message-tags', 'chghost', 'batch', 'away-notify', 'message-tags',
'msgid', 'setname', 'labeled-response', 'echo-message']) 'msgid', 'setname', 'labeled-response', 'echo-message'])
"""IRCv3 capabilities requested when they are available.
echo-message is special-cased to be requested only with labeled-response.
To check if a capability was negotiated, use `irc.state.capabilities_ack`.
"""
def _queueConnectMessages(self): def _queueConnectMessages(self):
if self.zombie: if self.zombie: