diff --git a/docs/module_guide/_module_guide.rst b/docs/module_guide/_module_guide.rst index e1241c3..e382906 100644 --- a/docs/module_guide/_module_guide.rst +++ b/docs/module_guide/_module_guide.rst @@ -13,7 +13,7 @@ file's name. .. code-block:: python - from pyircbot.modulebase import ModuleBase, hook + from pyircbot.modulebase import ModuleBase, hook, command class EchoExample(ModuleBase): The class's ``__init__`` method accepts 2 args - a reference to the bot's API @@ -47,7 +47,7 @@ In order to make your module respond to various IRC commands, pyircbot uses a system of "hooks", which can be defined using decorators or programmatically. Note: in this case, "commands" refers to IRC protocol commands such as PRIVMSG, KICK, JOIN, etc. Pyircbot also provides some meta-events that are accessed in -the same way. The complete list of supported commands can be seen in the source +the same way. The complete list of supported hooks can be seen in the source of :py:meth:`pyircbot.irccore.IRCCore.initHooks`. The easiest method is to use the ``hook`` decorator on any function your want @@ -59,7 +59,7 @@ called when an IRC command is received. def echo(self, event): The handler is passed and IRCEvent object containing the data sent by the irc -server. The values of these are can vary, but the format is alwaysthe same. +server. The values of these are can vary, but the format is always the same. ``event.args`` is the list of arguments the IRC server sent. ``event.prefix`` is the sender, parsed. ``trailing`` is arbitrary data associated @@ -83,6 +83,17 @@ Since the module described above echos messages, let's do that: This sends a PRIVMSG to the originating channel or nick, with the same msg content that was received. +Alternatively, if your module needs to respond to chat-based commands, a +similar decorator :py:class:`pyircbot.modulebase.command`. can be used: + +.. code-block:: python + + @command("echo") + def echo2(self, cmd, msg): + # If the message was ".echo bob asdf", cmd.args would look like: + # ["bob", "asdf"] + self.bot.act_PRIVMSG(msg.args[0], msg.trailing) + Beyond this, a module's class can import or do anything python can to deliver responses. For modules that use threads or connect to external services, a shutdown handler is needed to ensure a clean shutdown. diff --git a/pyircbot/modulebase.py b/pyircbot/modulebase.py index f123591..e9739c0 100644 --- a/pyircbot/modulebase.py +++ b/pyircbot/modulebase.py @@ -120,21 +120,23 @@ ATTR_COMMAND_HOOK = "__tag_commands" class hook(object): """ Decorator for calling module methods in response to IRC actions. Example: - ``` - @hook("PRIVMSG") - def mymyethod(self, message): - print("IRC server sent PRIVMSG") - ``` + + .. code-block:: python + + @hook("PRIVMSG") + def mymyethod(self, message): + print("IRC server sent PRIVMSG") + This stores a list of IRC actions each function is tagged for in method.__tag_hooks. This attribute is scanned during module init and appropriate hooks are set up. + + :param args: irc protocol event to listen for. See :py:meth:`pyircbot.irccore.IRCCore.initHooks` for a complete list + :type args: str """ def __init__(self, *args): self.commands = args def __call__(self, func): - """ - - """ if not hasattr(func, ATTR_ACTION_HOOK): setattr(func, ATTR_ACTION_HOOK, list(self.commands)) else: @@ -159,16 +161,29 @@ class irchook(object): class command(irchook): """ - Decorating for calling module methods in response to IRC actions. Example: - ``` - @hook("PRIVMSG") - def mymyethod(self, message): - print("IRC server sent PRIVMSG") - ``` - This stores a list of IRC actions each function is tagged for in method.__tag_hooks. This attribute is scanned + Decorator for calling module methods when a command is parsed from chat + + .. code-block:: python + + @command("ascii") + def cmd_ascii(self, cmd, msg): + print("Somebody typed .ascii with params {} in channel {}".format(str(cmd.args), msg.args[0])) + + This stores a list of IRC actions each function is tagged for in method.__tag_commands. This attribute is scanned during module init and appropriate hooks are set up. + + :param keywords: commands to listen for + :type keywords: str + :param require_args: only match if trailing data is passed with the command used + :type require_args: bool + :param allow_private: enable matching in private messages + :type allow_private: bool """ + prefix = "." + """ + Hotkey that must appear before commands + """ def __init__(self, *keywords, require_args=False, allow_private=False): self.keywords = keywords @@ -177,12 +192,23 @@ class command(irchook): self.parsed_cmd = None def call(self, method, msg): + """ + Internal use. Triggers the hooked function + """ if len(getargspec(method).args) == 3: - method(self.parsed_cmd, msg) + return method(self.parsed_cmd, msg) else: - method(self.parsed_cmd) + return method(self.parsed_cmd) def validate(self, msg, bot): + """ + Test a message and return true if matched. + + :param msg: message to test against + :type msg: pyircbot.irccore.IRCEvent + :param bot: reference to main pyircbot + :type bot: pyircbot.pyircbot.PyIRCBot + """ if not self.allow_private and msg.args[0] == "#": return False for keyword in self.keywords: