scribe : documentation

Spam-filter Plugins

This document is for Scribe's SVN release, which can be significantly different than previous releases. Get old docs here: 0.60.

Spam-filter plugins exist to allow third party developers to easily extend Scribe and test to see if comments being posted to the weblog are spam with whatever tool they want. Scribe also uses the plugin architecture to install some default spam-filtering functionality. The pre-packaged plugins is:

  • Akismet

Using Spam-filter Plugins

To use a spam-filter plugin, you simply need to set SPAMFILTER to the name of the spam-filter you want to use in your preferences.py file. Some spam-filters (like the built-in Akismet) may require additional configuration. Consult the documentation for the plugins that you plan to use for information about what additional configuration may be needed.

Installing plugins

If you obtain a plugin from a third party, you can simply put it into the plugins folder. The next time your code is reloaded, the plugin will be loaded.

Built-in Plugins

Akismet

The Akismet spam-filter is a very widely used spam-filter for weblogs. It requires that you have an API key from Wordpress, though. There are instructions on the Wordpress website for how to get a key.

To use Akismet, set AKISMET_KEY to your API key in your preferences.py file and make sure to set SPAMFILTER = 'akismet' as well.

Writing Custom Plugins

Base class

The base class object is scribe.core.plugins.base.SpamfilterPlugin. You should create a plugin object that inherits from this object.

Methods to override

The check, confirm_ham, and confirm_spam methods must all be overridden to create a spam-filter. Each method is passed a Comment object and a host string (letting you know what the host machine’s name is). The only method that needs to return anything is the check method which should return True if the comment is spam and False if it isn’t.

For example, the Akismet plugin looks something like this:

from scribe.core.plugins.base import SpamfilterPlugin
import akismet
class AkismetPluginException(Exception): pass
class AkismetPlugin(SpamfilterPlugin):
  def check(self, comment, host):
    # ask Akismet if the comment is spam
    # and return the result
    return is_spam(comment, host)
  def confirm_ham(self, comment, host):
    tell_is_ham(comment, host)
  def confirm_spam(self, comment, host):
    tell_is_spam(comment, host)

Note that even if your spam-filter doesn’t have a way of dealing with confirming ham versus spam, you need to implement these methods. You can simply define them with pass.

If you feel you need to, you can override the name method as well. By default this method simply takes the name of the class, strips off the Plugin part, and converts it to all lowercase. This should work fine for most plugin developers, and we encourage you do do this.

Defining custom preferences

You have the option of defining custom preferences for your plugin. Simply add a module called defaults to your module and define the default values for any preferences. When you want to use the preferences do the following:

from scribe.conf import settings
settings.MY_PREFERENCE

This will retrieve the value that the user defined in his/her preferences.py file if it exists, and if not, it will use the default value that you defined in the defaults module.

Using other Python libraries

You can include other python libraries by including a lib directory within your plugin. The lib directory will automatically be added to sys.path if it exists, so you can simply import modules from within lib. You should only use this if you’re using another author’s work that you don’t want to modify. Don’t put your own code in it.

Plugin module architecture

Each plugin must be a module contained within a directory. It cannot simply be a .py file. Here is a sample plugin architecture:

sidebar_coolfeature/
  __init__.py
  defaults.py
  lib/

Additional reference

Please don’t hesitate to use the built-in plugins as additional reference for creating new plugins.

Questions/Feedback

If you notice errors with this documentation, please open a ticket and let us know!