Browse Source

Add an unload hook for commands and tasks.

tags/v0.2
Ben Kurtovic 9 years ago
parent
commit
5534a46c55
6 changed files with 46 additions and 7 deletions
  1. +2
    -0
      CHANGELOG
  2. +3
    -3
      README.rst
  3. +13
    -3
      docs/customizing.rst
  4. +7
    -0
      earwigbot/commands/__init__.py
  5. +14
    -1
      earwigbot/managers.py
  6. +7
    -0
      earwigbot/tasks/__init__.py

+ 2
- 0
CHANGELOG View File

@@ -2,6 +2,8 @@ v0.2 (unreleased):


- Added a new command syntax allowing the caller to redirect replies to another - Added a new command syntax allowing the caller to redirect replies to another
user. Example: "!dictionary >Fred earwig" user. Example: "!dictionary >Fred earwig"
- Added unload() hooks to commands and tasks, called when they are killed
during a reload.
- Added 'rc' hook type to allow IRC commands to respond to RC watcher events. - Added 'rc' hook type to allow IRC commands to respond to RC watcher events.
- Added 'part' hook type as a counterpart to 'join'. - Added 'part' hook type as a counterpart to 'join'.
- Added !stalk/!watch. - Added !stalk/!watch.


+ 3
- 3
README.rst View File

@@ -133,8 +133,8 @@ Custom IRC commands
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~


Custom commands are subclasses of `earwigbot.commands.Command`_ that override Custom commands are subclasses of `earwigbot.commands.Command`_ that override
``Command``'s ``process()`` (and optionally ``check()`` or ``setup()``)
methods.
``Command``'s ``process()`` (and optionally ``check()``, ``setup()``, or
``unload()``) methods.


The bot has a wide selection of built-in commands and plugins to act as sample The bot has a wide selection of built-in commands and plugins to act as sample
code and/or to give ideas. Start with test_, and then check out chanops_ and code and/or to give ideas. Start with test_, and then check out chanops_ and
@@ -144,7 +144,7 @@ Custom bot tasks
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~


Custom tasks are subclasses of `earwigbot.tasks.Task`_ that override ``Task``'s Custom tasks are subclasses of `earwigbot.tasks.Task`_ that override ``Task``'s
``run()`` (and optionally ``setup()``) methods.
``run()`` (and optionally ``setup()`` or ``unload()``) methods.


See the built-in wikiproject_tagger_ task for a relatively straightforward See the built-in wikiproject_tagger_ task for a relatively straightforward
task, or the afc_statistics_ plugin for a more complicated one. task, or the afc_statistics_ plugin for a more complicated one.


+ 13
- 3
docs/customizing.rst View File

@@ -86,8 +86,9 @@ Custom IRC commands
Custom commands are subclasses of :py:class:`earwigbot.commands.Command` that Custom commands are subclasses of :py:class:`earwigbot.commands.Command` that
override :py:class:`~earwigbot.commands.Command`'s override :py:class:`~earwigbot.commands.Command`'s
:py:meth:`~earwigbot.commands.Command.process` (and optionally :py:meth:`~earwigbot.commands.Command.process` (and optionally
:py:meth:`~earwigbot.commands.Command.check` or
:py:meth:`~earwigbot.commands.Command.setup`) methods.
:py:meth:`~earwigbot.commands.Command.check`,
:py:meth:`~earwigbot.commands.Command.setup`, or
:py:meth:`~earwigbot.commands.Command.unload`) methods.


:py:class:`~earwigbot.commands.Command`'s docstrings should explain what each :py:class:`~earwigbot.commands.Command`'s docstrings should explain what each
attribute and method is for and what they should be overridden with, but these attribute and method is for and what they should be overridden with, but these
@@ -154,6 +155,10 @@ are the basics:
<earwigbot.irc.connection.IRCConnection.join>`, and <earwigbot.irc.connection.IRCConnection.join>`, and
:py:meth:`part(chan) <earwigbot.irc.connection.IRCConnection.part>`. :py:meth:`part(chan) <earwigbot.irc.connection.IRCConnection.part>`.


- Method :py:meth:`~earwigbot.commands.Command.unload` is called *once* with no
arguments immediately before the command is unloaded, such as when someone
uses ``!reload``. Does nothing by default.

Commands have access to :py:attr:`config.commands[command_name]` for config Commands have access to :py:attr:`config.commands[command_name]` for config
information, which is a node in :file:`config.yml` like every other attribute information, which is a node in :file:`config.yml` like every other attribute
of :py:attr:`bot.config`. This can be used to store, for example, API keys or of :py:attr:`bot.config`. This can be used to store, for example, API keys or
@@ -175,7 +180,8 @@ Custom bot tasks
Custom tasks are subclasses of :py:class:`earwigbot.tasks.Task` that Custom tasks are subclasses of :py:class:`earwigbot.tasks.Task` that
override :py:class:`~earwigbot.tasks.Task`'s override :py:class:`~earwigbot.tasks.Task`'s
:py:meth:`~earwigbot.tasks.Task.run` (and optionally :py:meth:`~earwigbot.tasks.Task.run` (and optionally
:py:meth:`~earwigbot.tasks.Task.setup`) methods.
:py:meth:`~earwigbot.tasks.Task.setup` or
:py:meth:`~earwigbot.tasks.Task.unload`) methods.


:py:class:`~earwigbot.tasks.Task`'s docstrings should explain what each :py:class:`~earwigbot.tasks.Task`'s docstrings should explain what each
attribute and method is for and what they should be overridden with, but these attribute and method is for and what they should be overridden with, but these
@@ -220,6 +226,10 @@ are the basics:
the task's code goes. For interfacing with MediaWiki sites, read up on the the task's code goes. For interfacing with MediaWiki sites, read up on the
:doc:`Wiki Toolset <toolset>`. :doc:`Wiki Toolset <toolset>`.


- Method :py:meth:`~earwigbot.tasks.Task.unload` is called *once* with no
arguments immediately before the task is unloaded. Does nothing by
default.

Tasks have access to :py:attr:`config.tasks[task_name]` for config information, Tasks have access to :py:attr:`config.tasks[task_name]` for config information,
which is a node in :file:`config.yml` like every other attribute of which is a node in :file:`config.yml` like every other attribute of
:py:attr:`bot.config`. This can be used to store, for example, edit summaries :py:attr:`bot.config`. This can be used to store, for example, edit summaries


+ 7
- 0
earwigbot/commands/__init__.py View File

@@ -120,3 +120,10 @@ class Command(object):
command's body here. command's body here.
""" """
pass pass

def unload(self):
"""Hook called immediately before a command is unloaded.

Does nothing by default; feel free to override.
"""
pass

+ 14
- 1
earwigbot/managers.py View File

@@ -137,6 +137,19 @@ class _ResourceManager(object):
self._load_module(modname, dir) self._load_module(modname, dir)
processed.append(modname) processed.append(modname)


def _unload_resources(self):
"""Unload all resources, calling their unload hooks in the process."""
res_type = self._resource_name[:-1] # e.g. "command" or "task"
for resource in self:
if not hasattr(resource, "unload"):
continue
try:
resource.unload()
except Exception:
e = "Error unloading {0} '{1}'"
self.logger.exception(e.format(res_type, resource.name))
self._resources.clear()

@property @property
def lock(self): def lock(self):
"""The resource access/modify lock.""" """The resource access/modify lock."""
@@ -146,7 +159,7 @@ class _ResourceManager(object):
"""Load (or reload) all valid resources into :py:attr:`_resources`.""" """Load (or reload) all valid resources into :py:attr:`_resources`."""
name = self._resource_name # e.g. "commands" or "tasks" name = self._resource_name # e.g. "commands" or "tasks"
with self.lock: with self.lock:
self._resources.clear()
self._unload_resources()
builtin_dir = path.join(path.dirname(__file__), name) builtin_dir = path.join(path.dirname(__file__), name)
plugins_dir = path.join(self.bot.config.root_dir, name) plugins_dir = path.join(self.bot.config.root_dir, name)
if getattr(self.bot.config, name).get("disable") is True: if getattr(self.bot.config, name).get("disable") is True:


+ 7
- 0
earwigbot/tasks/__init__.py View File

@@ -84,6 +84,13 @@ class Task(object):
""" """
pass pass


def unload(self):
"""Hook called immediately before the task is unloaded.

Does nothing by default; feel free to override.
"""
pass

def make_summary(self, comment): def make_summary(self, comment):
"""Make an edit summary by filling in variables in a config value. """Make an edit summary by filling in variables in a config value.




Loading…
Cancel
Save