Subsections

- - Naming and Locating
  - Distribution
  - Enabling
  - Disabling
  - Security

#
Plugins

MMA can be infinitely expanded by the use of PLUGINs.

So, what is a plugin? In it's simplest it is a bit of Python code which is loaded into a running MMA . This code can then communicate with MMA just as if it were a native part of it.

Warning: Since a plugin is just a bunch of Python code it can do anything ... unfortunately this may include malicious or unwanted things. The author of MMA cannot take any responsibility for anything which happens when running a plugin. It is up to you to ensure that any plugins you include in your MMA directories are safe to run. Only use plugins from a trusted source!

If you want to try writing your own PLUGIN, please refer to the “writing plugins” document in either HTML to PDF.

When a plugin is loaded into MMA 's memory it will add a keyword which can be used just like any other command. All PLUGIN command names are prefaced with a single “@” character. This serves two purposes:

1. It gives plugin keywords a distinctive appearance,
2. It permits plugin keywords which duplicate existing keywords. Native MMA keywords are guaranteed to never begin with an “@”.

## Naming and Locating

As mentioned above, a plugin consists of a Python module which is added to MMA 's internal command table. These modules are free to call existing MMA functions, and even add their own plugins, and call other programs.23.1

Each plugin must have a containing directory with the same name as the plugin. So, the plugin “hello” would live in the hello directory. Once found and loaded the command @HELLO will be available to your script.

This directory must contain a Python module with the name “plugin.py”. The plugin.py module should have the following methods defined:

run
  This is the entry point for a simple (non-track) command.

trackRun
  This is the entry point for a track command.

printUsage
  The entry point for a usage command. This is used by the -I command line option.

The spelling (including case) of these three methods must be exactly as described above.

In addition, each plugin directory must contain an empty file called __init__.py. This file is necessary for Python's import facility to operate. MMA checks for this file and will generate an error if not found or not empty.23.2

Hoping that a few lines of example code will compensate for the lack of pages of reference, we suggest that you look at the module plugins/hello/plugin.py.

When locating modules MMA makes a case-insensitive search for the directory and python module. So, when loading “hello” you could have a directory “HELLO” and a module “PLUGIN.py” and all will work. The Python module must end with “.py” (all lowercase). We really recommend you simplify your life and use the all lowercase version! If you have both a “hello” and “HELLO” directories a warning message will be printed; one of the two modules will be loaded, but which is indeterminate (the first found will be used).23.3

## Distribution

The directory for a plugin should also contain a sample file which shows how the plugin can be used and some documentation. At its simplest this could be a README text file; more complex plugins can have more extensive examples and other reference material.

Plugins can reside in four different locations. When requested to load a plugin MMA searches, in the order below, the following:

1. The user's current directory. This is normally referred to as “.”,

2. A directory named plugins in the user's current directory. This permits a collection of plugins for each user.

3. The directory of the current file being processed. This means that if you load a GROOVE into memory and the groove's library file contains a “load plugin” directive, the search will match a plugin in that directory.

4. The plugins directory. We recommend that all plugins use this location! It makes it easy to track where your plugins live. You cannot change the the location or name of this directory: it must be a directory called plugins and be located in the main MMA directory tree (the same location as the MMA modules directory). Unfortunately, if you are using a standard MMA distribution this directory may not be modifiable by you since it is in a “root access” location ... which is why the above locations are available.

You can change the search path using the DISABLE command, see below.

## Enabling

To enable a PLUGIN it must be first loaded into a running MMA . This is done with the PLUGIN command. For example,

Plugin Hello

will load the “hello” plugin into memory. You can now invoke the command with:

@Hello

or, you can pass a variety of additional information to the plugin code:

@Hello Some things to tell HELLO

If you have both a track and non-track function, you could:

Bass @Hello

- Please note that no plugins will be loaded or activated unless MMA is specifically told to load with a PLUGIN directive.

- You may have multiple plugin names on a single PLUGIN line.

- You can not reload a plugin. If you try a warning message will be displayed.

- When chosing a name for your plugin make sure it isn't the name of a module which MMA has already used. Examples include copy, random, time and os. If you attempt to load your module with such a name you will receive an error message.

## Disabling

You can disable the search path used when searching for plugins. If you are a bit worried about malicious code:

Plugin Disable=ALL

will prevent any plugins being loaded.

We noted above that the user's current directory, the directory of the current file, and the plugin directory are searched. You can disable any of these using the options “Dot”, “Local” and “PlugDir”. You can specify more that one by appending settings with single commas. So,

Plugin Disable=Dot,Local

will force the search to only the plugin directory.

For security, there is no “enable” command. So, feel safe in putting this in your mmarc file.

## Security

We try to give you as many options as possible in MMA . We also try to keep your systems and data as secure as we can.

We don't have any control over what a PLUGIN can do. But, we do make it a bit harder for someone to screw you around. The DISABLE options, above, are one such step.

In addition, the first time a plugin is loaded you will be asked if you wish to give permission for the plugin to load. If you don't recognize the name, just say “no”.

The prompt will permit the entry of a single character “y” (followed by the Enter key). Accepting a plugin will create an entry in the plugin.list file and the plugin will silently load in the future.

If you enter an “o” the plugin will be loaded only this run. This may or may not be a wise thing to do ... if you're not sure you probably should not enable it.

If any changes are made to the plugin code, you'll be asked again.

Permissions are stored in a file plugins.list. Depending on your system this will be located in a “standard” location.23.4

If you are confident that no harm will come to your system by loading plugins (which is probably true most of the time) you can skip all this security by starting MMA with the -II command line option.

#### Footnotes

... programs.23.1
  The reason we're so free with this stuff is that it's impossible to restrict what a good or malicious Python (or any other language) program can do. Again, Be Careful.
... empty.23.2
  Python doesn't restrict the __init__.py module to be empty. It can actually contain code. For security reasons we force it to be empty.
... used).23.3
  This would only be possible on computers with a case-sensitive filename structure, like Linux.
... location.23.4
  MMA uses the Python module appdirs.py (included in this distribution) to determine the “best” location to store configuration files. For more information see `http://github.com/ActiveState/appdirs`.