# -*- coding: utf-8 -*- """ *************************************************************************** GetScriptsAndModels.py --------------------- Date : June 2014 Copyright : (C) 2014 by Victor Olaya Email : volayaf at gmail dot com *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * *************************************************************************** """ from builtins import str from builtins import range __author__ = 'Victor Olaya' __date__ = 'June 2014' __copyright__ = '(C) 2014, Victor Olaya' # This will get replaced with a git SHA1 when you do a git archive __revision__ = '$Format:%H$' import os import json from functools import partial from qgis.PyQt import uic from qgis.PyQt.QtCore import Qt, QCoreApplication, QUrl from qgis.PyQt.QtGui import QCursor from qgis.PyQt.QtWidgets import QApplication, QTreeWidgetItem, QPushButton, QMessageBox from qgis.PyQt.QtNetwork import QNetworkReply, QNetworkRequest from qgis.utils import iface, show_message_log from qgis.core import (QgsNetworkAccessManager, QgsMessageLog, QgsApplication) from qgis.gui import QgsMessageBar from processing.core.ProcessingConfig import ProcessingConfig from processing.gui.ToolboxAction import ToolboxAction from processing.gui import Help2Html from processing.gui.Help2Html import getDescription, ALG_DESC, ALG_VERSION, ALG_CREATOR from processing.script.ScriptUtils import ScriptUtils from processing.modeler.ModelerUtils import ModelerUtils pluginPath = os.path.split(os.path.dirname(__file__))[0] WIDGET, BASE = uic.loadUiType( os.path.join(pluginPath, 'ui', 'DlgGetScriptsAndModels.ui')) class GetScriptsAction(ToolboxAction): def __init__(self): self.name, self.i18n_name = self.trAction('Get scripts from on-line scripts collection') self.group, self.i18n_group = self.trAction('Tools') def getIcon(self): return QgsApplication.getThemeIcon("/processingScript.svg") def execute(self): repoUrl = ProcessingConfig.getSetting(ProcessingConfig.MODELS_SCRIPTS_REPO) if repoUrl is None or repoUrl == '': QMessageBox.warning(None, self.tr('Repository error'), self.tr('Scripts and models repository is not configured.')) return dlg = GetScriptsAndModelsDialog(GetScriptsAndModelsDialog.SCRIPTS) dlg.exec_() if dlg.updateProvider: QgsApplication.processingRegistry().providerById('script').refreshAlgorithms() class GetModelsAction(ToolboxAction): def __init__(self): self.name, self.i18n_name = self.trAction('Get models from on-line scripts collection') self.group, self.i18n_group = self.trAction('Tools') def getIcon(self): return QgsApplication.getThemeIcon("/processingModel.svg") def execute(self): repoUrl = ProcessingConfig.getSetting(ProcessingConfig.MODELS_SCRIPTS_REPO) if repoUrl is None or repoUrl == '': QMessageBox.warning(None, self.tr('Repository error'), self.tr('Scripts and models repository is not configured.')) return dlg = GetScriptsAndModelsDialog(GetScriptsAndModelsDialog.MODELS) dlg.exec_() if dlg.updateProvider: QgsApplication.processingRegistry().providerById('model').refreshAlgorithms() class GetScriptsAndModelsDialog(BASE, WIDGET): HELP_TEXT = QCoreApplication.translate('GetScriptsAndModelsDialog', '
Check/uncheck algorithms in the tree to select the ones that you ' 'want to install or remove
' 'Algorithms are divided in 3 groups:
' 'Description: {0}
').format(getDescription(ALG_DESC, descriptions)) html += self.tr('Created by: {0}').format(getDescription(ALG_CREATOR, descriptions)) html += self.tr('
Version: {0}').format(getDescription(ALG_VERSION, descriptions)) reply.deleteLater() self.txtHelp.setHtml(html) def currentItemChanged(self, item, prev): if isinstance(item, TreeItem): url = self.urlBase + item.filename.replace(' ', '%20') + '.help' self.grabHTTP(url, self.setHelp, item) else: self.txtHelp.setHtml(self.HELP_TEXT) def getTreeBranchForState(self, filename, version): if not os.path.exists(os.path.join(self.folder, filename)): return self.notinstalledItem else: helpFile = os.path.join(self.folder, filename + '.help') try: with open(helpFile) as f: helpContent = json.load(f) currentVersion = float(helpContent[Help2Html.ALG_VERSION]) except Exception: currentVersion = 0 if version > currentVersion: return self.toupdateItem else: return self.uptodateItem def cancelPressed(self): super(GetScriptsAndModelsDialog, self).reject() def storeFile(self, reply, filename): """store a script/model that has been downloaded""" QApplication.restoreOverrideCursor() if reply.error() != QNetworkReply.NoError: if os.path.splitext(filename)[1].lower() == '.help': content = '{"ALG_VERSION" : %s}' % self.resources[filename[:-5]][0] else: self.popupError(reply.error(), reply.request().url().toString()) content = None else: content = bytes(reply.readAll()).decode('utf8') reply.deleteLater() if content: path = os.path.join(self.folder, filename) with open(path, 'w') as f: f.write(content) self.progressBar.setValue(self.progressBar.value() + 1) def okPressed(self): toDownload = [] for i in range(self.toupdateItem.childCount()): item = self.toupdateItem.child(i) if item.checkState(0) == Qt.Checked: toDownload.append(item.filename) for i in range(self.notinstalledItem.childCount()): item = self.notinstalledItem.child(i) if item.checkState(0) == Qt.Checked: toDownload.append(item.filename) if toDownload: self.progressBar.setMaximum(len(toDownload) * 2) for i, filename in enumerate(toDownload): QCoreApplication.processEvents() url = self.urlBase + filename.replace(' ', '%20') self.grabHTTP(url, self.storeFile, filename) url += '.help' self.grabHTTP(url, self.storeFile, filename + '.help') toDelete = [] for i in range(self.uptodateItem.childCount()): item = self.uptodateItem.child(i) if item.checkState(0) == Qt.Unchecked: toDelete.append(item.filename) # Remove py and help files if they exist for filename in toDelete: for pathname in (filename, filename + u".help"): path = os.path.join(self.folder, pathname) if os.path.exists(path): os.remove(path) self.updateProvider = len(toDownload) + len(toDelete) > 0 super(GetScriptsAndModelsDialog, self).accept() class TreeItem(QTreeWidgetItem): def __init__(self, filename, name, icon): QTreeWidgetItem.__init__(self) self.name = name self.filename = filename self.setText(0, name) self.setIcon(0, icon) self.setCheckState(0, Qt.Unchecked)