# -*- 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. * * * *************************************************************************** """ __author__ = 'Victor Olaya' __date__ = 'June 2014' __copyright__ = '(C) 201, Victor Olaya' # This will get replaced with a git SHA1 when you do a git archive __revision__ = '$Format:%H$' import os import json import urllib2 from urllib2 import HTTPError from PyQt4.QtCore import * from PyQt4.QtGui import * from processing.gui.ToolboxAction import ToolboxAction from PyQt4 import QtGui from processing.ui.ui_DlgGetScriptsAndModels import Ui_DlgGetScriptsAndModels from processing.script.ScriptUtils import ScriptUtils from processing.modeler.ModelerUtils import ModelerUtils from processing.gui import Help2Html from qgis.utils import iface from processing.gui.Help2Html import getDescription, ALG_DESC, ALG_VERSION, ALG_CREATOR class GetScriptsAction(ToolboxAction): def __init__(self): self.name = "Get scripts from on-line scripts collection" self.group = 'Tools' def getIcon(self): return QIcon(':/processing/images/script.png') def execute(self): try: dlg = GetScriptsAndModelsDialog(GetScriptsAndModelsDialog.SCRIPTS) dlg.exec_() if dlg.updateToolbox: self.toolbox.updateProvider('script') except HTTPError: QMessageBox.critical(iface.mainWindow(), "Connection problem", "Could not connect to scripts/models repository") class GetModelsAction(ToolboxAction): def __init__(self): self.name = "Get models from on-line scripts collection" self.group = 'Tools' def getIcon(self): return QIcon(':/processing/images/model.png') def execute(self): try: dlg = GetScriptsAndModelsDialog(GetScriptsAndModelsDialog.MODELS) dlg.exec_() if dlg.updateToolbox: self.toolbox.updateProvider('model') except HTTPError: QMessageBox.critical(iface.mainWindow(), "Connection problem", "Could not connect to scripts/models repository") def readUrl(url): try: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) return urllib2.urlopen(url).read() finally: QApplication.restoreOverrideCursor() class GetScriptsAndModelsDialog(QDialog, Ui_DlgGetScriptsAndModels): HELP_TEXT = ("

Processing resources manager

" "

Check/uncheck algorithms in the tree to select the ones that you want to install or remove

" "

Algorithms are divided in 3 groups:

" "") MODELS = 0 SCRIPTS = 1 def __init__(self, resourceType): QDialog.__init__(self, iface.mainWindow()) self.resourceType = resourceType if self.resourceType == self.MODELS: self.folder = ModelerUtils.modelsFolder() self.urlBase = "https://raw.githubusercontent.com/qgis/QGIS-Processing/master/models/" self.icon = QtGui.QIcon(os.path.dirname(__file__) + '/../images/model.png') else: self.folder = ScriptUtils.scriptsFolder() self.urlBase = "https://raw.githubusercontent.com/qgis/QGIS-Processing/master/scripts/" self.icon = QtGui.QIcon(os.path.dirname(__file__) + '/../images/script.png') self.lastSelectedItem = None self.setupUi(self) self.populateTree() self.updateToolbox = False self.buttonBox.accepted.connect(self.okPressed) self.buttonBox.rejected.connect(self.cancelPressed) self.tree.currentItemChanged .connect(self.currentItemChanged) def populateTree(self): self.uptodateItem = QTreeWidgetItem() self.uptodateItem.setText(0, "Installed") self.toupdateItem = QTreeWidgetItem() self.toupdateItem.setText(0, "Upgradable") self.notinstalledItem = QTreeWidgetItem() self.notinstalledItem.setText(0, "Not installed") self.toupdateItem.setIcon(0, self.icon) self.uptodateItem.setIcon(0, self.icon) self.notinstalledItem.setIcon(0, self.icon) resources = readUrl(self.urlBase + "list.txt").splitlines() resources = [r.split(",") for r in resources] for filename, version, name in resources: treeBranch = self.getTreeBranchForState(filename, float(version)) item = TreeItem(filename, name, self.icon) treeBranch.addChild(item) if treeBranch != self.notinstalledItem: item.setCheckState(0, Qt.Checked) self.tree.addTopLevelItem(self.toupdateItem) self.tree.addTopLevelItem(self.notinstalledItem) self.tree.addTopLevelItem(self.uptodateItem) self.webView.setHtml(self.HELP_TEXT) def currentItemChanged(self, item, prev): if isinstance(item, TreeItem): try: url = self.urlBase + item.filename.replace(" ","%20") + ".help" helpContent = readUrl(url) descriptions = json.loads(helpContent) html = "

%s

" % item.name html+="

Description: " + getDescription(ALG_DESC, descriptions)+"

" html+="

Created by: " + getDescription(ALG_CREATOR, descriptions)+"

" html+="

Version: " + getDescription(ALG_VERSION, descriptions)+"

" except HTTPError, e: html = "

No detailed description available for this script

" self.webView.setHtml(html) else: self.webView.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: currentVersion = 1 if version > currentVersion: return self.toupdateItem else: return self.uptodateItem def cancelPressed(self): self.close() def okPressed(self): toDownload = [] for i in xrange(self.toupdateItem.childCount()): item = self.toupdateItem.child(i) if item.checkState(0) == Qt.Checked: toDownload.append(item.filename) for i in xrange(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)) for i, filename in enumerate(toDownload): QCoreApplication.processEvents() url = self.urlBase + filename.replace(" ","%20") try: code = readUrl(url) path = os.path.join(self.folder, filename) with open(path, "w") as f: f.write(code) self.progressBar.setValue(i + 1) except HTTPError: QMessageBox.critical(iface.mainWindow(), "Connection problem", "Could not download file :" + filename) return toDelete = [] for i in xrange(self.uptodateItem.childCount()): item = self.uptodateItem.child(i) if item.checkState(0) == Qt.Unchecked: toDelete.append(item.filename) for filename in toDelete: path = os.path.join(self.folder, filename) os.remove(path) self.updateToolbox = len(toDownload) + len(toDelete)> 0 self.close() 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)