Picard Plugins Proposal
A proposal for the management of plugins for MusicBrainz Picard
MusicBrainz Picard supports the addition of user defined functions and extensions through optional plugins. Initially, plugins were developed and included in an "official" list of plugins by pushing the plugin to the metabrainz/picard-plugins repository on GitHub. By scanning the repository, a list was displayed on the Picard website and was available to Picard through an API on the website. This is the list that is displayed by default in the Picard options settings.
In some cases, the original plugin authors have abandoned the plugin or have not provided maintenance or response to reported issues in a timely manner. Further, the issues are being reported on the MetaBrainz ticket tracking system, with the expectation that the Picard development team will address them. Even though the Picard team is trying to address the issues raised, this is not an appropriate expectation which can also unfairly impact the reputation of the Picard software. As more and more plugins are developed by third-parties, this concern continues to grow.
The intent of this "proposal" is to document the issues and concerns, and provide a means for collaboratively developing a plan for the ongoing management of plugins available for MusicBrainz Picard. As such, it is a "working document", inviting input and revision by the core team of Picard developers, and comments by third-party developers of plugins for use with Picard.
There are a number of factors that must be considered in developing a system for managing plugins for Picard. These include such items as:
- Is it an official plugin, supported by the Picard team, or is it a third-party plugin supported by the plugin author?
- Should third-party plugins be included in the official default list provided within Picard and on the Picard website? Should there be a different list (e.g. on a wiki page similar to the MusicBrainz scripts page maintained by Colby Dray at https://wiki.musicbrainz.org/User:Colbydray/UserscriptList) with a disclaimer about the plugins not being officially supported by MusicBrainz Picard?
- How do we encourage issues with third-party plugins to be reported to the plugin author / maintainer rather than to the Picard team?
- How do authors of third-party plugins implement bug fixes, tweaks and improvements to their plugin without burdening the Picard team with reviews? Should the Picard team review all changes to third-party plugins? If so, how could this be enforced?
- How do we protect the reputation of the Picard software from buggy or poorly written third-party plugins? Should there be some sort of optional certification process available for third-party plugins? If so, what would it entail and how would it be managed?
- Can we define and document minimum standards (e.g., format, manifest, hooks, etc.) for plugins? How to enforce them?
- [Sophist] Some plugins might just provide code to be used by other catalogue or user written plugins - to ensure stability and backwards compatibility they needed to be in a centrally controlled repository with a standard set of approvers. To avoid the complications of maintaining approver lists on large numbers of repos, it probably makes more sense to have them in a single central repo.
- [Sophist] If you want to have separate approver lists for individual plugins, then they will need to be in separate repos. It may / may not be a good idea to allow plugin authors to approve their own changes which might be backwardly incompatible or of poor quality.
- [Sophist] If you want to include in the catalogue plugins entirely under the control of the author and held in the authors repo, then to prevent reputational damage to the (Picard) brand, I think it has to be abundantly clear that these are third party plugins not endorsed by Picard.
- [Sophist] Plugins by their nature as executable source code are open to security abuses (i.e. they can contain code that steals personal data or sends spam or takes part in denial of service attacks etc.). If the user runs (or is tricked into running) Picard with administrator privileges, the code could download other malware and take complete control of the user’s PC. At the moment a user can manually install a plugin of this nature - and we probably do not want to stop this, however bearing this in mind we may decide not to provide functionality to download and install plugins from any site other than Picard-Plugins, and indeed we should probably consider whether we need to add functionality to:
- Verify that installed plugins match the version on the Picard-Plugins web site;
- Only execute plugins which are from the Picard-Plugins web site;
- Provide an explicit option (with warnings and caveats) to allow a user to explicitly authorise the execution of individual plugins (either on a one-time basis or based on the file hash) that are not verified as accurate from the Picard-Plugins web site. (Default would be to not execute, and to show an explanation in the Options/Plugins list.)
- [Sophist] The nature of plugins is to allow users to extend Picard to meet their needs, and we subject to having suitable controls to ensure ongoing quality, security and stability of plugins that are associated with the Picard "brand", the approach taken should try to provide as much flexibility for people to submit plugins and updates to them as possible. We might want to think about having "official" / "production" plugins which have a great deal of review for quality, security and stability, and "unofficial" plugins that are reviewed only for security and are merged regardless of changes to functionality or code quality. This makes it far easier to launch a new "unofficial" / "beta" plugin and get feedback / iterate on functionality, but with an incentive for plugin authors to enhance the code quality and functionality to the point that it can be adopted as an "official" / "production" plugin.
- How to deal with translations for log output or user interfaces? Current consensus is to not translate log output for the purposes of debugging because that would lead to multiple different messages (one for each language) all meaning the same thing, thus making the debugging task much more difficult. There is currently no provision for translating user interface items.
- [outsidecontext / phw] Should allow for explicit activation / deactivation hooks for plugins. See discussion on pull request https://github.com/metabrainz/picard-plugins/pull/195#issuecomment-450730198 for more information.
- How to handle i18n translation and translation files?
- Provide a way to remove any persistent settings when a plugin is uninstalled. Should there be an uninstall method included in the plugin?
- Any other considerations?
Official vs. Third-Party Plugins
Throughout the document, there have been references made to third-party plugins as opposed to official plugins. The following is intended as a guideline for distinguishing between the two:
|Official Plugin||Third-Party Plugin|
|Listed on Picard website||Yes||No|
|Listed on Picard website API||Yes||No|
|Maintained by Picard dev team||Yes||No|
|Issues managed using MetaBrainz ticket tracker||Yes||No|
|Mandatory review / approval by Picard dev team||Yes||TBD|
Plugin Format / Specification
To facilitate standard processing within Picard, each plugin is required to comply with defined standards. Possible examples include:
- Each plugin must be self-sufficient, and not rely on another plugin being enabled in order to function properly.
- Each plugin must be distributed in the form of a zip file bearing the name of the plugin and containing either:
- one python code file bearing the same name as the zip file; or
- an __init__.py file.
- Additional files may be included in the zip file as required.
- The plugin code file or the __init__.py file must contain a manifest in the form of python constant definitions as described in the Plugin Manifest section below.
- Any other items?
Each plugin must include a manifest with the following items included as a minimum:
- PLUGIN_NAME - a string containing the name of the plugin
- PLUGIN_AUTHOR - a string containing the name of the author of the plugin
- PLUGIN_DESCRIPTION - a docstring containing a brief description of the plugin
- PLUGIN_VERSION - a string containing the version number of the plugin
- PLUGIN_API_VERSIONS - a list of strings identifying the Picard versions supported by the plugin
- PLUGIN_LICENSE - a string containing the title of the license under which the plugin is being released
- PLUGIN_LICENSE_URL - a string containing the url where the full text of the license can be found
The plugin manifest may also contain the following items, some of which are required for third-party plugins (indicated with a red asterisk):
- PLUGIN_HOMEPAGE_URL - a string containing the url to the homepage for the plugin
- PLUGIN_ISSUES_URL* - a string containing the url to the issues reporting and tracking system for the plugin
- PLUGIN_INFO_URL* - a string containing the url to the information for the plugin, provided in the same JSON format as the Picard Website API endpoint (e.g., https://picard.musicbrainz.org/api/v2/plugins/)
- PLUGIN_DOWNLOAD_URL* - a string containing the url used to download the plugin package file
- PLUGIN_USER_GUIDE_URL - a string containing the url to the usage documentation or user guide for the plugin
Potential options for providing the plugin manifest. There are certainly other possibilities. Once a decision is made, there should only be one standard method for providing the manifest:
- The manifest must be included in the plugin __init__.py file in the form of constant objects, such as: PLUGIN_NAME = "My Wonderful Picard Plugin" or PLUGIN_API_VERSIONS = ["2.0"]
- The manifest must be a stand-alone file which can be used by Picard and Picard Website to retrieve the plugin metadata without having the plugin loaded into Picard
Latest Version Information
The latest version information for official plugins is provided as part of the JSON information returned when querying the Picard website API. For consistency of processing within Picard, the same JSON information should be returned for third-party plugins when querying the URL provided in the plugin’s manifest as PLUGIN_INFO_URL. As plugins are loaded, for any third-party plugins found Picard will need to add the PLUGIN_INFO_URL values to its list of URLs to check for information. This way, Picard will only check for updates for official and installed third-party plugins. If the third-party plugin does not have the appropriate URL entry in its manifest, or if the URL does not provide the appropriate JSON response, the plugin will not show any update as being available.
Official plugins can be installed by selecting them from the list provided in the Picard’s options plugins page. Third-party plugins need to be downloaded and installed by manually selecting them from the Picard options plugins page. This should not change from the current system.
The process for updating official plugins should not change from what is done now. The download URL is obtained by querying the Picard website API. For third-party plugins, the download URL will need to be provided in the manifest as PLUGIN_DOWNLOAD_URL since it will not be available from the Picard website API. The process of downloading and installing the zip file can remain the same as is currently used.
For official plugins that are being maintained by the Picard dev team, the issues should be logged and managed using the current MetaBrainz ticketing system.
Since third-party plugins are not being maintained by the Picard dev team, but rather by the plugin author, issues should be reported and tracked using a system specified by the plugin author. The URL for accessing this system will need to be provided in the plugin’s manifest as PLUGIN_ISSUES_URL.
Additional information may be referenced by the plugin and could be linked through additional buttons, displayed as required in the plugin description section of the plugins page in the Picard options settings. This information could include the following items from the plugin manifest, where the information has been included:
- Plugin home page
- Plugin documentation / user guide
- Plugin issue tracking