diff --git a/sopel/coretasks.py b/sopel/coretasks.py index 621e8fb65f..bbdd243ec0 100644 --- a/sopel/coretasks.py +++ b/sopel/coretasks.py @@ -38,7 +38,9 @@ LOGGER = logging.getLogger(__name__) -CORE_QUERYTYPE = '999' +WHOX_QUERY = '%nuachrtf' +"""List of WHOX flags coretasks requests.""" +WHOX_QUERYTYPE = '999' """WHOX querytype to indicate requests/responses from coretasks. Other plugins should use a different querytype. @@ -783,12 +785,12 @@ def _remove_from_channel(bot, nick, channel): def _send_who(bot, channel): if 'WHOX' in bot.isupport: # WHOX syntax, see http://faerion.sourceforge.net/doc/irc/whox.var - # Needed for accounts in WHO replies. The `CORE_QUERYTYPE` parameter + # Needed for accounts in WHO replies. The `WHOX_QUERYTYPE` parameter # for WHO is used to identify the reply from the server and confirm # that it has the requested format. WHO replies with different # querytypes in the response were initiated elsewhere and will be # ignored. - bot.write(['WHO', channel, 'a%nuachtf,' + CORE_QUERYTYPE]) + bot.write(['WHO', channel, ','.join(WHOX_QUERY, WHOX_QUERYTYPE)]) else: # We might be on an old network, but we still care about keeping our # user list updated @@ -1391,21 +1393,21 @@ def account_notify(bot, trigger): @plugin.priority('medium') def recv_whox(bot, trigger): """Track ``WHO`` responses when ``WHOX`` is enabled.""" - if len(trigger.args) < 2 or trigger.args[1] != CORE_QUERYTYPE: + if len(trigger.args) < 2 or trigger.args[1] != WHOX_QUERYTYPE: # Ignored, some plugin probably called WHO LOGGER.debug("Ignoring WHO reply for channel '%s'; not queried by coretasks", trigger.args[1]) return - if len(trigger.args) != 8: + if len(trigger.args) != len(WHOX_QUERY): LOGGER.warning( "While populating `bot.accounts` a WHO response was malformed.") return - _, _, channel, user, host, nick, status, account = trigger.args + _, _, channel, user, host, nick, status, account, realname = trigger.args away = 'G' in status modes = ''.join([c for c in status if c in '~&@%+!']) - _record_who(bot, channel, user, host, nick, account, away, modes) + _record_who(bot, channel, user, host, nick, realname, account, away, modes) -def _record_who(bot, channel, user, host, nick, account=None, away=None, modes=None): +def _record_who(bot, channel, user, host, nick, realname=None, account=None, away=None, modes=None): nick = bot.make_identifier(nick) channel = bot.make_identifier(channel) if nick not in bot.users: @@ -1418,6 +1420,8 @@ def _record_who(bot, channel, user, host, nick, account=None, away=None, modes=N usr.host = host if usr.user is None and user: usr.user = user + if realname: + usr.realname = realname if account == '0': usr.account = None else: @@ -1452,9 +1456,10 @@ def _record_who(bot, channel, user, host, nick, account=None, away=None, modes=N def recv_who(bot, trigger): """Track ``WHO`` responses when ``WHOX`` is not enabled.""" channel, user, host, _, nick, status = trigger.args[1:7] + realname = trigger.args[-1].partition(' ')[-1] away = 'G' in status modes = ''.join([c for c in status if c in '~&@%+!']) - _record_who(bot, channel, user, host, nick, away=away, modes=modes) + _record_who(bot, channel, user, host, nick, realname, away=away, modes=modes) @plugin.event('AWAY') diff --git a/sopel/tools/target.py b/sopel/tools/target.py index cb8209112b..15ef8bf0bf 100644 --- a/sopel/tools/target.py +++ b/sopel/tools/target.py @@ -23,7 +23,7 @@ class User: :param str host: the user's hostname ("host.name" in `user@host.name`) """ __slots__ = ( - 'nick', 'user', 'host', 'channels', 'account', 'away', + 'nick', 'user', 'host', 'realname', 'channels', 'account', 'away', ) def __init__( @@ -39,6 +39,11 @@ def __init__( """The user's local username.""" self.host = host """The user's hostname.""" + self.realname = None + """The user's realname. + + Will be ``None`` if not received from the server yet. + """ self.channels: Dict[identifiers.Identifier, 'Channel'] = {} """The channels the user is in.