mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-10-31 00:06:02 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			242 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			242 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # -*- 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 = self.tr('Get scripts from on-line scripts collection', 'GetScriptsAction')
 | |
|         self.group = self.tr('Tools', 'GetScriptsAction')
 | |
| 
 | |
|     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(),
 | |
|                 self.tr('Connection problem', 'GetScriptsAction'),
 | |
|                 self.tr('Could not connect to scripts/models repository', 'GetScriptsAction'))
 | |
| 
 | |
| 
 | |
| class GetModelsAction(ToolboxAction):
 | |
| 
 | |
|     def __init__(self):
 | |
|         self.name = self.tr('Get models from on-line scripts collection', 'GetModelsAction')
 | |
|         self.group = self.tr('Tools', 'GetModelsAction')
 | |
| 
 | |
|     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(),
 | |
|                 self.tr('Connection problem', 'GetModelsAction'),
 | |
|                 self.tr('Could not connect to scripts/models repository', 'GetModelsAction'))
 | |
| 
 | |
| 
 | |
| def readUrl(url):
 | |
|     try:
 | |
|         QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
 | |
|         return urllib2.urlopen(url).read()
 | |
|     finally:
 | |
|         QApplication.restoreOverrideCursor()
 | |
| 
 | |
| 
 | |
| class GetScriptsAndModelsDialog(QDialog,  Ui_DlgGetScriptsAndModels):
 | |
| 
 | |
|     HELP_TEXT = QCoreApplication.translate('GetScriptsAndModelsDialog',
 | |
|         '<h3> Processing resources manager </h3>'
 | |
|         '<p>Check/uncheck algorithms in the tree to select the ones that you '
 | |
|         'want to install or remove</p>'
 | |
|         '<p>Algorithms are divided in 3 groups:</p>'
 | |
|         '<ul><li><b>Installed:</b> Algorithms already in your system, with '
 | |
|         'the latest version available</li>'
 | |
|         '<li><b>Upgradable:</b> Algorithms already in your system, but with '
 | |
|         'a newer version available in the server</li>'
 | |
|         '<li><b>Not installed:</b> Algorithms not installed in your '
 | |
|         'system</li></ul>')
 | |
|     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, self.tr('Installed'))
 | |
|         self.toupdateItem = QTreeWidgetItem()
 | |
|         self.toupdateItem.setText(0, self.tr('Updatable'))
 | |
|         self.notinstalledItem = QTreeWidgetItem()
 | |
|         self.notinstalledItem.setText(0, self.tr('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 = '<h2>%s</h2>' % item.name
 | |
|                 html += self.tr('<p><b>Description:</b> %s</p>') % getDescription(ALG_DESC, descriptions)
 | |
|                 html += self.tr('<p><b>Created by:</b> %s') % getDescription(ALG_CREATOR, descriptions)
 | |
|                 html += self.tr('<p><b>Version:</b> %s') % getDescription(ALG_VERSION, descriptions)
 | |
|             except HTTPError, e:
 | |
|                 html = self.tr('<h2>No detailed description available for this script</h2>')
 | |
|             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(),
 | |
|                         self.tr('Connection problem'),
 | |
|                         self.tr('Could not download file: %s') % 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)
 |