diff --git a/picard/const/__init__.py b/picard/const/__init__.py index 89f7701bf..fa52d183e 100644 --- a/picard/const/__init__.py +++ b/picard/const/__init__.py @@ -98,3 +98,13 @@ MUSICBRAINZ_SERVERS = [ 'musicbrainz.org', 'beta.musicbrainz.org', ] + +# Plugins API +PLUGINS_API = { + 'host': 'picard.musicbrainz.org', + 'port': 80, + 'endpoint': { + 'plugins': '/api/v1/plugins/', + 'download': '/api/v1/download/' + } +} diff --git a/picard/plugin.py b/picard/plugin.py index 770c7cca9..c1d80c7f6 100644 --- a/picard/plugin.py +++ b/picard/plugin.py @@ -20,6 +20,7 @@ from PyQt4 import QtCore from collections import defaultdict import imp +import json import os.path import shutil import picard.plugins @@ -29,7 +30,7 @@ from picard import (config, version_from_string, version_to_string, VersionError) -from picard.const import USER_PLUGIN_DIR +from picard.const import USER_PLUGIN_DIR, PLUGINS_API from picard.util import os_path_samefile @@ -173,6 +174,19 @@ class PluginWrapper(PluginShared): return self.file[len(self.dir)+1:] +class PluginData(PluginShared): + + """Used to store plugin data from JSON API""" + def __init__(self, d, module_name): + self.__dict__ = d + super(PluginData, self).__init__() + self.module_name = module_name + + @property + def files_list(self): + return ", ".join(self.files.keys()) + + class PluginManager(QtCore.QObject): plugin_installed = QtCore.pyqtSignal(PluginWrapper, bool) @@ -181,6 +195,11 @@ class PluginManager(QtCore.QObject): QtCore.QObject.__init__(self) self.plugins = [] self._api_versions = set([version_from_string(v) for v in picard.api_versions]) + self._available_plugins = {} + + @property + def available_plugins(self): + return self._available_plugins def load_plugindir(self, plugindir): plugindir = os.path.normpath(plugindir) @@ -265,6 +284,27 @@ class PluginManager(QtCore.QObject): self.plugin_installed.emit(plugin, False) except (OSError, IOError): log.warning("Unable to copy %s to plugin folder %s" % (path, USER_PLUGIN_DIR)) + def query_available_plugins(self): + self.tagger.xmlws.get( + PLUGINS_API['host'], + PLUGINS_API['port'], + PLUGINS_API['endpoint']['plugins'], + self._plugins_json_loaded, + xml=False, + priority=True, + important=True + ) + + def _plugins_json_loaded(self, response, reply, error): + if error: + self.tagger.window.set_statusbar_message( + N_("Error loading plugins list: %(error)s"), + {'error': unicode(error)}, + echo=log.error + ) + else: + self._available_plugins = [PluginData(data, key) for key, data in + json.loads(response)['plugins'].items()] def enabled(self, name): return True diff --git a/picard/tagger.py b/picard/tagger.py index 69a04246b..b4e4e9a9e 100644 --- a/picard/tagger.py +++ b/picard/tagger.py @@ -193,6 +193,7 @@ class Tagger(QtGui.QApplication): if not os.path.exists(USER_PLUGIN_DIR): os.makedirs(USER_PLUGIN_DIR) self.pluginmanager.load_plugindir(USER_PLUGIN_DIR) + self.pluginmanager.query_available_plugins() self.acoustidmanager = AcoustIDManager() self.browser_integration = BrowserIntegration()