From 3b198d9000e983888b6cb0e1464ed91f49108148 Mon Sep 17 00:00:00 2001 From: Borys Jurgiel Date: Tue, 1 Apr 2014 16:32:48 +0200 Subject: [PATCH] [FEATURE] [Plugin Manager] Voting for plugins from Plugin Manager --- python/pyplugin_installer/installer.py | 15 ++++ python/pyplugin_installer/installer_data.py | 9 ++- src/app/pluginmanager/README | 1 + src/app/pluginmanager/qgspluginmanager.cpp | 81 +++++++++++++++++++-- src/app/pluginmanager/qgspluginmanager.h | 2 +- 5 files changed, 100 insertions(+), 8 deletions(-) diff --git a/python/pyplugin_installer/installer.py b/python/pyplugin_installer/installer.py index b017b3b7ff6..590fd1dfa17 100644 --- a/python/pyplugin_installer/installer.py +++ b/python/pyplugin_installer/installer.py @@ -188,6 +188,7 @@ class QgsPluginInstaller(QObject): plugin = plugins.all()[key] iface.pluginManagerInterface().addPluginMetadata({ "id" : key, + "plugin_id" : plugin["plugin_id"] or "", "name" : plugin["name"], "description" : plugin["description"], "about" : plugin["about"], @@ -512,3 +513,17 @@ class QgsPluginInstaller(QObject): reposName = reposName.decode("utf-8") repositories.setInspectionFilter(reposName) self.reloadAndExportData() + + + # ----------------------------------------- # + def sendVote(self, plugin_id, vote): + """ send vote via the RPC """ + + if not plugin_id or not vote: + return False + url = "http://plugins.qgis.org/plugins/RPC2/" + params = "{\"id\":\"djangorpc\",\"method\":\"plugin.vote\",\"params\":[%s,%s]}" % (str(plugin_id), str(vote)) + req = QNetworkRequest(QUrl(url)) + req.setRawHeader("Content-Type", "application/json"); + reply = QgsNetworkAccessManager.instance().post(req, params) + return True diff --git a/python/pyplugin_installer/installer_data.py b/python/pyplugin_installer/installer_data.py index 35825273b2a..dcf94a0c691 100644 --- a/python/pyplugin_installer/installer_data.py +++ b/python/pyplugin_installer/installer_data.py @@ -413,8 +413,14 @@ class Repositories(QObject): if icon and not icon.startswith("http"): icon = "http://%s/%s" % ( QUrl(self.mRepositories[reposName]["url"]).host() , icon ) + if pluginNodes.item(i).toElement().hasAttribute("plugin_id"): + plugin_id = pluginNodes.item(i).toElement().attribute("plugin_id") + else: + plugin_id = None + plugin = { "id" : name, + "plugin_id" : plugin_id, "name" : pluginNodes.item(i).toElement().attribute("name"), "version_available" : pluginNodes.item(i).toElement().attribute("version"), "description" : pluginNodes.item(i).firstChildElement("description").text().strip(), @@ -647,6 +653,7 @@ class Plugins(QObject): plugin = { "id" : key, + "plugin_id" : None, "name" : pluginMetadata("name") or key, "description" : pluginMetadata("description"), "about" : pluginMetadata("about"), @@ -749,7 +756,7 @@ class Plugins(QObject): if not self.mPlugins[key][attrib] and plugin[attrib]: self.mPlugins[key][attrib] = plugin[attrib] # other remote metadata is preffered: - for attrib in ["name", "description", "about", "category", "tags", "changelog", "author_name", "author_email", "homepage", + for attrib in ["name", "plugin_id", "description", "about", "category", "tags", "changelog", "author_name", "author_email", "homepage", "tracker", "code_repository", "experimental", "deprecated", "version_available", "zip_repository", "download_url", "filename", "downloads", "average_vote", "rating_votes"]: if ( not attrib in translatableAttributes ) or ( attrib == "name" ): # include name! diff --git a/src/app/pluginmanager/README b/src/app/pluginmanager/README index bf6b0563b90..687fef83c5a 100644 --- a/src/app/pluginmanager/README +++ b/src/app/pluginmanager/README @@ -1,6 +1,7 @@ PLUGIN METADATA TAGS ======================================================= id the key; C++ library base name or Python module name +plugin_id for the official repository: an integer id. At the time, used for voting only. name human readable plugin name description short description of the plugin purpose only about longer description: how does it work, where does it install, how to run it? diff --git a/src/app/pluginmanager/qgspluginmanager.cpp b/src/app/pluginmanager/qgspluginmanager.cpp index a328730c9a5..e0e5e4ab3db 100644 --- a/src/app/pluginmanager/qgspluginmanager.cpp +++ b/src/app/pluginmanager/qgspluginmanager.cpp @@ -612,11 +612,13 @@ void QgsPluginManager::showPluginDetails( QStandardItem * item ) " width:360px;" " margin-left:98px;" " padding-top:3px;" - " }"; + " }" + ""; - if ( ! metadata->value( "average_vote" ).isEmpty() ) + if ( ! metadata->value( "plugin_id" ).isEmpty() ) { html += QString( + "").arg( metadata->value( "average_vote" ).toFloat() / 5 * 92 ); + html += QString( + "").arg( metadata->value( "plugin_id" ) ); } - html += ""; + + html += ""; // First prepare message box(es) if ( ! metadata->value( "error" ).isEmpty() ) @@ -713,7 +758,7 @@ void QgsPluginManager::showPluginDetails( QStandardItem * item ) } html += "

"; - html += "
"; + html += "
"; html += "
"; if ( ! metadata->value( "rating_votes" ).isEmpty() ) { @@ -727,8 +772,9 @@ void QgsPluginManager::showPluginDetails( QStandardItem * item ) { html += tr( "%1 downloads" ).arg( metadata->value( "downloads" ) ); } - html += "
"; + html += "
"; + html += ""; html += "
"; @@ -790,6 +836,8 @@ void QgsPluginManager::showPluginDetails( QStandardItem * item ) html += ""; + html += ""; + wvDetails->setHtml( html ); // Set buttonInstall text (and sometimes focus) @@ -1105,7 +1153,28 @@ void QgsPluginManager::on_vwPlugins_doubleClicked( const QModelIndex & theIndex void QgsPluginManager::on_wvDetails_linkClicked( const QUrl & url ) { + if ( url.scheme() == "rpc2" ) + { + if ( url.host() == "plugin.vote" ) + { + QString params = url.path(); + QString response; + QgsPythonRunner::eval( QString( "pyplugin_installer.instance().sendVote('%1', '%2')" ).arg( params.split( "/" )[1] ) + .arg( params.split( "/" )[2] ), response ); + if ( response == "True" ) + { + pushMessage( tr( "Vote sent successfully" ), QgsMessageBar::INFO ); + } + else + { + pushMessage( tr( "Sending vote to the plugin repository failed." ), QgsMessageBar::WARNING ); + } + } + } + else + { QDesktopServices::openUrl( url ); + } } diff --git a/src/app/pluginmanager/qgspluginmanager.h b/src/app/pluginmanager/qgspluginmanager.h index 0a48e8ab603..ee1ee9cfb2a 100644 --- a/src/app/pluginmanager/qgspluginmanager.h +++ b/src/app/pluginmanager/qgspluginmanager.h @@ -168,7 +168,7 @@ class QgsPluginManager : public QgsOptionsDialogBase, private Ui::QgsPluginManag void clearRepositoryFilter( ); //! show the given message in the Plugin Manager internal message bar - void pushMessage( const QString &text, QgsMessageBar::MessageLevel level, int duration ); + void pushMessage( const QString &text, QgsMessageBar::MessageLevel level, int duration = -1 ); protected: //! Reimplement QgsOptionsDialogBase method as we have a custom window title what would be overwritten by this method