def resolve_path(path, collection_path, search_paths): """Try to resolve the SVG and image paths. This is the procedure: * It might be a complete local file system path, check if it exists * It might be a URL (either local file system or http(s)) * Check in the 'svg' directory of the collection * Check in the 'image' directory of the collection * Check in the search_paths :param path: The original path. :type path: str :param collection_path: The local file system path for the collection. :type collection_path: str :param search_paths: List of paths to search for images/SVGs. :type search_paths: str """ # It might be a complete local file system path if QFile(path).exists(): return QFileInfo(path).canonicalFilePath() # It might be a URL if '://' in path: url = QUrl(path) if url.isValid() and url.scheme() != '': if url.scheme().lower() == 'file': # It's a url to local file path = url.toLocalFile() if QFile(path).exists(): return QFileInfo(path).canonicalFilePath() else: # URL pointing to online resource return path # Check in the 'svg' directory of the collection file_name = path_leaf(path) svg_collection_path = Path(collection_path, 'svg', file_name) if QFile(str(svg_collection_path)).exists(): return QFileInfo(str(svg_collection_path)).canonicalFilePath() # Check in the 'image' directory of the collection image_collection_path = Path(collection_path, 'image', file_name) if QFile(str(image_collection_path)).exists(): return QFileInfo(str(image_collection_path)).canonicalFilePath() # Still not found, check the search_paths for search_path in search_paths: local_path = Path(search_path, path) if QFile(str(local_path)).exists(): return QFileInfo(str(local_path)).canonicalFilePath() # Can't find any, just return the original path return path
def xmlDownloaded(self): """ populate the plugins object with the fetched data """ reply = self.sender() reposName = reply.property('reposName') if reply.error() != QNetworkReply.NoError: # fetching failed 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 canceled the download manually, it was most likely caused by a timeout. In this case consider increasing the connection timeout value in QGIS options window.") elif reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) == 301: redirectionUrl = reply.attribute(QNetworkRequest.RedirectionTargetAttribute) if redirectionUrl.isRelative(): redirectionUrl = reply.url().resolved(redirectionUrl) redirectionCounter = reply.property('redirectionCounter') + 1 if redirectionCounter > 4: self.mRepositories[reposName]["state"] = 3 self.mRepositories[reposName]["error"] = QCoreApplication.translate("QgsPluginInstaller", "Too many redirections") else: # Fire a new request and exit immediately in order to quietly destroy the old one self.requestFetching(reposName, redirectionUrl, redirectionCounter) reply.deleteLater() return else: reposXML = QDomDocument() content = reply.readAll() # Fix lonely ampersands in metadata a = QByteArray() a.append("& ") b = QByteArray() b.append("& ") content = content.replace(a, b) reposXML.setContent(content) pluginNodes = reposXML.elementsByTagName("pyqgis_plugin") if pluginNodes.size(): for i in range(pluginNodes.size()): fileName = pluginNodes.item(i).firstChildElement("file_name").text().strip() if not fileName: fileName = QFileInfo(pluginNodes.item(i).firstChildElement("download_url").text().strip().split("?")[0]).fileName() match = re.match('(.*?)[.-]', fileName) if match: name = match.groups()[0] else: name = fileName experimental = False if pluginNodes.item(i).firstChildElement("experimental").text().strip().upper() in ["TRUE", "YES"]: experimental = True deprecated = False if pluginNodes.item(i).firstChildElement("deprecated").text().strip().upper() in ["TRUE", "YES"]: deprecated = True trusted = False if pluginNodes.item(i).firstChildElement("trusted").text().strip().upper() in ["TRUE", "YES"]: trusted = True icon = pluginNodes.item(i).firstChildElement("icon").text().strip() if icon and not icon.startswith("http"): url = QUrl(self.mRepositories[reposName]["url"]) if url.scheme() in ('http', 'https'): icon = "{}://{}/{}".format(url.scheme(), 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(), "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(), "category": pluginNodes.item(i).firstChildElement("category").text().strip(), "tags": pluginNodes.item(i).firstChildElement("tags").text().strip(), "changelog": pluginNodes.item(i).firstChildElement("changelog").text().strip(), "author_email": pluginNodes.item(i).firstChildElement("author_email").text().strip(), "tracker": pluginNodes.item(i).firstChildElement("tracker").text().strip(), "code_repository": pluginNodes.item(i).firstChildElement("repository").text().strip(), "downloads": pluginNodes.item(i).firstChildElement("downloads").text().strip(), "average_vote": pluginNodes.item(i).firstChildElement("average_vote").text().strip(), "rating_votes": pluginNodes.item(i).firstChildElement("rating_votes").text().strip(), "icon": icon, "experimental": experimental, "deprecated": deprecated, "trusted": trusted, "filename": fileName, "installed": False, "available": True, "status": "not installed", "error": "", "error_details": "", "version_installed": "", "zip_repository": reposName, "library": "", "readonly": False, "plugin_dependencies": pluginNodes.item(i).firstChildElement("plugin_dependencies").text().strip(), } qgisMinimumVersion = pluginNodes.item(i).firstChildElement("qgis_minimum_version").text().strip() if not qgisMinimumVersion: qgisMinimumVersion = "2" qgisMaximumVersion = pluginNodes.item(i).firstChildElement("qgis_maximum_version").text().strip() if not qgisMaximumVersion: qgisMaximumVersion = qgisMinimumVersion[0] + ".99" # if compatible, add the plugin to the list if not pluginNodes.item(i).firstChildElement("disabled").text().strip().upper() in ["TRUE", "YES"]: if isCompatible(pyQgisVersion(), qgisMinimumVersion, qgisMaximumVersion): # add the plugin to the cache plugins.addFromRepository(plugin) self.mRepositories[reposName]["state"] = 2 else: # no plugin metadata found self.mRepositories[reposName]["state"] = 3 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:") + " {} {}".format( reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.attribute(QNetworkRequest.HttpReasonPhraseAttribute) ) self.repositoryFetched.emit(reposName) # is the checking done? if not self.fetchingInProgress(): self.checkingDone.emit() reply.deleteLater()