Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.viewcode',
'sphinx_autodoc_annotation',
]

# Add any paths that contain templates here, relative to this directory.
Expand Down
4 changes: 1 addition & 3 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
sphinx>=1.2

sphinx-autodoc-annotation
sphinx>=8.2.3

-e .
hypchat
Expand Down
130 changes: 130 additions & 0 deletions docs/user_guide/plugin_development/command_parameters.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
Command Parameters
==================

This page explains how to handle command parameters in Errbot plugins, including default values, argument parsing, and best practices.

Basic Command Parameters
------------------------

The most basic form of a bot command takes a message object and arguments:

.. code-block:: python

@botcmd
def hello(self, msg, args):
return f"Hello! You said: {args}"

In this case, ``msg`` is the message object containing information about who sent the command and where, and ``args`` is a string containing everything after the command.

Default Values
--------------

You can provide default values for command parameters. This is useful when you want to make certain arguments optional:

.. code-block:: python

@botcmd
def echo(self, msg, args="default message"):
return f"You said: {args}"

In this example, if someone calls the command without arguments, ``args`` will be set to "default message".

.. note::
Default values work for both the ``msg`` and ``args`` parameters. However, it's recommended to only use default values for ``args`` as the ``msg`` parameter is typically required for proper command handling.

Argument Splitting
------------------

You can automatically split arguments into a list using the ``split_args_with`` parameter:

.. code-block:: python

@botcmd(split_args_with=None) # Split on any whitespace
def count(self, msg, args):
# If user types: !count one two three
# args will be ['one', 'two', 'three']
return f"You provided {len(args)} arguments"

The ``split_args_with`` parameter works exactly like Python's ``str.split()``. Common values are:

- ``None``: Split on any whitespace (recommended for most cases)
- ``' '``: Split on single spaces only
- ``','``: Split on commas
- ``'|'``: Split on pipe characters

Advanced Argument Parsing
-------------------------

For more complex argument parsing, you can use the ``arg_botcmd`` decorator which provides argparse-style argument handling:

.. code-block:: python

@arg_botcmd('name', type=str)
@arg_botcmd('--count', dest='repeat', type=int, default=1)
def repeat(self, msg, name=None, repeat=None):
return name * repeat

This allows for:
- Type checking and conversion
- Optional arguments with defaults
- Named arguments
- Help text generation

Best Practices
--------------

1. **Parameter Order**: Always keep parameters in the order ``(self, msg, args)`` for consistency.

2. **Default Values**: Use default values for optional parameters, but be careful with the ``msg`` parameter as it's usually required.

3. **Argument Splitting**: Use ``split_args_with=None`` when you need to handle multiple space-separated arguments.

4. **Type Safety**: Use ``arg_botcmd`` when you need type checking or complex argument parsing.

5. **Documentation**: Always document your command's parameters and expected usage in the function's docstring.

Example with All Features
-------------------------

Here's a complete example showing various parameter handling techniques:

.. code-block:: python

@arg_botcmd('name', type=str, help='The name to greet')
@arg_botcmd('--count', dest='repeat', type=int, default=1, help='Number of times to repeat')
@arg_botcmd('--shout', dest='shout', action='store_true', help='Convert to uppercase')
def greet(self, msg, name=None, repeat=None, shout=False):
"""Greet someone with a customizable message.

Example:
!greet Alice --count 3 --shout
"""
if not name:
return "Please provide a name to greet"

message = f"Hello, {name}!"
if shout:
message = message.upper()

return message * repeat

This command demonstrates:
- Required and optional arguments
- Type conversion
- Default values
- Boolean flags
- Help text
- Proper documentation

Common Pitfalls
---------------

1. **Default Values for msg**: While possible, it's generally not recommended to provide default values for the ``msg`` parameter as it's essential for command context.

2. **Argument Splitting**: Remember that ``split_args_with=None`` splits on any whitespace, which might not be what you want if you need to preserve spaces in arguments.

3. **Type Conversion**: When using ``arg_botcmd``, always specify the correct type for arguments to ensure proper conversion and validation.

4. **Parameter Names**: Keep parameter names consistent with the decorator's expectations (``msg`` and ``args`` for basic commands, or the names specified in ``arg_botcmd``).

5. **Documentation**: Always include examples in your docstrings to help users understand how to use your commands correctly.
2 changes: 2 additions & 0 deletions docs/user_guide/plugin_development/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ with sets of recipes on a range of topics describing how to handle more advanced
development_environment
basics
botcommands
command_parameters
messaging
threaded_replies
presence
mentions
persistence
configuration
provisioning
streams
dependencies
dynaplugs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ It will give you on stdout a python dictionary of the core namespace like::

{'configs': {'Webserver': {'PORT': 8888}}}

To read the values from a plugin storage, for example here from alimac/err-factoid you can do::
To read the values from a plugin storage, for example here from the ChatRoom plugin you can do::

errbot --storage-get Factoid
errbot --storage-get ChatRoom

It will give you on stdout a similar output::

{'FACTOID': {'fire': 'burns', 'water': 'wet'}}
{'rooms': ['#general', '#support']}


Writing values
Expand All @@ -54,11 +54,8 @@ Checking back::
errbot --storage-get core
{'configs': {'Webserver': {'PORT': 9999}}}

Changing facts in Factoid (note the merge is only on the first level so we change all FACTOID here)::
Changing plugin storage values (note the merge is only on the first level)::

echo "{'FACTOID': {'errbot': 'awesome'}}" | errbot --storage-merge Factoid

>>> !errbot?
errbot is awesome
echo "{'rooms': ['#general', '#support', '#dev']}" | errbot --storage-merge ChatRoom

You can use --storage-set in the same fashion but it will erase first the namespace before writing your values.
12 changes: 6 additions & 6 deletions docs/user_guide/plugin_development/testing_plugins_fullstack.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Testing your plugins with unittest
This guide explains how to test your Errbot plugins using the built-in testing framework. Errbot provides a powerful testing backend called ``FullStackTest`` that allows you to write unit tests for your plugins in a familiar unittest style.

Basic Test Setup
--------------
----------------

To test your plugin, create a test file (e.g., `test_myplugin.py`) in your plugin's directory. Here's a basic example:

Expand All @@ -29,7 +29,7 @@ To test your plugin, create a test file (e.g., `test_myplugin.py`) in your plugi
self.assertIn('Hello!', self.pop_message())

Running Tests
------------
-------------

You can run your tests using Python's unittest framework:

Expand All @@ -38,7 +38,7 @@ You can run your tests using Python's unittest framework:
python -m unittest test_myplugin.py

Test Methods
-----------
------------

FullStackTest provides several methods to help test your plugin's behavior:

Expand All @@ -59,7 +59,7 @@ FullStackTest provides several methods to help test your plugin's behavior:
- Test plugin dependencies

Example Test Cases
----------------
------------------

Here are some example test cases showing different testing scenarios:

Expand Down Expand Up @@ -105,7 +105,7 @@ Here are some example test cases showing different testing scenarios:
self.assertIn('Mock response', self.pop_message())

Best Practices
-------------
--------------

1. **Test Isolation**: Each test should be independent and not rely on the state from other tests.

Expand All @@ -118,7 +118,7 @@ Best Practices
5. **Documentation**: Document your test cases to explain what they're testing and why.

Complete Example
--------------
----------------

Here's a complete example of a test suite for a plugin:

Expand Down
18 changes: 9 additions & 9 deletions docs/user_guide/plugin_development/threaded_replies.rst
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
Threaded Replies
===============
================

Errbot supports threaded replies, which allows bot responses to be organized in conversation threads when the backend supports this feature. This is particularly useful for maintaining context in group chats and keeping related messages together.

Enabling Threaded Replies
------------------------
-------------------------

There are two ways to enable threaded replies in Errbot:

1. Per-command basis using the `in_reply_to` parameter in `send`
2. Globally for specific commands using the `DIVERT_TO_THREAD` configuration

Per-command Threaded Replies
---------------------------
----------------------------

You can send a threaded reply to any message using the `in_reply_to` parameter in `send`:

Expand All @@ -27,7 +27,7 @@ You can send a threaded reply to any message using the `in_reply_to` parameter i
self.send(msg.frm, "This is a threaded response", in_reply_to=msg)

Global Thread Configuration
-------------------------
---------------------------

You can configure Errbot to automatically send responses in threads for specific commands by adding them to the `DIVERT_TO_THREAD` configuration in your config.py:

Expand All @@ -40,7 +40,7 @@ You can configure Errbot to automatically send responses in threads for specific
DIVERT_TO_THREAD = ("ALL_COMMANDS",)

Backend Support
--------------
---------------

Threaded replies are supported by the following backends:

Expand All @@ -52,7 +52,7 @@ Threaded replies are supported by the following backends:
Note that not all backends support threaded replies. If a backend doesn't support threading, the message will be sent as a regular message.

Best Practices
-------------
--------------

1. Use threaded replies for:
- Long conversations that need to maintain context
Expand All @@ -66,7 +66,7 @@ Best Practices
- Debug information

Example Plugin
-------------
--------------

Here's a complete example of a plugin that demonstrates threaded replies:

Expand Down Expand Up @@ -96,7 +96,7 @@ Here's a complete example of a plugin that demonstrates threaded replies:
self.send(msg.frm, help_text, in_reply_to=msg)

Configuration
------------
-------------

To enable threaded replies globally for specific commands, add them to your config.py:

Expand All @@ -114,7 +114,7 @@ To enable threaded replies globally for specific commands, add them to your conf
DIVERT_TO_THREAD = ("ALL_COMMANDS",)

Limitations
----------
-----------

1. Not all backends support threaded replies
2. Threaded replies may not be visible in all chat clients
Expand Down
2 changes: 1 addition & 1 deletion docs/user_guide/setup.rst
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ on `PyPI <https://pypi.org/project/errbot/>`_.
Provisioning (advanced)
-----------------------

See the :doc:`provisioning documentation </user_guide/provisioning>`
See the :doc:`provisioning documentation </user_guide/plugin_development/provisioning>`

.. _virtualenv: https://virtualenv.pypa.io/en/latest/
.. _pip: https://pip.pypa.io/en/stable/
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"colorlog==6.7.0",
"markdown==3.4.4",
"ansi==0.3.6",
"Pygments==2.16.1",
"Pygments>=2.17",
"pygments-markdown-lexer==0.1.0.dev39", # sytax coloring to debug md
"dulwich==0.21.5", # python implementation of git
"deepmerge==1.1.0",
Expand Down