irc3.plugins.command Command plugin

Introduce a @command decorator

The decorator use docopts to parse command arguments.

Usage

Create a python module with some commands:

# -*- coding: utf-8 -*-
from irc3.plugins.command import command


@command
def echo(bot, mask, target, args):
    """Echo command

        %%echo <words>...
    """
    yield ' '.join(args['<words>'])


@command(permission='admin', public=False)
def adduser(bot, mask, target, args):
    """Add a user

        %%adduser <name> <password>
    """
    bot.privmsg(mask.nick, 'User added')


@command(show_in_help_list=False)
def my_secret_operation(bot, mask, target, args):
    """Do something you don't want in !help all the time

        %%my_secret_operation
    """
    yield "I like turtles"

And register it:

>>> bot = IrcBot()
>>> bot.include('irc3.plugins.command')  # register the plugin
>>> bot.include('mycommands')            # register your commands

Check the result:

>>> bot.test(':gawel!user@host PRIVMSG #chan :!echo foo')
PRIVMSG #chan :foo

In the docstring, %% is replaced by the command character. ! by default. You can override it by passing a cmd parameter to bot’s config.

When a command is not public, you can’t use it on a channel:

>>> bot.test(':gawel!user@host PRIVMSG #chan :!adduser foo pass')
PRIVMSG gawel :You can only use the 'adduser' command in private.

If a command is tagged with show_in_help_list=False, it won’t be shown on the result of !help.

>>> bot.test(':gawel!user@host PRIVMSG #chan :!help')
PRIVMSG #chan :Available commands: !adduser, !echo, !help

View extra info about a command by specifying it to !help.

>>> bot.test(':gawel!user@host PRIVMSG #chan :!help echo')
PRIVMSG #chan :Echo command
PRIVMSG #chan :!echo <words>...
>>> bot.test(':gawel!user@host PRIVMSG #chan :!help nonexistant')
PRIVMSG #chan :No such command. Try !help for an overview of all commands.

Guard

You can use a guard to prevent untrusted users to run some commands. The free_policy is used by default.

There is two builtin policy:

class irc3.plugins.command.free_policy(bot)[source]

Default policy

class irc3.plugins.command.mask_based_policy(bot)[source]

Allow only valid masks. Able to take care or permissions

Mask based guard using permissions:

>>> config = ini2config("""
... [bot]
... nick = nono
... includes =
...     irc3.plugins.command
...     mycommands
... [irc3.plugins.command]
... guard = irc3.plugins.command.mask_based_policy
... [irc3.plugins.command.masks]
... gawel!*@* = all_permissions
... foo!*@* = help
... """)
>>> bot = IrcBot(**config)

foo is allowed to use command without permissions:

>>> bot.test(':foo!u@h PRIVMSG nono :!echo got the power')
PRIVMSG foo :got the power

foo is not allowed to use command except those with the help permission:

>>> bot.test(':foo!u@h PRIVMSG nono :!ping')
PRIVMSG foo :You are not allowed to use the 'ping' command

gawel is allowed:

>>> bot.test(':gawel!u@h PRIVMSG nono :!ping')
NOTICE gawel :PONG gawel!

Async commands

Commands can be coroutines:

# -*- coding: utf-8 -*-
from irc3.plugins.command import command
from irc3.compat import Queue
import irc3


@irc3.plugin
class AsyncCommands(object):
    """Async commands example. This is what it's look like on irc::

        <gawel> !get
        <gawel> !put item
        <irc3> items added to queue
        <irc3> item
    """

    def __init__(self, bot):
        self.bot = bot
        self.queue = Queue()

    @command
    def put(self, mask, target, args):
        """Put items in queue

            %%put <words>...
        """
        for w in args['<words>']:
            self.queue.put_nowait(w)
        yield 'items added to queue'

    @command
    async def get(self, mask, target, args):
        """Async get items from the queue

            %%get
        """
        messages = []
        message = await self.queue.get()
        messages.append(message)
        while not self.queue.empty():
            message = await self.queue.get()
            messages.append(message)
        return messages

Available options

The plugin accept the folowing options:

[irc3.plugins.command]
cmd = !
use_shlex = true
antiflood = true
casesensitive = true
guard = irc3.plugins.command.mask_based_policy

Command arguments

The command() decorator accept the folowing arguments:

name: if set, use this name as the command name instead of the function name.

permission: if set, this permission will be required to run the command. See Guard section

use_shlex: if False, do not use shlex to parse command line.

options_first: if True use docopt’s options_first options. Allow to have args that starts with - as arguments.

error_format: allow to customize error messages. must be a callable that accept keyword arguments cmd, args and exc. For example, error_format=”Error for {cmd}”.format will work.

quiet: if True don’t show errors