numberoverzero / bottom

asyncio-based rfc2812-compliant IRC Client
http://bottom-docs.readthedocs.io
MIT License
76 stars 23 forks source link

Add an event for nickname change #31

Closed yuvallanger closed 8 years ago

yuvallanger commented 8 years ago

Sometimes a server might change a user's nickname. Right now I have no way of telling if the nickname was changed.

I've used this to print each and every event I get:

def handle_logging(session):
    for event in [
        'CLIENT_CONNECT',
        'JOIN',
        'NOTICE',
        'PART',
        'PING',
        'PRIVMSG',
        'RPL_BOUNCE',
        'RPL_CREATED',
        'RPL_ENDOFMOTD',
        'RPL_LUSERCHANNELS',
        'RPL_LUSERCLIENT',
        'RPL_LUSERME',
        'RPL_LUSEROP',
        'RPL_LUSERUNKNOWN',
        'RPL_MOTD',
        'RPL_MOTDSTART',
        'RPL_MYINFO',
        'RPL_WELCOME',
        'RPL_YOURHOST',
    ]:
        session.bot.on(
            event,
            lambda **kwargs: print(
                '{}: {} {}'.format(
                    arrow.utcnow(),
                    event,
                    kwargs,
                )))

None of the events were a nickname change event, just a RPL_YOURHOST warning me that I have 30 seconds to change my nickname and 30 seconds later RPL_YOURHOST telling me that it'll change my nickname. Nothing standard.

Many thanks!

numberoverzero commented 8 years ago

Just want to make sure I understand:

If that's correct, it sounds like there's a response coming in that bottom hasn't implemented unpacking for. Unhandled commands are caught here, and logged at debug.

Can you please enable logging at the debug level and update with the specific reply that isn't handled?

import asyncio
import bottom

# Use an explicit loop with debug logging
loop = asyncio.get_event_loop()
loop.set_debug(True)

# Pass that loop to your bot
bot = bottom.Client(..., loop=loop)

# Enable debug-level logging wherever you're running your bot from
# Assuming it's at the bottom of the file, it'd be:
if __name__ == "__main__":
    import logging
    logging.basicConfig(level=logging.DEBUG)

You should see a message like:

Failed to parse line >>> [IRC WIRE FORMAT HERE]
yuvallanger commented 8 years ago

You are correct. The whole output:

2016-08-04T19:17:03.332661+00:00: RPL_YOURHOST {'host': 'services.', 'target': 'sufganya', 'nick': 'NickServ', 'user': 'NickServ', 'message': 'This nickname is registered. Please choose a different nickname, or identify via \x02/msg NickServ identify <password>\x02.'}
2016-08-04T19:17:03.332954+00:00: RPL_YOURHOST {'host': 'services.', 'target': 'sufganya', 'nick': 'NickServ', 'user': 'NickServ', 'message': 'You have 30 seconds to identify to your nickname before it is changed.'}
2016-08-04T19:17:08.326469+00:00: RPL_YOURHOST {'nick': 'sufganya', 'host': '141.226.161.4', 'user': '~sufganya', 'channel': '#sufganya'}
2016-08-04T19:17:34.098061+00:00: RPL_YOURHOST {'host': 'services.', 'target': 'sufganya', 'nick': 'NickServ', 'user': 'NickServ', 'message': 'You failed to identify in time for the nickname sufganya'}
DEBUG:bottom:Failed to parse line >>> :sufganya!~sufganya@141.226.161.4 NICK :Guest88253
numberoverzero commented 8 years ago

Re-checked the RFC, and indeed NICK is also a response from the server:

3.1.2 Nick message

      Command: NICK
   Parameters: <nickname>

   NICK command is used to give user a nickname or change the existing
   one.

Kalt                         Informational                     [Page 10]

RFC 2812          Internet Relay Chat: Client Protocol        April 2000

   Numeric Replies:

           ERR_NONICKNAMEGIVEN             ERR_ERRONEUSNICKNAME
           ERR_NICKNAMEINUSE               ERR_NICKCOLLISION
           ERR_UNAVAILRESOURCE             ERR_RESTRICTED

   Examples:

   NICK Wiz                ; Introducing new nick "Wiz" if session is
                           still unregistered, or user changing his
                           nickname to "Wiz"

   :WiZ!jto@tolsun.oulu.fi NICK Kilroy
                           ; Server telling that WiZ changed his
                           nickname to Kilroy.

Because "nick" is part of the nickmask that's unpacked, we'll need a different key for the new nickname. "new_nick" could work - ideally something that won't overlap in meaning, so it can be used consistently throughout all of the events.

Do you want to take a shot at fixing it? There's some prior art that should make the change pretty easy to work through.

If not, (which is fine) I'll add it to unpack.py in a bit, and probably have a 1.0.3 release in an hour or two.


Thanks for opening an issue! Please continue to do so for any other missing commands you find. The wire log is extremely helpful.

yuvallanger commented 8 years ago

It is late, I won't be able to make it.

numberoverzero commented 8 years ago

bottom 1.0.3 is out with support for NICK. The new nickname is under the kwarg new_nick.

Thanks again for opening an issue!