PluginManager¶
Role¶
The PluginManager
loads plugins that enforce the Plugin
Description Policy, and offers the most simple methods to activate
and deactivate the plugins once they are loaded.
Note
It may also classify the plugins in various categories, but this behaviour is optional and if not specified elseway all plugins are stored in the same default category.
Note
It is often more useful to have the plugin manager behave
like singleton, this functionality is provided by
PluginManagerSingleton
Plugin Description Policy¶
When creating a PluginManager
instance, one should provide it with
a list of directories where plugins may be found. In each directory,
a plugin should contain the following elements:
For a Standard plugin:
myplugin.yapsy-plugin
A plugin info file identical to the one previously described.
myplugin
A directory ontaining an actual Python plugin (ie with a
__init__.py
file that makes it importable). The upper namespace of the plugin should present a class inheriting theIPlugin
interface (the same remarks apply here as in the previous case).
For a Single file plugin:
myplugin.yapsy-plugin
A plugin info file which is identified thanks to its extension, see the Plugin Info File Format to see what should be in this file.
The extension is customisable at the
PluginManager
’s instanciation, since one may usually prefer the extension to bear the application name.
myplugin.py
The source of the plugin. This file should at least define a class inheriting the
IPlugin
interface. This class will be instanciated at plugin loading and it will be notified the activation/deactivation events.
Plugin Info File Format¶
The plugin info file is a text file encoded in ASCII or UTF-8 and gathering, as its name suggests, some basic information about the plugin.
it gives crucial information needed to be able to load the plugin
it provides some documentation like information like the plugin author’s name and a short description fo the plugin functionality.
Here is an example of what such a file should contain:
[Core]
Name = My plugin Name
Module = the_name_of_the_pluginto_load_with_no_py_ending
[Documentation]
Description = What my plugin broadly does
Author = My very own name
Version = the_version_number_of_the_plugin
Website = My very own website
Note
From such plugin descriptions, the PluginManager
will
built its own representations of the plugins as instances of
the PluginInfo class.
Changing the default behaviour¶
The default behaviour for locating and loading plugins can be changed using the various options exposed on the interface via getters.
The plugin detection, in particular, can be fully customized by
settting a custom plugin locator. See IPluginLocator
for more
details on this.
Extensibility¶
Several mechanisms have been put up to help extending the basic functionalities of the proivided classes.
A few hints to help you extend those classes:
If the new functionalities do not overlap the ones already
implemented, then they should be implemented as a Decorator class of the
base plugin. This should be done by inheriting the
PluginManagerDecorator
.
If this previous way is not possible, then the functionalities should
be added as a subclass of PluginManager
.
Note
The first method is highly prefered since it makes it possible to have a more flexible design where one can pick several functionalities and litterally add them to get an object corresponding to one’s precise needs.
API¶
-
class
yapsy.PluginManager.
PluginManager
(categories_filter=None, directories_list=None, plugin_info_ext=None, plugin_locator=None)¶ Manage several plugins by ordering them in categories.
The mechanism for searching and loading the plugins is already implemented in this class so that it can be used directly (hence it can be considered as a bit more than a mere interface)
The file describing a plugin must be written in the syntax compatible with Python’s ConfigParser module as in the Plugin Info File Format
About the __init__:
Initialize the mapping of the categories and set the list of directories where plugins may be. This can also be set by direct call the methods:
setCategoriesFilter
forcategories_filter
setPluginPlaces
fordirectories_list
setPluginInfoExtension
forplugin_info_ext
You may look at these function’s documentation for the meaning of each corresponding arguments.
-
activatePluginByName
(name, category='Default')¶ Activate a plugin corresponding to a given category + name.
-
appendPluginCandidate
(candidateTuple)¶ Append a new candidate to the list of plugins that should be loaded.
The candidate must be represented by the same tuple described in
getPluginCandidates
.
-
appendPluginToCategory
(plugin, category_name)¶ Append a new plugin to the given category.
-
collectPlugins
()¶ Walk through the plugins’ places and look for plugins. Then for each plugin candidate look for its category, load it and stores it in the appropriate slot of the category_mapping.
-
deactivatePluginByName
(name, category='Default')¶ Desactivate a plugin corresponding to a given category + name.
-
getAllPlugins
()¶ Return the list of all plugins (belonging to all categories).
-
getCategories
()¶ Return the list of all categories.
-
getPluginByName
(name, category='Default')¶ Get the plugin correspoding to a given category and name
-
getPluginCandidates
()¶ Return the list of possible plugins.
Each possible plugin (ie a candidate) is described by a 3-uple: (info file path, python file path, plugin info instance)
-
getPluginInfoClass
()¶ DEPRECATED(>1.9): directly control that with the IPluginLocator instance instead !
Get the class that holds PluginInfo.
-
getPluginLocator
()¶ Grant direct access to the plugin locator.
-
getPluginsOf
(**kwargs)¶ Returns a set of plugins whose properties match the named arguments provided here along with their correspoding values.
-
getPluginsOfCategory
(category_name)¶ Return the list of all plugins belonging to a category.
-
instanciateElement
(element)¶ DEPRECATED(>1.11): reimplement instead
instanciateElementWithImportInfo
!Override this method to customize how plugins are instanciated.
Warning
This method is called only if
instanciateElementWithImportInfo
has not been reimplemented !
-
instanciateElementWithImportInfo
(element, element_name, plugin_module_name, candidate_filepath)¶ Override this method to customize how plugins are instanciated.
Note
This methods recieves the ‘element’ that is a candidate as the plugin’s main file, but also enough information to reload its containing module and this element.
-
loadPlugins
(callback=None, callback_after=None)¶ Load the candidate plugins that have been identified through a previous call to locatePlugins. For each plugin candidate look for its category, load it and store it in the appropriate slot of the
category_mapping
.You can specify 2 callbacks: callback, and callback_after. If either of these are passed a function, (in the case of callback), it will get called before each plugin load attempt and (for callback_after), after each attempt. The
plugin_info
instance is passed as an argument to each callback. This is meant to facilitate code that needs to run for each plugin, such as adding the directory it resides in to sys.path (so imports of other files in the plugin’s directory work correctly). You can use callback_after to remove anything you added to the path.
-
locatePlugins
()¶ Convenience method (actually call the IPluginLocator method)
-
removePluginCandidate
(candidateTuple)¶ Remove a given candidate from the list of plugins that should be loaded.
The candidate must be represented by the same tuple described in
getPluginCandidates
.
-
removePluginFromCategory
(plugin, category_name)¶ Remove a plugin from the category where it’s assumed to belong.
-
setCategoriesFilter
(categories_filter)¶ Set the categories of plugins to be looked for as well as the way to recognise them.
The
categories_filter
first defines the various categories in which the plugins will be stored via its keys and it also defines the interface tha has to be inherited by the actual plugin class belonging to each category.
-
setPluginInfoClass
(picls, strategies=None)¶ DEPRECATED(>1.9): directly configure the IPluginLocator instance instead !
Convenience method (actually call self.getPluginLocator().setPluginInfoClass)
When using a
PluginFileLocator
you may restrict the strategies to which the change of PluginInfo class will occur by just giving the list of strategy names in the argument “strategies”
-
setPluginInfoExtension
(ext)¶ DEPRECATED(>1.9): for backward compatibility. Directly configure the IPluginLocator instance instead !
Warning
This will only work if the strategy “info_ext” is active for locating plugins.
-
setPluginLocator
(plugin_locator, dir_list=None, picls=None)¶ Sets the strategy used to locate the basic information.
See IPluginLocator for the policy that plugin_locator must enforce.
-
setPluginPlaces
(directories_list)¶ DEPRECATED(>1.9): directly configure the IPluginLocator instance instead !
Convenience method (actually call the IPluginLocator method)
-
updatePluginPlaces
(directories_list)¶ DEPRECATED(>1.9): directly configure the IPluginLocator instance instead !
Convenience method (actually call the IPluginLocator method)
-
class
yapsy.PluginManager.
PluginManagerSingleton
¶ Singleton version of the most basic plugin manager.
Being a singleton, this class should not be initialised explicitly and the
get
classmethod must be called instead.To call one of this class’s methods you have to use the
get
method in the following way:PluginManagerSingleton.get().themethodname(theargs)
To set up the various coonfigurables variables of the PluginManager’s behaviour please call explicitly the following methods:
setCategoriesFilter
forcategories_filter
setPluginPlaces
fordirectories_list
setPluginInfoExtension
forplugin_info_ext
-
classmethod
get
()¶ Actually create an instance
-
classmethod
setBehaviour
(list_of_pmd)¶ Set the functionalities handled by the plugin manager by giving a list of
PluginManager
decorators.This function shouldn’t be called several time in a same process, but if it is only the first call will have an effect.
It also has an effect only if called before the initialisation of the singleton.
In cases where the function is indeed going to change anything the
True
value is return, in all other cases, theFalse
value is returned.