csbot.plugin module

csbot.plugin.build_plugin_dict(plugins)[source]

Build a dictionary mapping the value of plugin_name() to each plugin class in plugins. PluginDuplicate is raised if more than one plugin has the same name.

exception csbot.plugin.PluginDuplicate[source]

Bases: Exception

exception csbot.plugin.PluginDependencyUnmet[source]

Bases: Exception

exception csbot.plugin.PluginFeatureError[source]

Bases: Exception

class csbot.plugin.PluginManager(loaded, available, plugins, args)[source]

Bases: collections.abc.Mapping

A simple plugin manager and proxy.

The plugin manager is responsible for loading plugins and proxying method calls to all plugins. In addition to accepting loaded, a list of existing plugin objects, it will attempt to load each of plugins from available (a mapping of plugin name to plugin class), passing args to the constructors.

Attempting to load missing or duplicate plugins will log errors and warnings respectively, but will not result in an exception or any change of state. A plugin class’ dependencies are checked before loading and a PluginDependencyUnmet is raised if any are missing.

The Mapping interface is implemented to provide easy querying and access to the loaded plugins. All attributes that do not start with a _ are treated as methods that will be proxied through to every plugin in the order they were loaded (loaded before plugins) with the same arguments.

plugins = {}

Loaded plugins.

class csbot.plugin.ProvidedByPlugin(plugin, kwargs)

Bases: tuple

kwargs

Alias for field number 1

plugin

Alias for field number 0

class csbot.plugin.PluginMeta(name, bases, dict)[source]

Bases: type

Metaclass for Plugin that collects methods tagged with plugin feature decorators.

class csbot.plugin.Plugin(bot)[source]

Bases: object

Bot plugin base class.

All bot plugins should inherit from this class. It provides convenience methods for hooking events, registering commands, accessing MongoDB and manipulating the configuration file.

CONFIG_DEFAULTS = {}

Default configuration values, used automatically by config_get().

CONFIG_ENVVARS = {}

Configuration environment variables, used automatically by config_get().

PLUGIN_DEPENDS = set()

Plugins that missing_dependencies() should check for.

log = None

The plugin’s logger, created by default using the plugin class’ containing module name as the logger name.

classmethod plugin_name()[source]

Get the name of the plugin, by default the class name in lowercase.

classmethod qualified_name()[source]

Get the fully qualified class name, most useful when complaining about duplicate plugins names.

classmethod missing_dependencies(plugins)[source]

Return elements from PLUGIN_DEPENDS that are not in the container plugins.

This should be used with some container of already loaded plugin names (e.g. a dictionary or set) to find out which dependencies are missing.

static hook(hook)[source]
static command(cmd, **metadata)[source]

Tag a command to be registered by setup().

Additional keyword arguments are added to a metadata dictionary that gets stored with the command. This is a good place to put, for example, the help string for the command:

@Plugin.command('foo', help='foo: does something amazing')
def foo_command(self, e):
    pass
static integrate_with(*otherplugins)[source]

Tag a method as providing integration with otherplugins.

During setup(), all methods tagged with this decorator will be run if all of the named plugins are loaded. The actual plugin objects will be passed as arguments to the method in the same order.

Note

The order that integration methods are called in cannot be guaranteed, because attribute order is not preserved during class creation.

static use(other, **kwargs)[source]

Create a property that will be provided by another plugin.

Returns a ProvidedByPlugin instance. PluginMeta will collect attributes of this type, and add other as an implicit plugin dependency. setup() will replace it with a value acquired from the plugin named by other. For example:

class Foo(Plugin):
    stuff = Plugin.use('mongodb', collection='stuff')

will cause setup() to replace the stuff attribute with:

self.bot.plugins[other].provide(self.plugin_name(), **kwargs)
fire_hooks(event)[source]

Execute all of this plugin’s handlers for event.

All handlers are treated as coroutine functions, and the return value is a list of all the invoked coroutines.

provide(plugin_name, **kwarg)[source]

Provide a value for a Plugin.use() usage.

setup()[source]

Plugin setup.

  • Replace all ProvidedByPlugin attributes.
  • Fire all plugin integration methods.
  • Register all commands provided by the plugin.
teardown()[source]

Plugin teardown.

  • Unregister all commands provided by the plugin.
config

Get the configuration section for this plugin.

Uses the [plugin_name] section of the configuration file, creating an empty section if it doesn’t exist.

See also

configparser

subconfig(subsection)[source]

Get a configuration subsection for this plugin.

Uses the [plugin_name/subsection] section of the configuration file, creating an empty section if it doesn’t exist.

config_get(key)[source]

Convenience wrapper proxying get() on config.

Given a key, this method tries the following in order:

self.config[key]
for v in self.CONFIG_ENVVARS[key]:
    os.environ[v]
self.CONFIG_DEFAULTS[key]

KeyError is raised if none of the methods succeed.

config_getboolean(key)[source]

Identical to config_get(), but proxying getboolean.

plugin_cmds = []
plugin_hooks = defaultdict(<class 'list'>, {})
plugin_integrations = []
plugin_provide = []
class csbot.plugin.SpecialPlugin(bot)[source]

Bases: csbot.plugin.Plugin

A special plugin with a special name that expects to be handled specially. Probably shouldn’t have too many of these or they won’t feel special anymore.

PLUGIN_DEPENDS = set()
plugin_cmds = []
plugin_hooks = defaultdict(<class 'list'>, {})
plugin_integrations = []
plugin_provide = []
classmethod plugin_name()[source]

Change the plugin name to something that can’t possibly result from a class name by prepending a @.