irc3

repository·main·Indexed 42 days ago

https://github.com/gawel/irc3

A pluggable IRC client library based on asyncio with DCC and SASL support. Designed for developers building asynchronous IRC clients or bots, it provides high-level abstractions like the IrcBot class, a plugin system with @plugin and @event decorators, and low-level communication via IrcConnection. Version 1.1.13.dev0 includes support for DCC file transfers, IRC reply (RPL) and error (ERR) event handling, and a template module for quick bot scaffolding.

Tokens
16.7K
Snippets
59
Records
75
Agent score
52%

What's inside irc3

  1. Manage configuration with Config and parse_config

    main

    The irc3.utils module provides tools for handling library configuration:

    • Config: A class for managing configuration state.
    • parse_config: A function to parse configuration data.
    • extract_config: A function to extract configuration settings.
  2. Handle IRC Replies (RPL) using @irc3.event

    main

    In irc3, IRC replies (RPL) are handled as events. You can respond to specific numeric replies by using the @irc3.event decorator with the corresponding constant from irc3.rfc.

    When an event is triggered, the decorated function receives the bot instance as the first argument, followed by the parsed components of the IRC message as keyword arguments. The specific keyword arguments available depend on the format of the reply being matched.

    from irc3 import event
    from irc3.rfc import RPL_WHOREPLY
    
    @event(RPL_WHOREPLY)
    def myevent(bot, srv=None, me=None, channel=None, username=None, host=None, server=None, nick=None, modes=None, data=None):
        # do something
  3. Handle IRC Error (ERR) events

    main

    In irc3, IRC error messages (ERR) are exposed as events via the irc3.event decorator. You can listen for specific error codes by referencing the corresponding constant in irc3.rfc.

    When an error event is triggered, the decorated function receives the bot instance and several keyword arguments parsed from the IRC message, such as srv (the server), me (your nickname), channel, nick, or data (the trailing message text), depending on the specific error's format.

    @irc3.event(rfc.ERR_BADCHANNELKEY)
    def myevent(bot, srv=None, me=None, channel=None, data=None):
        # Handle the error (e.g., 475 - ERR_BADCHANNELKEY)
        pass
  4. Implement reloadable plugins in irc3

    main

    To allow a plugin to be reloaded without restarting the entire bot, the plugin class must implement a reload class method. This method is responsible for taking the old instance and returning a new, ready-to-use instance of the newly loaded class.

    Additionally, you can implement lifecycle hooks to manage state or cleanup during the reload process:

    • before_reload(self): Executed before the old plugin instance is replaced.
    • after_reload(self): Executed after the new plugin instance is initialized.
    class Plugin(object):
        def __init__(self, bot):
            self.bot = bot
    
        @classmethod
        def reload(cls, old):
            """this method should return a ready to use plugin instance.
            cls is the newly reloaded class. old is the old instance.
            """
            return cls(old.bot)
    
        def before_reload(self):
            """Do stuff before reload"""
            pass
    
        def after_reload(self):
            """Do stuff after reload"""
            pass
  5. Use hupper for development restarts

    main

    If you prefer to restart the entire bot whenever a file changes during development instead of using irc3's internal plugin reloading, you can use the hupper package.

    1. Install hupper: pip install hupper

    2. Run your bot via hupper: hupper -m irc3 config.ini

    $ pip install hupper
    $ hupper -m irc3 config.ini
  6. Quick start: Create a bot using the irc3 template

    main

    To quickly scaffold a new bot, use the irc3.template module. This creates a directory containing a config.ini file and a sample plugin (mybot_plugin.py) that includes an echo command and a join greeting.

    1. Create and enter a new directory:
      $ mkdir mybot
      $ cd mybot
    2. Run the template generator:
      $ python -m irc3.template mybot
    3. Configure the bot by editing the generated config.ini:
      • Set the autojoin channel.
      • Update your IRC mask in the [irc3.plugins.command.mask] section.
    4. Run the bot:
      $ irc3 config.ini
    $ mkdir mybot
    $ cd mybot
    $ python -m irc3.template mybot
    $ irc3 config.ini
  7. Install irc3

    main

    irc3 is a pluggable IRC client library based on Python's asyncio. It requires Python 3.11 or higher.

    To install the latest version:

    pip install irc3

    If you are constrained to an older environment and cannot use Python 3.11+, you can install a legacy version (pre-0.9) that supports older Python versions:

    pip install "irc3<0.9"
  8. Understand the DCCBase lifecycle and state

    main

    DCCBase is the abstract base class for all DCC implementations. It inherits from asyncio.Protocol and manages the connection state using asyncio.Future objects.

    State Futures:

    • ready: Resolved when the connection is ready.
    • started: Resolved when connection_made is called.
    • closed: Resolved when the connection is terminated.

    Lifecycle Methods:

    • connection_made(transport): Called when the connection is established. Sets the started future.
    • connection_lost(exc): Called when the connection is lost; triggers close().
    • close(result=None): Cleans up resources, cancels idle timeouts, closes the transport, and updates the bot's internal connection tracking (decrementing total and removing the mask/port from the bot's registry).
  9. Manage plugins and event registration with Registry

    main

    The Registry class manages the lifecycle of plugins and the mapping of regex-based events.

    • Plugins: Managed via IrcObject.get_plugin(ob) and IrcObject.include(*modules). Plugins are instantiated with the IrcObject instance passed to them.
    • Events: Events are attached to the bot using IrcObject.attach_events(*events, **kwargs).
      • iotype determines if the event is 'in' (incoming) or 'out' (outgoing).
      • Use insert=True in attach_events to prioritize the event (placing it at the start of the match list).
    • Reloading: IrcObject.reload(*modules) allows for hot-reloading plugins and configuration files without restarting the process.
  10. Send files via DCC using irc3.IrcBot methods

    main

    You can interact with DCC (Direct Client-to-Client) features through the IrcBot instance. The primary methods available are:

    • dcc_chat: Initiates a DCC chat.
    • dcc_get: Initiates a DCC file transfer (download).
    • dcc_send: Initiates a DCC file transfer (upload).

    Below is a pattern for a simple plugin that sends a generated file using dcc_send.

    # Example plugin pattern for sending a file
    # Based on ../examples/dcc_send.py
    
    # Note: The actual implementation details are in the example file,
    # but the core mechanism uses self.dcc_send(nick, filename)
  11. Use the irc3.plugins.command plugin

    main

    The irc3.plugins.command plugin provides basic administrative and utility commands.

    • !help [<cmd>]: Displays help information. You can optionally specify a command name to get details about that specific command.
    • !ping: Performs a ping/pong check.

    Note: !ping requires admin permission and is only available in private channels.

    !help [<cmd>]
    !ping