Tuesday, November 15, 2005

Adding Axiomatic plugins

axiomatic has featured prominently in many of my recent blog posts, but what is it?

As one might guess, in simplest terms, axiomatic is a tool for manipulating Axiom databases. Going into a little more detail, axiomatic is a command line tool which gathers axiom.iaxiom.IAxiomaticCommand plugins using the Twisted plugin system and presents them as subcommands to the user, while providing the implementations of these subcommands with access to objects that pretty much any Axiom manipulation code is going to want (currently, that amounts to an opened Store instance). Twisted's option parser is used as the basic unit of functionality here.

I've already talked about several IAxiomaticCommand implementations: web, mantissa, and start. The first two of these add new Items to an Axiom database or change the values associated with existing Items. The last "starts" an Axiom database (more on what that means in a future post!).

So what you really want to know is how do I write an axiomatic plugin? Let me tell you, it could scarcely be easier:

from zope.interface import classProvides
from twisted import plugin
from twisted.python import usage
from axiom import iaxiom
from axiom.scripts import axiomatic

class PrintAllItems(usage.Options, axiomatic.AxiomaticSubCommandMixin):
# This one tells the plugin system this object is a plugin
# This one tells axiom it is an axiomatic plugin

# This is how it will be invoked on the command line
name = "print-some-items"

# This will show up next to the name in --help output
description = "Display an arbitrary number of Items"

optParameters = [
# We'll take the number of Items to display as a command
# line parameter. This is "--num-items x" or "-n x" or
# any of the other standard spellings. The default is 5.
('num-items', 'n', '5', 'The number of Items to display'),

def postOptions(self):
s = self.parent.getStore()
count = int(self.decodeCommandLine(self['num-items']))
for i in xrange(count):
print s.getItemByID(i)
except KeyError:
# The Item didn't exist

(Okay, seriously - I know this is a bit long: we'll be working on lifting a lot of the boilerplate out to simplify things; expect about half of the above code to become redundant soon). I just drop this into a file in axiom/plugins/ (there are other places I could put it, if I wanted; read the Twisted plugin documentation to learn more) and I've got a new subcommand:

exarkun@boson:~$ axiomatic --help
Usage: axiomatic [options]
-d, --dbdir= Path containing axiom database to configure/create
--help Display this help and exit.
mail Accept SMTP connections
userbase Users. Yay.
mantissa Blank Mantissa service
web-application Web interface for normal user
web Web. Yay.
web-admin Administrative controls for the web
radical omfg play the game now
click-chronicle-site Chronicler of clicking
encore Install BookEncore site store requirements.
sip-proxy SIP proxy and registrar
vendor Interface for purchasing new services.
vendor-site Required site-store installation gunk
print-some-items Display an arbitrary number of Items
start Launch the given Axiomatic database

Neat, huh?*

In case you're dying to see the output of this new command:

exarkun@boson:~/Scratch/Run/demo$ axiomatic -d my.axiom/ print-some-items
<axiom.item._PowerupConnector object at 0xb6fc770c>
<axiom.item._PowerupConnector object at 0xb6fc770c>
<axiom.userbase.LoginSystem object at 0xb6f42104>

1 comment: