-
Notifications
You must be signed in to change notification settings - Fork 0
How to Make a Plugin
Extending pytide with plugins is easy, as the predefined plugin class does most of the work, and you only need to define a few things.
The first step is to make a subclass of NetworkTools.models.plugin.Plugin (although since your plugin file will be sitting in NetworkTools.plugins, it can be accessed using dot-notation - import ..models.plugin
or from ..models import plugin
. This tutorial will give you the barebones needed to make your plugin work with pytide, but won't help you with actually making a plugin for a different server - that bit is down to you.
from ..models import plugin, digest, user
class WaveSeverConnection(plugin.Plugin):
pass
Now, add placeholders for all the required functions in a plugin. It isn't necessary to put anything in them just yet, but it is helpful to have them in code so that none are missing or forgotten later.
from models import plugin, digest, user
class PyGoWaveConnection(plugin.Plugin):
def __init__(self, username, password):
pass
def _query(self, query, startpage):
pass
def _contacts(self):
pass
def _me(self):
pass
The above methods are the only required ones at this time, but this list will likely grow over time. Below is a description of what these methods are to do:
-
__init__
: This is called by the plugin.Plugin initialisation method. Raising a NetworkTools.ConnectionError will cause a login attempt to fail, and the initialization of the plugin will abort. This error is handled neatly by the Network object. Also note: you don't need to make a call to super() for init to work: this functionality has already been worked out. -
_query
: Don't forget the underscore! This function needs to return a..models.digest.SearchResults
object, which will pretty much guarantee the need for conversion from the server's format to PyTide's format. Your plugin is responsible for handling this. As always, you can look to the gwave.py file for an example (in that case, there is a separate class for converting from the Google Wave Data API's models, but they could just as easily be top level functions - there are no restrictions here). -
_contacts
: Returns a list of all the people in your account's contacts (as models.user.User instances). This might be a good time to bring up exception handling. If you don't handle an exception, it will eventually end up being handled by the Network object. This is so you can raise ConnectionErrors and such on purpose to let the Network know that something went wrong, not so you can just be lazy about your exception handling. Just because it works without manual handling doesn't mean it should be done (much like mangled HTML). -
_me
: Returns a..models.user.User
version of the metadata for your own account. Expect to be able to copy/paste/modify a lot of code over from your _contacts() function, but remember that it's just returning one object this time, not a list.
Once you have coded your plugin to work with a particular server, it is time to integrate your plugin into PyTide, it is very simple. Depending on how big your plugin is, it can vary in size from a whole folder to a single file. This does not matter. Simply drop all of the code into the plugins directory - /NetworkTools/plugins/
.
There is but one thing left to do - add an entry or two to the plugins configuration file, called plugin_mapping.txt
. It is located in the plugins directory.
The line should consist of the following:
protocol_name path.to.plugin PluginClassname
-
protocol_name
: The name of the the protocol that your plugin supports. (Currently, the only defined plugin name is "google_data", for the Google Wave Data API. If any more plugin names are officially defined, they will appear in the "protocol_names.txt" file in the plugins directory. -
path.to.plugin
: The Python style path to your plugin (Python Style = works in an import statement). So if it is a single file, put straight into the plugins folder, then this will just be your file's name, without the .py. If your plugin is in a seperate directory, however, you must specify the directory too. This should be the path assuming that you are already in the /plugins/ directory. -
PluginClassname
: The name given to the actual plugin class, within the file specified inpath.to.plugin
. This is the class that was defined in steps 1 & 2, and is a subclass of..models.plugin
.
Add one of these lines for each plugin as you support. (In fact, you are not required to use a domain. An IP address is also fine.)
If you are designing the plugin to be used by anyone else, then you should provide a script with your plugin that adds the files to the plugin directory and the relevant lines to the configuration file.
That's all there is to it. Hopefully the "scary" has been taken out of it, so that as you know how your protocol works, making a plugin will be trivial. It isn't recommended to look into models/plugin.py for guidance (other than the doc strings), because, though the plugin system has a gloriously simple interface, it's a multiprocessing-based monster underneath, and not for the faint of heart to analyze.
Back to How the Code Works