Pears

Intro

Pears plugins can do just about anything. They have full access to the internals of the application, both the GUI and the engine. If you felt like it, you could even replace the engine on the fly with your own, or completely restyle the GUI, though such actions could mean a lot of work.

Plugins are plain Python code files (with a .pear extension), with a bit of icing on top, just enough to allow Pears to extract the properties from it. All plugins should be placed in the Plugins directory of the Pears directory.

Pears recognizes two types of plugins: individual plugins and plugin collections. An individual plugin file exposes a single class as being a plugin; this plugin has its own top-level menu entry in the Pears plugins menu. A plugin collection is a plugin file which exposes several classes as being plugins. Such a collection has a single entry in the Plugins menu, with submenus for its individual plugins.

Coding style

The plugin file is imported in the global Pears namespace. This means that you must be careful not to overwrite anything that's already there. The best way to avoid this is to prepend all your global definitions with an identifier unique to your plugin. You should also give a unique name to your plugin file and to things like the ShortName (see below).

The plugin classes themselves must have names which make it clear what their function is. This is because Pears might prompt the user asking whether (s)he wishes to run class whatever, and whatever should make sense.

The code should not use large global variables, preferably none at all. Large structures which are not directly relevant to the plugin definition are better suited for placement in a separate py file in the plugins directory, which is imported by the plugin at runtime.

Regarding the coding itself: 4 spaces per indentation level, no tabs.

Writing

A plugin is a class which does something when its run method is called. The standard way of creating such a class is by subclassing the BasePlugin class, like this:
class MyPlugin(BasePlugin):
    def run(self):
        alert("MyPlugin", "Hello world!") 
        # alert is a function in pearsapp.py which shows a dialog
Put this code in a file myplugin.pear in the plugins subdirectory of the Pears directory. Now start Pears and click on the Plugins menu. The plugin is not there! That's because we forgot the icing, which are comments telling Pears what is to be found in this plugin file. For the precise structure of these comments, read the pearsplugin.py file in the Pears directory. In this case, you'll need to put the following comments in the myplugin.pear file, so the result will looks something like this:
### PEARSPLUGIN
### LongName=My first plugin
### ShortName=Hello world
### Hint=Says hello
### Version=1.0
### Author=John Doe
### Class=MyPlugin
### END

class MyPlugin(BasePlugin):
    def run(self):
        alert("MyPlugin", "Hello world!") 
        # alert is a function in pearsapp.py which shows a dialog
Bo back to Pears and click on Refresh plugins list in the Plugins menu. This will rebuild the list. If you look again, you'll se an entry Hello world. Click on it and voila, your first plugin is done.

Note that only classes which are exposed by the comment structure outlined above will be visible in Pears. However, I do not recommend putting large global variables in the plugin files themselves, as they will pollute the global namespace. It's better to place these variables in a py file in the plugins directory and import this at runtime. This is possible because the plugins directory also does duty as a the plugins module. Let's look at some example code. Add to the file you created above the following class:
class MySecondPlugin(BasePlugin):
    """Shows a random quote from MyData"""
    def __init__(self):
        import plugins.MyData as data
        self.quotes = data.quotes # list of strings
    def run(self):
        import random
        print "Quote:", random.choice(self.quotes)
We'll turn the myplugin.pear file into a plugin collection by removing the comments added above and replacing them with:
### PEARSPLUGINCOLLECTION
### LongName=Some demonstration plugins
### ShortName=Demo
### Hint=Demo plugins
### Version=1.0
### Author=John Doe
### 0.ShortName=Hello world
### 0.Hint=Says hello
### 0.Class=MyPlugin
### 1.ShortName=Quote of the day
### 1.Hint=Print a quote to the console
### 1.Class=MySecondPlugin
### END
Now we still need to define the MyData module which contains the quotes. Make a new text file in the plugins directory and call it MyData.py. Open it in your text editor and write:
quotes = [
          "Nobody expects the Spanish Inquisition!",
          "Spam, spam, spam, spam, spam, eggs and spam.",
          "Help, help, I'm being repressed!",
         ]
Ready to go now. Return to Pears, refresh the plugins menu and activate your brand new plugin. In the console you'll see one of the quotes.

For more information, see the plugins that came with Pears and the pearsplugin.py file in the Pears directory.

Contributing

If you write a plugin that you wish to contribute for the main distribution, there are some things you should take into account:
  • the plugin must fall under the Pears licence or a more liberal one, like the Python, BSD or LGPL licence
  • the plugin must adhere to the coding style outlined above
  • I might pass bug reports about the plugin on to you.
© 2003, 2004 Project 5