numberoverzero / bottom

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

Feature Request: send raw commands #32

Closed DACRepair closed 7 years ago

DACRepair commented 8 years ago

Add a "raw" command type. such as: bot.send('RAW', message='<server specific command / non-rfc2812 command here>') Have it sort of a "use at your own peril" sort of thing (meaning there would be no error handling, just dump the raw error message out).

IE: pack.py:

elif command == "RAW":
    return "{}".format(f("message", kwargs))

I totally understand the concept that this would circumvent the whole "doing commands as routes",, but this could make it simpler for those of use that have extended upon the original library for functionality of non-standardized operations within a specific IRC server.

numberoverzero commented 8 years ago

Thanks for opening an issue!

This seems totally reasonable; there are probably a lot of custom extensions that don't fit into the available send commands. It can also be useful for any dynamic message creation, or custom formatting.

I'm not sure about the exact syntax, so I want to roll that around for a bit. I prefer to have it more clearly delineated from send, than just using a different string. It should be immediately obvious that I'm not using the defined commands anymore.

This might be the feature request that opens the door for more general command extension. That is, a way to hook up custom functions in between receiving the wire bytes and emitting a signal. And finally replacing the eyesore that is pack.py/unpack.py

On Aug 30, 2016 6:20 PM, "DACRepair" notifications@github.com wrote:

Add a "raw" command type. such as: bot.send('RAW', message='<server specific command / non-rfc2812 command here>') Have it sort of a "use at your own peril" sort of thing (meaning there would be no error handling, just dump the raw error message out).

pack.py:

elif command == "RAW": return "{}".format(f("message", kwargs))

I totally understand the concept that this would circumvent the whole "doing commands as routes",, but this could make it simpler for those of use that have extended upon the original library for functionality of non-standardized operations within a specific IRC server.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/numberoverzero/bottom/issues/32, or mute the thread https://github.com/notifications/unsubscribe-auth/ABKsgeasG2TVYjotjLp7Qbu0HSloifZVks5qlNbEgaJpZM4JxI3- .

numberoverzero commented 7 years ago

Finally found some free time, I'm working on this now. Sorry it's been so long.

Plan for new interface:

Client.raw_handlers: List[Function[[bytes], bool]]
Client.send_raw(AnyStr) -> None

The existing unpacking behavior will be moved into a raw handler, and by default is hooked up during client __init__. This preserves behavior and covers the 99% use-case. If someone wants to disconnect the usual IRC signals they can simply remove it from the raw_handlers list.

Most users will want to put new handlers before existing handlers, so it's tempting to iterate raw_handlers in reverse so that raw_handlers.append matches the common intent. Alternatively, forcing raw_handlers.insert(my_new_handler, 0) is more explicit.

I'll try to have a branch up this weekend.