8 changes: 4 additions & 4 deletions python/pyplugin_installer/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def fetchAvailablePlugins(self, reloadMode):
if repositories.allUnavailable() and repositories.allUnavailable() != repositories.allEnabled():
for key in repositories.allUnavailable():
if not keepQuiet:
QMessageBox.warning(iface.mainWindow(), self.tr("QGIS Python Plugin Installer"), self.tr("Error reading repository:") + " " + key + "\n" + repositories.all()[key]["error"])
QMessageBox.warning(iface.mainWindow(), self.tr("QGIS Python Plugin Installer"), self.tr("Error reading repository:") + " " + key + "\n\n" + repositories.all()[key]["error"])
if QgsApplication.keyboardModifiers() == Qt.KeyboardModifiers(Qt.ShiftModifier):
keepQuiet = True
# finally, rebuild plugins from the caches
Expand Down Expand Up @@ -172,9 +172,7 @@ def exportRepositoriesToManager(self):
""" Update manager's repository tree widget with current data """
iface.pluginManagerInterface().clearRepositoryList()
for key in repositories.all():
url = repositories.all()[key]["url"]
v=str(QGis.QGIS_VERSION_INT)
url += "?qgis=%d.%d" % ( int(v[0]), int(v[1:3]) )
url = repositories.all()[key]["url"] + repositories.urlParams()
repository = repositories.all()[key]
if repositories.inspectionFilter():
enabled = ( key == repositories.inspectionFilter() )
Expand All @@ -201,6 +199,7 @@ def exportPluginsToManager(self):
"id" : key,
"name" : plugin["name"],
"description" : plugin["description"],
"about" : plugin["about"],
"category" : plugin["category"],
"tags" : plugin["tags"],
"changelog" : plugin["changelog"],
Expand Down Expand Up @@ -448,6 +447,7 @@ def editRepository(self, reposName):
dlg = QgsPluginInstallerRepositoryDialog( iface.mainWindow() )
dlg.editName.setText(reposName)
dlg.editURL.setText(repositories.all()[reposName]["url"])
dlg.editParams.setText(repositories.urlParams())
dlg.checkBoxEnabled.setCheckState(checkState[repositories.all()[reposName]["enabled"]])
if repositories.all()[reposName]["valid"]:
dlg.checkBoxEnabled.setEnabled(True)
Expand Down
92 changes: 46 additions & 46 deletions python/pyplugin_installer/installer_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,54 +49,41 @@
mPlugins = dict of dicts {id : {
"id" unicode # module name
"name" unicode, #
"description" unicode, #
"name" unicode, # human readable plugin name
"description" unicode, # short description of the plugin purpose only
"about" unicode, # longer description: how does it work, where does it install, how to run it?
"category" unicode, # will be removed?
"tags" unicode, # comma separated, spaces allowed
"changelog" unicode, # may be multiline
"author_name" unicode, #
"author_email" unicode, #
"homepage" unicode, # url to a tracker site
"author_name" unicode, # author name
"author_email" unicode, # author email
"homepage" unicode, # url to the plugin homepage
"tracker" unicode, # url to a tracker site
"code_repository" unicode, # url to a repository with code
"version_installed" unicode, #
"library" unicode, # full path to the installed library/Python module
"code_repository" unicode, # url to the source code repository
"version_installed" unicode, # installed instance version
"library" unicode, # absolute path to the installed library / Python module
"icon" unicode, # path to the first:(INSTALLED | AVAILABLE) icon
"pythonic" const bool=True
"pythonic" const bool=True # True if Python plugin
"readonly" boolean, # True if core plugin
"installed" boolean, # True if installed
"available" boolean, # True if available in repositories
"status" unicode, # ( not installed | new ) | ( installed | upgradeable | orphan | newer )
"error" unicode, # NULL | broken | incompatible | dependent
"error_details" unicode, # more details
"experimental" boolean, # chosen version: experimental or stable?
"version_available" unicode, # chosen version: version
"zip_repository" unicode, # chosen version: the remote repository id
"download_url" unicode, # chosen version: url for downloading
"filename" unicode, # chosen version: the zip file to be downloaded
"downloads" unicode, # chosen version: number of dowloads
"average_vote" unicode, # chosen version: average vote
"rating_votes" unicode, # chosen version: number of votes
"stable:version_available" unicode, # stable version found in repositories
"stable:download_source" unicode,
"stable:download_url" unicode,
"stable:filename" unicode,
"stable:downloads" unicode,
"stable:average_vote" unicode,
"stable:rating_votes" unicode,
"experimental:version_available" unicode, # experimental version found in repositories
"experimental:download_source" unicode,
"experimental:download_url" unicode,
"experimental:filename" unicode,
"experimental:downloads" unicode,
"experimental:average_vote" unicode,
"experimental:rating_votes" unicode
"error_details" unicode, # error description
"experimental" boolean, # true if experimental, false if stable
"version_available" unicode, # available version
"zip_repository" unicode, # the remote repository id
"download_url" unicode, # url for downloading the plugin
"filename" unicode, # the zip file name to be unzipped after downloaded
"downloads" unicode, # number of dowloads
"average_vote" unicode, # average vote
"rating_votes" unicode, # number of votes
}}
"""



translatableAttributes = ["name", "description", "tags"]
translatableAttributes = ["name", "description", "about", "tags"]

reposGroup = "/Qgis/plugin-repos"
settingsGroup = "/Qgis/plugin-installer"
Expand Down Expand Up @@ -249,6 +236,13 @@ def allUnavailable(self):
return repos


# ----------------------------------------- #
def urlParams(self):
""" return GET parameters to be added to every request """
v=str(QGis.QGIS_VERSION_INT)
return "?qgis=%d.%d" % ( int(v[0]), int(v[1:3]) )


# ----------------------------------------- #
def setRepositoryData(self, reposName, key, value):
""" write data to the mRepositories dict """
Expand Down Expand Up @@ -368,9 +362,9 @@ def load(self):
def requestFetching(self,key):
""" start fetching the repository given by key """
self.mRepositories[key]["state"] = 1
url = QUrl(self.mRepositories[key]["url"])
v=str(QGis.QGIS_VERSION_INT)
url.addQueryItem('qgis', '.'.join([str(int(s)) for s in [v[0], v[1:3]]]) ) # don't include the bugfix version!
url = QUrl(self.mRepositories[key]["url"] + self.urlParams() )
#v=str(QGis.QGIS_VERSION_INT)
#url.addQueryItem('qgis', '.'.join([str(int(s)) for s in [v[0], v[1:3]]]) ) # don't include the bugfix version!

self.mRepositories[key]["QRequest"] = QNetworkRequest(url)
self.mRepositories[key]["QRequest"].setAttribute( QNetworkRequest.User, key)
Expand Down Expand Up @@ -406,12 +400,7 @@ def xmlDownloaded(self):
self.mRepositories[reposName]["state"] = 3
self.mRepositories[reposName]["error"] = reply.errorString()
if reply.error() == QNetworkReply.OperationCanceledError:
self.mRepositories[reposName]["error"] += "\n\n" + QCoreApplication.translate("QgsPluginInstaller", "If you haven't cancelled the download manually, it might be caused by a timeout. In this case consider increasing the connection timeout value in QGIS options.")
elif reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200:
self.mRepositories[reposName]["state"] = 3
self.mRepositories[reposName]["error"] = QCoreApplication.translate("QgsPluginInstaller", "Status code:") + " %d %s" % (
reply.attribute(QNetworkRequest.HttpStatusCodeAttribute),
reply.attribute(QNetworkRequest.HttpReasonPhraseAttribute))
self.mRepositories[reposName]["error"] += "\n\n" + QCoreApplication.translate("QgsPluginInstaller", "If you haven't cancelled the download manually, it was most likely caused by a timeout. In this case consider increasing the connection timeout value in QGIS options window.")
else:
reposXML = QDomDocument()
reposXML.setContent(reply.readAll())
Expand All @@ -434,6 +423,7 @@ def xmlDownloaded(self):
"name" : pluginNodes.item(i).toElement().attribute("name"),
"version_available" : pluginNodes.item(i).toElement().attribute("version"),
"description" : pluginNodes.item(i).firstChildElement("description").text().strip(),
"about" : pluginNodes.item(i).firstChildElement("about").text().strip(),
"author_name" : pluginNodes.item(i).firstChildElement("author_name").text().strip(),
"homepage" : pluginNodes.item(i).firstChildElement("homepage").text().strip(),
"download_url" : pluginNodes.item(i).firstChildElement("download_url").text().strip(),
Expand Down Expand Up @@ -470,8 +460,14 @@ def xmlDownloaded(self):
plugins.addFromRepository(plugin)
self.mRepositories[reposName]["state"] = 2
else:
# no plugin metadata found
self.mRepositories[reposName]["state"] = 3
self.mRepositories[reposName]["error"] = QCoreApplication.translate("QgsPluginInstaller", "Server response is 200 OK, but doesn't look like plugin metatada.")
if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 200:
self.mRepositories[reposName]["error"] = QCoreApplication.translate("QgsPluginInstaller", "Server response is 200 OK, but doesn't contain plugin metatada. This is most likely caused by a proxy or a wrong repository URL. You can configure proxy settings in QGIS options.")
else:
self.mRepositories[reposName]["error"] = QCoreApplication.translate("QgsPluginInstaller", "Status code:") + " %d %s" % (
reply.attribute(QNetworkRequest.HttpStatusCodeAttribute),
reply.attribute(QNetworkRequest.HttpReasonPhraseAttribute))

self.repositoryFetched.emit( reposName )

Expand Down Expand Up @@ -647,6 +643,7 @@ def pluginMetadata(fct):
"id" : key,
"name" : pluginMetadata("name") or key,
"description" : pluginMetadata("description"),
"about" : pluginMetadata("about"),
"icon" : icon,
"category" : pluginMetadata("category"),
"tags" : pluginMetadata("tags"),
Expand Down Expand Up @@ -734,15 +731,18 @@ def rebuild(self):
self.mPlugins[key] = plugin # just add a new plugin
else:
# update local plugin with remote metadata
# name, description, icon: only use remote data if local one is not available (because of i18n and to not download the icon)
# description, about, icon: only use remote data if local one not available. Prefer local version because of i18n.
# NOTE: don't prefer local name to not desynchronize names if repository doesn't support i18n.
# Also prefer local icon to avoid downloading.
for attrib in translatableAttributes + ["icon"]:
if attrib != "name":
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", "category", "tags", "changelog", "author_name", "author_email", "homepage",
for attrib in ["name", "description", "about", "category", "tags", "changelog", "author_name", "author_email", "homepage",
"tracker", "code_repository", "experimental", "version_available", "zip_repository",
"download_url", "filename", "downloads", "average_vote", "rating_votes"]:
if not attrib in translatableAttributes:
if ( not attrib in translatableAttributes ) or ( attrib == "name" ): # include name!
if plugin[attrib]:
self.mPlugins[key][attrib] = plugin[attrib]
# set status
Expand Down
Loading