====== Plugin Drafts ====== As MedUX needs to be completely modular, we need a plugin framework that has some capabilities: * **it must be easy** to understand and use * **it must be maintained**. It must be a framework that will not vanish in half a year. There are several plugin systems that are available for python, and could be possibly used as a base. A good overview is [[http://wehart.blogspot.co.at/2009/01/python-plugin-frameworks.html|here]]. I'll leave out all the ones that do not fit here and just list the ones that are taken into consideration for MedUX: * [[https://gitlab.com/nerdocs/gdaps|GDAPS]] - our own plugin system * [[http://martyalchin.com/2008/jan/10/simple-plugin-framework|Marty Alchin's framework]] - nice start. * [[http://yapsy.sourceforge.net|Yapsy]] - maybe too narrow * [[https://github.com/PyUtilib/pyutilib/|PyUtilib]] - Loosely derived from trac. I would use just the plugin framework core. Documentation of the "Component Architecture" is [[https://software.sandia.gov/trac/pyutilib/export/1831/pyutilib.component.doc/trunk/doc/plugin/pca.pdf|here]] Old ones (not taken into consideration further): * [[http://trac.edgewall.org/browser/branches/1.0-stable/trac/core.py|trac]] - only for web... * [[https://pythonhosted.org/django-plugins/|Django-Plugins]] - only Django, but seems very nice. * [[https://github.com/mitsuhiko/pluginbase|Pluginbase]] - stability?? * [[https://github.com/daltonmatos/plugnplay|PlugNPlay]] - small, inactive...?? Brainstorming: * Cryptographic (PGP, or at least SHA2) source authentication / integrity check / plugin signing. * Plugins as ZIP files or directories * Plugin class where plugins can derive from, or duck typing * python file for metadata too, or external JSON/XML file? * when plugin is a python file, (unknown) code must be run to determine the metadata of the plugin. But we have to trust the plugin anyway, as python has no sandbox possibility to run code in. So BestPractice would be: * audit the plugin * mark it as trusted, sign it * only run plugins that are signed. * How should plugin load order be determined? * plugin dependencies, and then determination by sorting algorithm? * hard coded "order" property of plugins and load by this order? Here is a sample Python code for a plugin class: class Plugin: """ Plugin class to derive from """ # name of the plugin name = "My Plugin" # Version number # 3-tuple: major, minor, revision version = (1, 0, 0) # Description of the plugin # long text, translatable description = "" # Category to be listed in. category = "Base" # Author's name of the plugin autor = "" # Author's email of the plugin author_email = "" # Is this plugin configurable? # if True, method config_widget() should be implemented. configurable = False # Can this plugin be disabled by the user? Use with care. can_be_disabled = False def __init__(self): pass def setup(self): """ Called once, when plugin gets installed. """ def initialize(self): """ Called at application start. Do all necessary things here to bring up the plugin. """ def delayed_initialize(self): """ Called after full start of the application, to set up other tasks that are not that important. Can be called async. """ def config_widget(self): """ This method, if implemented, must return a QWidget, which then will get loadedinto the config settings page of MedUX. The widget can have an optional method 'validate()' that takes no arguments and is called immediately after the user clicks OK. Changes are applied if (and only if) the validate method returns True. """ raise NotImplementedError() def save_settings(self): """ Save settings that are configured via the config_widget. This could be done individually, the preferred way is using the MedUX settings API. """ raise NotImplementedError() Some code ideas are taken from the [[http://calibre-ebook.com|calibre project]], all code listed here is licensed under the GPLv3.